Android实战开发篇 双服务加时间广播和屏幕关闭解锁广播保护APP存活

Posted 彭老希

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android实战开发篇 双服务加时间广播和屏幕关闭解锁广播保护APP存活相关的知识,希望对你有一定的参考价值。

一、androidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="liuxiaozhu.com.appkeepalive">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:name=".MyAppliction"
        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>
        
        <!--intent-filter android:priority="1000"-->
         <!--将服务的优先级设置为最高1000-->
         
        <service
            android:name=".service.MyServiceOne"
            android:persistent="true"
            android:process=":remote">
            <intent-filter android:priority="1000">
                <action android:name="myservice1" />
            </intent-filter>
        </service>
        
        <service
            android:name=".service.MyServiceTwo"
            android:persistent="true"
            android:process=":remote">
            <intent-filter android:priority="1000">
                <action android:name="myservice2" />
            </intent-filter>
        </service>
    </application>

</manifest>

二、服务 【双服务互相开启】

(1)服务一

/**
* 服务一 :MyServiceOne 
* 主要任务:创建就开启服务二
*/
public class MyServiceOne extends Service {
    public final static String TAG = "myservice1";

    public MyServiceOne() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.e(TAG, "onStartCommand");
        startServiceTwo();
        //START_REDELIVER_INTENT,START_NOT_STICKY和START_STICKY区别不是太明白
        //如果这个Service被系统Kill了或者app被Kill了,Service还能自动重启。
        return START_REDELIVER_INTENT;
    }


    @Override
    public void onCreate() {
        super.onCreate();
        Log.e(TAG, "服务创建了");
       startServiceTwo();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.e(TAG, "服务销毁了");
        startServiceTwo();
    }

    private void startServiceTwo() {
        boolean b = ServiceMangerUtils.isServiceWorked(MyServiceOne.this, "myservice2");
        if(!b) {
            Intent service = new Intent(MyServiceOne.this, MyServiceTwo.class);
            startService(service);
            Log.e(TAG, "Start ServiceTwo");
        }
    }
}

(2)服务二

/**
* 服务二 :MyServiceTwo 
* 主要任务:创建就开启服务一
*/
public class MyServiceTwo extends Service {
    public final static String TAG = "myservice2";

    public MyServiceTwo() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.e(TAG, "onStartCommand");
        startServiceOne();
        //如果这个Service被系统Kill了或者app被Kill了,Service还能自动重启。
        return START_REDELIVER_INTENT;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.e(TAG, "服务创建了");
        startServiceOne();
    }
    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.e(TAG, "服务销毁了");
        startServiceOne();

    }

    /**
     * 检查服务是否存在,不存在唤起
     */
    private void startServiceOne() {
        boolean b = ServiceMangerUtils.isServiceWorked(MyServiceTwo.this, "myservice1");
        if (!b) {
            Intent service = new Intent(MyServiceTwo.this, MyServiceOne.class);
            startService(service);
            Log.e(TAG, "start ServiceOne");
        }
    }
}

二、服务监测工具类

public class ServiceMangerUtils {
    /**
     * 判断服务是否运行
     *
     * @param context
     * @param serviceName
     * @return
     */
    public static boolean isServiceWorked(Context context, String serviceName) {
        ActivityManager myManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        //获取当前所有服务
        ArrayList<ActivityManager.RunningServiceInfo> runningService =
                (ArrayList<ActivityManager.RunningServiceInfo>) myManager.getRunningServices(Integer.MAX_VALUE);
        for (int i = 0; i < runningService.size(); i++) {
            if (runningService.get(i).service.getClassName().equals(serviceName)) {
                return true;
            }
        }
        return false;
    }
}

三、时间广播拉起服务

/**
 * 用来监听手机时间广播(在appliytion里开启广播),每一分钟系统会发送一次
 * 该广播只需要拉起MyServiceOne 
 */

public class MyBroadcast extends BroadcastReceiver {
    private boolean isServiceRunning = false;

    @Override
    public void onReceive(Context context, Intent intent) {

        if (intent.getAction().equals(Intent.ACTION_TIME_TICK)) {//如果广播是每分钟发送一次的时间广播
            Log.e("timeBroad", "时间变化了");
            isServiceRunning = ServiceMangerUtils.isServiceWorked(MyAppliction.getmContext(), "myservice1");
            if (!isServiceRunning) {
                Intent i = new Intent(context, MyServiceOne.class);
                context.startService(i);
            }
        }
        if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
            Log.e("timeBroad", "屏幕解锁了");
            isServiceRunning = ServiceMangerUtils.isServiceWorked(MyAppliction.getmContext(), "myservice1");
            if (!isServiceRunning) {
                Intent i = new Intent(context, MyServiceOne.class);
                context.startService(i);
            }
        }
        if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
            Log.e("timeBroad", "屏幕关闭了");
            isServiceRunning = ServiceMangerUtils.isServiceWorked(MyAppliction.getmContext(), "myservice1");
            if (!isServiceRunning) {
                Intent i = new Intent(context, MyServiceOne.class);
                context.startService(i);
            }
        }
    }


}

四、【关键】全局注册 MyAppliction.java

public class MyAppliction extends Application {
    private static Context mContext;
    @Override
    public void onCreate() {
        super.onCreate();
        mContext = getApplicationContext();
        //开启系统时间广播(动态注册,不能静态注册)
        //部分机型会屏蔽时间广播
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(Intent.ACTION_TIME_TICK);//系统时间,每分钟发送一次
        intentFilter.addAction(Intent.ACTION_SCREEN_ON);//屏幕打开(解锁),
        intentFilter.addAction(Intent.ACTION_SCREEN_OFF);//屏幕关闭
        MyBroadcast myBroadcast = new MyBroadcast();
        registerReceiver(myBroadcast, intentFilter);
        startMyService();
    }

    public static Context getmContext() {
        return mContext;
    }
    /**
     * 开启双服务
     */
    private void startMyService() {
        Intent serviceOne = new Intent();
        serviceOne.setClass(this, MyServiceOne.class);
        startService(serviceOne);
    }

}

五、应用

在AndroidManifest.xml中添加上述的全局服务开启,应用即开启了双服务保护

android:name=".MyAppliction"

/***
 * 程序保活,即活动继承了 AppCompatActivity 便自动开启了双服务保活
 */
public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

}

以上是关于Android实战开发篇 双服务加时间广播和屏幕关闭解锁广播保护APP存活的主要内容,如果未能解决你的问题,请参考以下文章

Android实战开发篇 监听广播唤起Activity(活动)Dialog弹窗的方案

Android实战开发篇 监听应用APK卸载覆盖安装的广播无法接受的问题解决

Android总结篇系列:Android广播机制----学习

好文推荐kafkastreams加时间窗口的count

Android广播机制

Android 监听屏幕唤醒和关闭的广播