代码之家  ›  专栏  ›  技术社区  ›  XpressGeek

应用程序被终止时广播接收器未调用服务

  •  1
  • XpressGeek  · 技术社区  · 6 年前

    我的目标是 重新启动服务 当应用程序处于后台,甚至在主页上被清除时。应用程序(&A);当应用程序处于前台和后台时,服务运行得很好,但当我强行关闭应用程序(从主页清除)时 服务 停止工作。没关系,但我实现了 广播接收机 重新启动 服务 但看起来 its(广播接收器) 甚至都没打过电话 它本身 或者 服务 而应用程序被强制删除/从主页上清除。

    我的设备是: 小米红米注4

    我在这里包括了我的代码:

    主要活动。JAVA

    package com.turzo.servicetest;
    
    import android.app.ActivityManager;
    import android.content.BroadcastReceiver;
    import android.content.Context;
    import android.content.Intent;
    import android.content.IntentFilter;
    import android.net.ConnectivityManager;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.util.Log;
    
    public class MainActivity extends AppCompatActivity {
    
        private String TAG = "ServiceTest";
        Intent mServiceIntent;
        private SensorService mSensorService;
    
        Context ctx;
    
        public Context getCtx() {
            return ctx;
        }
    
    
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            ctx = this;
            registerRec();
            setContentView(R.layout.activity_main);
    
            mSensorService = new SensorService(getCtx());
            mServiceIntent = new Intent(getCtx(), mSensorService.getClass());
            if (!isMyServiceRunning(mSensorService.getClass())) {
                startService(mServiceIntent);
            }
    
        }
    
        private boolean isMyServiceRunning(Class<?> serviceClass) {
            ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
            for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
                if (serviceClass.getName().equals(service.service.getClassName())) {
                    Log.i (TAG, true+"");
                    return true;
                }
            }
            Log.i (TAG, false+"");
            return false;
        }
    
    
        @Override
        protected void onDestroy() {
           stopService(mServiceIntent);
            Log.i(TAG, "onDestroy!");
            super.onDestroy();
    
        }
    
        public void registerRec(){
    
    
            SensorRestarterBroadcastReceiver myreceiver = new SensorRestarterBroadcastReceiver();
            IntentFilter intentFilter = new IntentFilter();
            intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
            registerReceiver((BroadcastReceiver) myreceiver, intentFilter);
        }
    
    
    
    
    
    
    
    }
    

    传感器维修。JAVA

    package com.turzo.servicetest;
    
    import android.app.Service;
    import android.content.BroadcastReceiver;
    import android.content.Context;
    import android.content.Intent;
    import android.content.IntentFilter;
    import android.net.ConnectivityManager;
    import android.os.IBinder;
    import android.support.annotation.Nullable;
    import android.util.Log;
    
    import java.util.Timer;
    import java.util.TimerTask;
    
    
    public class SensorService extends Service {
        public int counter=0;
        private String TAG = "ServiceTest";
        public SensorService(Context applicationContext) {
            super();
            Log.i(TAG , "here I am!");
        }
    
        public SensorService() {
        }
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            super.onStartCommand(intent, flags, startId);
    
            startTimer();
            return START_STICKY;
        }
    
        @Override
        public void onDestroy() {
            super.onDestroy();
            Log.i(TAG , "ondestroy!");
            Intent broadcastIntent = new Intent("com.turzo.servicetest.ActivityRecognition.RestartSensor");
            sendBroadcast(broadcastIntent);
            stoptimertask();
        }
    
        private Timer timer;
        private TimerTask timerTask;
        long oldTime=0;
        public void startTimer() {
            //set a new Timer
            timer = new Timer();
    
            //initialize the TimerTask's job
            initializeTimerTask();
    
            //schedule the timer, to wake up every 1 second
            timer.schedule(timerTask, 1000, 1000); //
        }
    
        /**
         * it sets the timer to print the counter every x seconds
         */
        public void initializeTimerTask() {
            timerTask = new TimerTask() {
                public void run() {
                    Log.i(TAG , "in timer ++++  "+ (counter++));
                }
            };
        }
    
        /**
         * not needed
         */
        public void stoptimertask() {
            //stop the timer, if it's not already null
            if (timer != null) {
                timer.cancel();
                timer = null;
            }
        }
    
        @Nullable
        @Override
        public IBinder onBind(Intent intent) {
            return null;
        }
    
    
    } 
    

    SensorRestarterBroadcastReceiver。JAVA

    package com.turzo.servicetest;
    
    import android.content.BroadcastReceiver;
    import android.content.Context;
    import android.content.Intent;
    import android.util.Log;
    
    
    public class SensorRestarterBroadcastReceiver extends BroadcastReceiver {
    
        @Override
        public void onReceive(Context context, Intent intent) {
            Log.i(SensorRestarterBroadcastReceiver.class.getSimpleName(), "Service Stops! Oooooooooooooppppssssss!!!!");
    
            context.startService(new Intent(context, SensorService.class));
        }
    
    }
    

    AndroidManifext。xml

        <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.turzo.servicetest">
    
        <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>
    
    
            <service
                android:name="com.turzo.servicetest.SensorService"
                android:enabled="true" >
            </service>
    
            <receiver
                android:name="com.turzo.servicetest.SensorRestarterBroadcastReceiver"
                android:enabled="true"
                android:exported="true"
                android:label="RestartServiceWhenStopped">
                <intent-filter>
                    <action android:name="com.turzo.servicetest.ActivityRecognition.RestartSensor"/>
                </intent-filter>
            </receiver>
    
    
        </application>
    
    </manifest> 
    
    1 回复  |  直到 6 年前
        1
  •  1
  •   ADM    6 年前

    您应该重新启动 Service 在里面 onTaskRemoved() .

      @Override
        public void onTaskRemoved(Intent rootIntent) {
            Intent restartService = new Intent(getApplicationContext(),
                    this.getClass());
            restartService.setPackage(getPackageName());
            PendingIntent restartServicePI = PendingIntent.getService(
                    getApplicationContext(), 1, restartService,
                    PendingIntent.FLAG_ONE_SHOT);
            AlarmManager alarmService = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
            alarmService.set(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + 1000, restartServicePI);
        }
    

    注:- 从android O开始。你不能打电话 startService .

    如果针对Android 8.0的应用程序在不允许创建后台服务的情况下尝试使用该方法,startService()方法现在会抛出非法状态异常。

    这不适用于前台服务,因为用户可以注意到这些服务。它可以在后台运行,并在顶部显示通知。默认情况下,这些限制仅适用于针对Android 8.0(API级别26)或更高版本的应用程序。然而,用户可以从设置屏幕为任何应用程序启用大多数这些限制,即使该应用程序的目标API级别低于26。因此,如果用户启用API 26以下的限制 服务 不起作用。
    阅读 Background Execution Limits .

    所以尽量避免使用 服务 如果可以的话。利用 WorkManager 如果符合要求。