当应用程序在后台或被杀死时,BroadcastReceiver 不起作用
BroadcastReceiver does not work when application is in background or killed
我创建了 BroadcastReceiver
,用于检测设备何时收到来电。
我的密码是
[BroadcastReceiver()]
[IntentFilter(new[] { "android.intent.action.PHONE_STATE" })]
public class MyBroadcastReceiver : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
//My implementation
}
}
问题是当应用程序未 运行 或被强制终止时,BroadcastReceiver class 不会被调用。
有人可以帮忙吗?
当应用程序被终止时,BroadcastReceiver 将无法工作,你必须为此使用服务,你可以在服务中使用 BroadcastReceiver 运行 即使应用程序未 运行ning。
BroadcastReceiver does not work when application is not in background or killed
你可以参考:Android Broadcast Receiver not working when the app is killed,正如CommonsWare所说:
Once onReceive()
returns, if you do not have an activity in the foreground and you do not have a running service, your process importance will drop to what the documentation refers to as a "cached process". Your process is eligible to be terminated at any point. Once your process is terminated, your BroadcastReceiver
goes away. Hence, your code as written will be unreliable, as your process might be terminated within your 30-second window.
解决方案:
因此您可以使用 Service
来实现您的功能,这是我的简单演示:
[Service]
[IntentFilter(new String[] { "com.xamarin.DemoService" })]
public class DemoService : Service
{
private static DemoReceiver m_ScreenOffReceiver;
public override IBinder OnBind(Intent intent)
{
return null;
}
public override void OnCreate()
{
registerScreenOffReceiver();
base.OnCreate();
}
public override void OnDestroy()
{
UnregisterReceiver(m_ScreenOffReceiver);
m_ScreenOffReceiver = null;
base.OnDestroy();
}
//From this thread:
public override void OnTaskRemoved(Intent rootIntent)
{
Intent restartServiceIntent = new Intent(Application.Context, typeof(DemoService));
restartServiceIntent.SetPackage(PackageName);
PendingIntent restartServicePendingIntent = PendingIntent.GetService(Application.Context, 1, restartServiceIntent, PendingIntentFlags.OneShot);
AlarmManager alarmService = (AlarmManager)Application.Context.GetSystemService(Context.AlarmService);
alarmService.Set(AlarmType.ElapsedRealtime, SystemClock.ElapsedRealtime() + 1000, restartServicePendingIntent);
base.OnTaskRemoved(rootIntent);
}
private void registerScreenOffReceiver()
{
m_ScreenOffReceiver = new DemoReceiver();
IntentFilter filter = new IntentFilter("com.xamarin.example.TEST");
RegisterReceiver(m_ScreenOffReceiver, filter);
}
}
更新:
如果您需要更高优先级的服务运行以避免它被杀死,您可以尝试使用Foreground Service. As SushiHangover :
作为前台服务,它具有更高的优先级,因此 OS 将认为它最后被杀死,它避免了自动打瞌睡您的服务以在以后的 API 等中节省电池... "downside" 是必须让用户知道它是 运行ning,因此要求放在通知栏中,我个人认为这不是问题,希望这是所有人的硬性要求服务。
我创建了 BroadcastReceiver
,用于检测设备何时收到来电。
我的密码是
[BroadcastReceiver()]
[IntentFilter(new[] { "android.intent.action.PHONE_STATE" })]
public class MyBroadcastReceiver : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
//My implementation
}
}
问题是当应用程序未 运行 或被强制终止时,BroadcastReceiver class 不会被调用。 有人可以帮忙吗?
当应用程序被终止时,BroadcastReceiver 将无法工作,你必须为此使用服务,你可以在服务中使用 BroadcastReceiver 运行 即使应用程序未 运行ning。
BroadcastReceiver does not work when application is not in background or killed
你可以参考:Android Broadcast Receiver not working when the app is killed,正如CommonsWare所说:
Once
onReceive()
returns, if you do not have an activity in the foreground and you do not have a running service, your process importance will drop to what the documentation refers to as a "cached process". Your process is eligible to be terminated at any point. Once your process is terminated, yourBroadcastReceiver
goes away. Hence, your code as written will be unreliable, as your process might be terminated within your 30-second window.
解决方案:
因此您可以使用 Service
来实现您的功能,这是我的简单演示:
[Service]
[IntentFilter(new String[] { "com.xamarin.DemoService" })]
public class DemoService : Service
{
private static DemoReceiver m_ScreenOffReceiver;
public override IBinder OnBind(Intent intent)
{
return null;
}
public override void OnCreate()
{
registerScreenOffReceiver();
base.OnCreate();
}
public override void OnDestroy()
{
UnregisterReceiver(m_ScreenOffReceiver);
m_ScreenOffReceiver = null;
base.OnDestroy();
}
//From this thread:
public override void OnTaskRemoved(Intent rootIntent)
{
Intent restartServiceIntent = new Intent(Application.Context, typeof(DemoService));
restartServiceIntent.SetPackage(PackageName);
PendingIntent restartServicePendingIntent = PendingIntent.GetService(Application.Context, 1, restartServiceIntent, PendingIntentFlags.OneShot);
AlarmManager alarmService = (AlarmManager)Application.Context.GetSystemService(Context.AlarmService);
alarmService.Set(AlarmType.ElapsedRealtime, SystemClock.ElapsedRealtime() + 1000, restartServicePendingIntent);
base.OnTaskRemoved(rootIntent);
}
private void registerScreenOffReceiver()
{
m_ScreenOffReceiver = new DemoReceiver();
IntentFilter filter = new IntentFilter("com.xamarin.example.TEST");
RegisterReceiver(m_ScreenOffReceiver, filter);
}
}
更新:
如果您需要更高优先级的服务运行以避免它被杀死,您可以尝试使用Foreground Service. As SushiHangover
作为前台服务,它具有更高的优先级,因此 OS 将认为它最后被杀死,它避免了自动打瞌睡您的服务以在以后的 API 等中节省电池... "downside" 是必须让用户知道它是 运行ning,因此要求放在通知栏中,我个人认为这不是问题,希望这是所有人的硬性要求服务。