在android 9.0或更高版本上连续运行服务



我的应用程序是关于备份SMS/MMS消息的。

到目前为止,我的想法是在它们到达或发送时立即将CCD_ 2备份到CCD_,然后定期将创建的XML文件上传到云存储,即使应用程序没有运行。

这种方法是我发现的唯一一种足够可靠的方法,不会丢失任何对话。

做所有这些的函数基本上都是完整的,但我注意到谷歌不允许service在设备上是running continuously

所以,我的问题是,有没有一种方法可以让servicebackground中连续运行,而不会在一段时间后被杀死。我对foreground services不感兴趣,因为我不希望我的用户一直显示notification

这基本上是我的第一个应用程序,我甚至不确定我的备份软件方法是否正确。

我很想知道我应该如何解决这个问题。此刻我所关心的是,我的应用程序会立即备份sendreceive上的每一次对话。

您可以在服务中使用android.permission.BIND_NOTIFICATION_LISTENER_SERVICE权限但您必须向用户请求"瞌睡模式"的android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS权限,然后在服务中为您的BroadCastReceiver使用Thread。这种方式保证了您的服务始终运行,但它将花费电池寿命。我已经为我的应用程序尝试并测试了这一点,从api级别19到28,甚至在诺基亚等禁用了androidO后台运行服务的设备中也从未停止过,但有了这个技巧,你可以让它继续运行。像Gameboosters或Cleaners这样的应用程序也使用这个技巧来保持那里的服务始终运行。

更新:

<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
<service
android:name=".Service.NLService"
android:enabled="true"
android:exported="true"
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"
>
<intent-filter>
<action android:name="android.service.notification.NotificationListenerService" />
</intent-filter>
</service>

服务

@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
public class NLService extends NotificationListenerService {
private static final String TAG = NLService.class.getSimpleName();
@Override
public void onCreate() {
super.onCreate();
new Thread(new Runnable() {
@Override
public void run() {
while (true)
try {
doSomeThing(NLService.this);
Thread.sleep(6000);
} catch (Exception ignore) {
}
}
}).start();
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Override
public void onNotificationPosted(StatusBarNotification sbn) {
doSomeThing(this);
}
@Override
public void onNotificationRemoved(StatusBarNotification sbn) {
doSomeThing(this);
}

请求权限

private static final String ACTION_NOTIFICATION_LISTENER_SETTINGS = "android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS";
public void askForNotificationServicePermission() {
context.startActivity(new Intent(ACTION_NOTIFICATION_LISTENER_SETTINGS));
}
public void askForDozeModePermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
Intent intent = new Intent();
String packageName = context.getPackageName();
intent.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
intent.setData(Uri.parse("package:" + packageName));
context.startActivity(intent);
}
}

doSomeThing(this);是您想要运行的一些方法,例如您的broudcastreceiver。

最新更新