我的应用与
BroadcastReceiver
完美兼容。但是,它是通过Activity运行的,并且希望使BroadcastReceiver
始终保持运行(而不仅是我的Activity运行时)。我该如何实现?我已经看过
BroadcastReceiver
的生命周期,但是文档中提到的全部是生命周期仅限于onReceive
方法,而不是保持BroadcastReceiver
检查传入SMS的生命周期。 如何使它持久化?
感谢
#1 楼
您需要在清单中定义一个动作名称为android.intent.action.BOOT_COMPLETED的接收方。<!-- Start the Service if applicable on boot -->
<receiver android:name="com.prac.test.ServiceStarter">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
请确保还包括完整的启动权限。
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
使用Service可以使任何内容持久化。如果系统启动,请使用接收方接收启动事件以重新启动服务。.
启动时启动服务的代码。让服务做您检查短信或任何您想要的工作。您需要在
MyPersistingService
中做您自己的工作。import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
public class ServiceStarter extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Intent i = new Intent("com.prac.test.MyPersistingService");
i.setClass(context, MyPersistingService.class);
context.startService(i);
}
}
#2 楼
服务或引导完成不是强制性的实际上,您不需要实现
Service
或注册到android.intent.action.BOOT_COMPLETED
一些示例显示了如何在以下情况下注册/注销
BroadcastReceiver
活动已创建并销毁。但是,这对于仅在打开应用程序时才有的意图很有用(例如,用于服务/活动之间的内部通信)。但是,如果是SMS,则要收听意图一直(不仅在打开应用程序时)。
还有另一种方法
您可以创建一个
class
,它扩展了BroadcastReceiver
并通过AndroidManifest.xml
注册到所需的意图。这样,BroadcastReceiver
就不会影响您的活动了(并且与活动的生命周期无关)这样,即使您的应用收到短信,Android也会在收到短信后立即自动通知您
BroadcastReceiver
已关闭。AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest>
...
<uses-permission android:name="android.permission.READ_SMS"/>
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
<application>
....
<receiver android:name=".MyCustomBroadcastReceiver">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
</application>
</manifest>
MyCustomBroadcastReceiver.java
public class MyCustomBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if(intent != null) {
String action = intent.getAction();
if(action != null) {
if(action.equals("android.provider.Telephony.SMS_RECEIVED")) {
// DO YOUR STUFF
} else if (action.equals("ANOTHER ACTION")) {
// DO ANOTHER STUFF
}
}
}
}
}
注意事项
您可以将其他Intent过滤器添加到AndroidManifest,并在同一
BroadcastReceiver
中处理所有这些过滤器。仅当您执行长任务时才启动服务。您只需要显示一个通知或更新一些数据库,只需使用上面的代码即可。
评论
如果应用崩溃次数过多或用户强行停止应用,则不会在广播事件中重新启动该应用
–盆地
17年11月22日在14:43
@ W0rmH0le当他不启动活动或应用程序而重新启动手机时会发生什么?他不需要引导完成的接收器吗?
– eawedat
18年7月13日在8:53
@eawedat由于所需的意图已在AndroidManifest中注册,因此即使您尚未打开应用,Android也会调用您的广播接收器类。仅当您计划在设备启动时立即采取措施时,才需要boot_completed意图。但是事实并非如此。他只有在SMS到达时才会采取措施。
– W0rmH0le
18年7月13日在16:20
#3 楼
在清单中添加广播接收器: <receiver android:name=".BootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</receiver>
创建类BootReciever.java
public class BootReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)){
// +++ Do Operation Here +++
}
}
}
#4 楼
除了@Javanator
回答,我想提供一个针对(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
的Android版本的保护套就我而言,这适用于Android SDK 29(10)if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(new Intent(context,FloatingWindow.class));
} else {
context.startService(new Intent(context, FloatingWindow.class));
}
#5 楼
使用此代码并在清单中还提及广播:public class BootService extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)){
Toast.makeText(context, "Boot Completed", Toast.LENGTH_SHORT).show();
//write code here
}
}
}
评论
您可能还需要确保在应用清单文件中定义了RECEIVE_BOOT_COMPLETED权限,此功能才能起作用。
–杰伊·西德里(Jay Sidri)
2012年5月27日在18:01
如果应用程序上下文正在从项目库扩展另一个上下文,这是否可行?
– Maxrunner
2012年8月23日18:00
这项服务如何?
– Slayton
2013年9月25日14:03在
它是一种广播,可让您的服务在设备启动后继续运行。
–罗希特·夏尔马(Rohit Sharma)
2013年9月26日上午8:24
同样重要的是要注意,如果您的应用程序安装到内部存储中,则仅会接收启动完成广播,如果在外部存储中允许,则不会获得广播。如果使您的应用获得广播的启动至关重要,则您可能需要考虑仅允许内部安装。 developer.android.com/guide/topics/data/install-location.html
– Jawnnypoo
2015年3月10日在18:18