首页 > 解决方案 > 即使应用程序在棉花糖中被杀死,如何避免杀死后台服务?

问题描述

我想创建一个 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);
        }
    }

标签: androidlocationandroid-6.0-marshmallowbackground-service

解决方案


您的服务在 Android 8 上没有被杀死的事实听起来像是运气的问题。可能你的 Android 8 手机有足够的资源并保持服务活着,但它迟早会被杀死。

为了实现您的目标,您需要在前台运行您的服务。查看官方文档

仅当您的应用程序需要执行用户注意到的任务时,您才应该使用前台服务,即使他们没有直接与应用程序交互。因此,前台服务必须显示优先级为 PRIORITY_LOW 或更高的状态栏通知,这有助于确保用户了解您的应用正在做什么。如果操作的重要性足够低以至于您想使用最低优先级通知,那么您可能不应该使用服务;相反,请考虑使用计划作业。

每个运行服务的应用都会给系统增加额外的负载,消耗系统资源。如果应用程序试图通过使用低优先级通知来隐藏其服务,这可能会影响用户正在与之交互的应用程序的性能。因此,如果应用程序尝试运行具有最低优先级通知的服务,系统会在通知抽屉的底部调用应用程序的行为。


推荐阅读