android - 即使应用程序在棉花糖中被杀死,如何避免杀死后台服务?
问题描述
我想创建一个 android 应用程序来使用 android 服务跟踪实时位置。但是当我从最近的应用程序列表中杀死该应用程序时,Service 也在 android 6(华为 y3 2017)中被杀死。但相同的代码适用于 android 8。请帮我解决我的问题。请在下面找到我的代码。
我在 onStartCommand 方法中添加了 START_STICKY 和 START_REDELIVER_INTENT 标志。
我试图在 onTaskRemoved 方法中重新启动服务。
试图将 android:process 属性添加到
清单.xml
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".Login" />
<activity android:name=".Home" />
<service
android:name=".TrackingService"
android:enabled="true"
android:exported="true" />
</application>
这就是如何在家庭活动中启动我的服务
Intent intent = new Intent(Home.this, TrackingService.class);
startService(intent);
TrackingService.java 服务文件
@Override
public void onCreate(){
buildNotification();
requestLocationUpdates();
Toast.makeText(getBaseContext(), "Service Started", Toast.LENGTH_SHORT).show();
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId){
return START_STICKY;
}
private void buildNotification() {
Random random = new Random();
int m = random.nextInt(9999 - 1000) + 1000;
String stop = "stop";
registerReceiver(stopReceiver, new IntentFilter(stop));
PendingIntent broadcastIntent = PendingIntent.getBroadcast(this, 0, new Intent(stop), PendingIntent.FLAG_UPDATE_CURRENT);
Notification.Builder builder = new Notification.Builder(this)
.setContentTitle(getString(R.string.app_name))
.setContentText(getString(R.string.tracking_enabled_notif))
.setOngoing(true)
.setContentIntent(broadcastIntent);
startForeground(m, builder.build());
}
protected BroadcastReceiver stopReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
unregisterReceiver(stopReceiver);
stopSelf();
}
};
private void requestLocationUpdates() {
LocationRequest request = new LocationRequest();
request.setInterval(15000);
request.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
FusedLocationProviderClient client = LocationServices.getFusedLocationProviderClient(this);
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
final DatabaseReference ref = FirebaseDatabase.getInstance().getReference("connected/"+user.getUid());
int permission = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION);
if (permission == PackageManager.PERMISSION_GRANTED) {
client.requestLocationUpdates(request, new LocationCallback() {
@Override
public void onLocationResult(LocationResult locationResult) {
android.location.Location location =
locationResult.getLastLocation();
String lat = Double.toString(location.getLatitude());
String lng = Double.toString(location.getLongitude());
Toast.makeText(getBaseContext(), "Lat "+lat, Toast.LENGTH_SHORT).show();
if (location != null) {
ref.setValue(locationObj);
}
enter code here}
}, null);
}
}
解决方案
您的服务在 Android 8 上没有被杀死的事实听起来像是运气的问题。可能你的 Android 8 手机有足够的资源并保持服务活着,但它迟早会被杀死。
为了实现您的目标,您需要在前台运行您的服务。查看官方文档:
仅当您的应用程序需要执行用户注意到的任务时,您才应该使用前台服务,即使他们没有直接与应用程序交互。因此,前台服务必须显示优先级为 PRIORITY_LOW 或更高的状态栏通知,这有助于确保用户了解您的应用正在做什么。如果操作的重要性足够低以至于您想使用最低优先级通知,那么您可能不应该使用服务;相反,请考虑使用计划作业。
每个运行服务的应用都会给系统增加额外的负载,消耗系统资源。如果应用程序试图通过使用低优先级通知来隐藏其服务,这可能会影响用户正在与之交互的应用程序的性能。因此,如果应用程序尝试运行具有最低优先级通知的服务,系统会在通知抽屉的底部调用应用程序的行为。
推荐阅读
- postgresql - 在我的本地 postgres-data 卷中看不到任何文件
- java - html 文件被下载而不是被重定向到它
- spring - 从 spring Activiti starter 中排除 spring security 导致 spring secutiry 问题
- java - 相同的命令通过 bash 运行,Java 的 ProcessBuilder api 得到不同的输出
- android - YUV 输出的目标分辨率上的 CameraX alpha5 错误?
- reporting-services - 具有反向代理的主数据服务
- java - 当负数包含括号时,如何将字符串值汇总为 Big.Decimal?
- java - 如何将单击的数组项保存到sqlite
- android - 单击通知按钮不会在颤动中打开应用程序
- android - Google Play:如何访问“Play 管理中心的目标受众和内容部分”