如何避免杀死后台应用程序,甚至在棉花糖中杀死应用程序?

时间:2019-01-31 09:31:40

标签: android location android-6.0-marshmallow background-service

我想创建一个Android应用来使用Android服务跟踪实时位置。但是当我从最近的应用程序列表中删除该应用程序时,Service也被Android 6(Huawei Y3 2017)杀死了。但是相同的代码也可以在android 8上运行。请帮助我解决问题。请在下面找到我的代码。

我在onStartCommand方法中添加了START_STICKY和START_REDELIVER_INTENT标志。

我试图用onTaskRemoved方法重新启动服务。

试图将android:process属性添加到

Manifest.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);
        }
    }

2 个答案:

答案 0 :(得分:1)

您的服务并未在Android 8上被淘汰的事实听起来很幸运。您的Android 8手机可能有足够的资源并可以保持该服务正常运行,但迟早会被终止。

要实现目标,您需要在前台运行服务。检出official documentation

  

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

     

每个运行服务的应用都会给系统带来额外的负担,从而消耗系统资源。如果应用程序尝试通过使用低优先级通知来隐藏其服务,则可能会削弱用户正在与之交互的应用程序的性能。因此,如果应用程序尝试使用最低优先级通知运行服务,则系统会在通知抽屉的底部调出该应用程序的行为。

答案 1 :(得分:-1)

尝试在您的主要活动中注册您的广播接收器,以及您希望接收器这样做的意图动作

private void RegisteringBroadcastReciever()
{
   broadcastReceiver = new XYZIntentReceiver();
   var filter = new IntentFilter();
   filter.AddAction("hearing.arc.intent.action.action1");
   filter.AddAction("hearing.arc.intent.action.action2");
   filter.AddAction("hearing.arc.intent.action.action3");
   filter.AddAction("hearing.arc.intent.action.action4");           
   AppInstance.ApplicationContext.RegisterReceiver(broadcastReceiver, filter);
} 

即使我有类似的问题。但是我在Oreo设备上也遇到了这个问题。但是此修复解决了我的问题。 Android要求在onDestroy()方法中注销此接收器。但是不要那样做。可能会再次终止该服务。

希望这会有所帮助。