'How can I open app when screen is off from foreground service?
Android: 11
NETStandard.Library: 2.0.3
Xamarin.Forms: 5.0.0.2012
Permissions(i tried):
"android.permission.FOREGROUND_SERVICE"
"android.permission.INSTANT_APP_FOREGROUND_SERVICE"
"android.permission.SYSTEM_ALERT_WINDOW"
"android.permission.DISABLE_KEYGUARD"
"android.permission.WAKE_LOCK"
"android.permission.MODIFY_PHONE_STATE"
"android.permission.RESTART_PACKAGES"
I have a security application that my clients want to know something all the time via SMS and firebase, so I have to keep the application open at all time, And I have to open Activity even when my app is closed and the screen is off,
To do that,I wrote BroadcastReceiver which is:
[BroadcastReceiver]
[IntentFilter(new[] { "android.provider.Telephony.SMS_RECEIVED" }, Priority = (int)IntentFilterPriority.HighPriority)]
public class SmsListener : BroadcastReceiver
SmsListener class always works fine.
and I have ForegroundService that work only on update notifications, play sound, Vibrate phone but I cannot open activity without error!
here is how i wrote this service:
public class AndroidServiceHelper : IAndroidService
{
private static Context context = global::Android.App.Application.Context;
public void StartService()
{
var intent = new Intent(context, typeof(AntiTheft));
if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.O)
{
context.StartForegroundService(intent);
}
else
{
context.StartService(intent);
}
}
public void StopService()
{
var intent = new Intent(context, typeof(AntiTheft));
context.StopService(intent);
}
}
and here is my AntiTheft Class which is my service:
[Service(Enabled = true, Label = "xxxx")]
public class AntiTheft : Service
{
public override IBinder OnBind(Intent intent)
{
return null;
}
public override void OnCreate()
{
base.OnCreate();
}
public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
{
Notification notif = DependencyService.Get<INotification>().ReturnNotif();
StartForeground(Constants.SERVICE_RUNNING_NOTIFICATION_ID, notif);
return StartCommandResult.Sticky;
}
public override void OnDestroy()
{
base.OnDestroy();
}
public override bool StopService(Intent name)
{
return base.StopService(name);
}
}
and this is how I show AlarmActivity (I put everything I have tried so this isn't clean at all!):
public void ShowAlert(string address, string message)
{
Toast.MakeText(context, message, ToastLength.Short).Show();
Intent mainIntent = new Intent(context, typeof(AlertActivity));
mainIntent.AddFlags(ActivityFlags.NewTask | ActivityFlags.ClearTop | ActivityFlags.SingleTop);
mainIntent.PutExtra(address, message);
context.StartActivity(mainIntent);
//Intent launchIntent = Application.Context.PackageManager.GetLaunchIntentForPackage(Application.Context.PackageName);
//Intent mainIntent = Intent.MakeRestartActivityTask(launchIntent.Component);
//mainIntent.AddFlags(ActivityFlags.NewTask | ActivityFlags.ClearTop | ActivityFlags.SingleTop);
//mainIntent.PutExtra(address, message);
//context.StartActivity(mainIntent);
Toast.MakeText(context, message, ToastLength.Short).Show();
var f96v = (Vibrator)context.GetSystemService(Context.VibratorService);
long[] vbf = { 100, 200, 200, 500, 500, 400, 400, 100 };
f96v.Cancel();
f96v.Vibrate(VibrationEffect.CreateWaveform(vbf, 1));
var alarmAttributes = new AudioAttributes.Builder()
.SetContentType(AudioContentType.Music)
.SetUsage(AudioUsageKind.Alarm)
.Build();
Android.Net.Uri alarmUri = Android.Net.Uri.Parse($"{ContentResolver.SchemeAndroidResource}://{Application.Context.PackageName}/{Resource.Raw.car_alarm}");
var mNotificationManager = context.GetSystemService(Context.NotificationService) as NotificationManager;
NotificationChannel notificationChannel = new NotificationChannel(Constants.FOREGROUND_CHANNEL_ID, "xxxx", NotificationImportance.Default);
notificationChannel.Importance = NotificationImportance.High;
notificationChannel.EnableLights(true);
notificationChannel.EnableVibration(true);
notificationChannel.SetSound(alarmUri, alarmAttributes);
notificationChannel.SetShowBadge(true);
notificationChannel.SetVibrationPattern(new long[] { 100, 200, 300, 400, 500, 400, 300, 200, 400 });
notificationChannel.SetBypassDnd(true);
notificationChannel.LockscreenVisibility = NotificationVisibility.Public;
var pendingIntent = PendingIntent.GetActivity(context, 0, mainIntent, PendingIntentFlags.UpdateCurrent);
var notification = new Notification.Builder(context, Constants.FOREGROUND_CHANNEL_ID)
.SetColor(Android.Resource.Color.DarkerGray)
.SetContentTitle(address)
.SetOngoing(true)
.SetContentText(message)
.SetSmallIcon(Resource.Mipmap.icon)
.SetContentIntent(pendingIntent);
if (Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.O)
{
notification.SetChannelId(Constants.FOREGROUND_CHANNEL_ID);
mNotificationManager.CreateNotificationChannel(notificationChannel);
mNotificationManager.Notify(Constants.SERVICE_RUNNING_NOTIFICATION_ID, notification.Build());
}
}
Edit 1: in my AlertActivity i have
[Activity(Label = "AlertActivity", Name = "com.xxxx.xxxx.AlertActivity", AlwaysRetainTaskState = true, TurnScreenOn = true, NoHistory = true,
ShowForAllUsers = true, ShowWhenLocked = true,
LaunchMode = Android.Content.PM.LaunchMode.SingleInstance)]
internal class AlertActivity : Activity
{
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
KeyguardManager keyguardManager = (KeyguardManager)GetSystemService(Context.KeyguardService);
PowerManager pm = (PowerManager)GetSystemService(Context.PowerService);
if (keyguardManager != null)
{
keyguardManager.RequestDismissKeyguard(this, null);
PowerManager.WakeLock wl = pm.NewWakeLock(WakeLockFlags.Full | WakeLockFlags.AcquireCausesWakeup, "");
wl.Acquire();
}
Window.AddFlags(WindowManagerFlags.ShowWhenLocked |
WindowManagerFlags.KeepScreenOn |
WindowManagerFlags.DismissKeyguard |
WindowManagerFlags.TurnScreenOn | WindowManagerFlags.AllowLockWhileScreenOn | WindowManagerFlags.TouchableWhenWaking);
// Create your application here
SetContentView(Resource.Layout.activity_alert);
income = FindViewById<TextView>(Resource.Id.alert_text);
start();
}
every single help is life saving :)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|