android下使用service来延迟定时自启第三方应用程序
发表时间:2016-5-3 评论:0 点击 2,560+
最近一款电视聚合直播软件VST全聚合又被xx了,开始会员了,直播功能被独立了出来,成了另外一个软件,小薇直播。
目前应该是安卓智能电视上最好用的一款直播软件了,一般像这类的直播软件都可以设置开机自动运行,方便喜欢看直播电视又不怎么懂电视功能的人使用,问题出来了,此软件目前有点bug。直播软件开机运行了,等一会就闪退了。当小微直播运行不到一分钟的时候就闪退了,不懂得人还不知道哪点去打开,这样可以写一个安卓辅助工具来帮助小薇直播软件开机自动延迟启动。延迟启动不要在ui线程的操作,那样会阻塞ui。看起来就像死机一样很不友好,把自启功能写到service里,让service来操作自启运行,自xx版本之后,没有ui,没有图标的service不能独立启动了,需要借助外力,我们建立个默认的Activity就行了,安装后运行一次以后就不用启动了,以后开机启动就是service了。进入正题。
新建一个默认的app,新建一个MainService 类继承 service,启动第三方app的功能就在service里写。
package com.yyx.qd;
import android.app.Service;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.Process;
import android.util.Log;
/**
*
* 延迟启动第三方应用程序
*
*/
public class MainService extends Service {
@Override
public IBinder onBind(Intent arg0) {
// 不需要提供服务绑定的时候返回null。
return null;
}
public static final String TAG = "info";
private Looper looper = null;
private MyHandler handler = null;
public class MyHandler extends Handler{
public MyHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
Log.v(TAG, "开始sleep 40秒!");
long endTime = System.currentTimeMillis()+40*1000;
while(System.currentTimeMillis()<endTime){
synchronized (this) {
try {
wait(endTime - System.currentTimeMillis());
}catch (InterruptedException e) {
e.printStackTrace();
}
Log.v(TAG, "40 sleep 已经结束!");
try {
Log.v(TAG, "再 sleep 12s!");
Thread.sleep(12000);
Log.v(TAG, "sleep 12s 已经完成!");
PackageManager pm = getPackageManager();
// String packageName = "com.vst.live";
String packageName = "com.speedsoftware.rootexplorer";
Intent myIntent = pm.getLaunchIntentForPackage(packageName);
if (myIntent != null){
startActivity(myIntent);
}
stopSelf(msg.arg1);//注销自己
} catch (Exception e) {
e.printStackTrace();
Log.v(TAG, "应用启动bug了!");
}
}
}
}
}
@Override
public void onCreate() {
super.onCreate();
//创建handler专用后台线程。
HandlerThread thread = new HandlerThread("ServiceStartArguments",Process.THREAD_PRIORITY_BACKGROUND);
thread.start();
//创建线程对应handler
looper = thread.getLooper();
handler = new MyHandler(looper);
Log.d(TAG,"执行--------onCreate()");
}
// @Override
// public void onStart(Intent intent, int startId) {
// // TODO Auto-generated method stub
// super.onStart(intent, startId);
// Log.d(TAG,"执行--------onStart()");
// }
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Message msg = handler.obtainMessage();
msg.arg1 = startId;
handler.sendMessage(msg);
Log.d(TAG,"执行--------onStartCommand()");
//如果被系统关闭将自动重启
return START_STICKY;
}
@Override
public void onDestroy() {
super.onDestroy();
Log.v(TAG, "qdapp服务已经退出---onDestroy()!");
}
}
//┏┓ ┏┓
//┏┛┻━━━┛┻┓
//┃ ┃
//┃ ━ ┃
//┃ ┳┛ ┗┳ ┃
//┃ ┃
//┃ ┻ ┃
//┃ ┃
//┗━┓ ┏━┛
//┃ ┃ 神兽保佑
//┃ ┃ 代码无BUG!
//┃ ┗━━━┓
//┃ ┣┓
//┃ ┏┛
//┗┓┓┏━┳┓┏┛
//┃┫┫ ┃┫┫
//┗┻┛ ┗┻┛
MainActivity 默认界面就行了。
新建BootBroadcastReceiver 类继承BroadcastReceiver,用于接受广播消息。
package com.yyx.qd;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
//该类派生自BroadcastReceiver,覆载方法onReceive中,检测接收到的Intent是否符合BOOT_COMPLETED,如果符合,则启动MainActivity
public class BootBroadcastReceiver extends BroadcastReceiver {
static final String ACTION = "android.intent.action.BOOT_COMPLETED";
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(ACTION)){
Intent service = new Intent(context,MainService.class);
context.startService(service);
Log.v("TAG","开机自启动--MainService.class");
}
}
}
修改AndroidManifest.xml 加入权限,加入自启服务,加入receiver
<;?xml version="1.0" encoding="utf-8"?>
<;manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.yyx.qd"
android:versionCode="1"
android:versionName="1.0" >;
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<;uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="19" />;
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >;
<service
android:name = "com.yyx.qd.MainService">;
<category android:name="android.intent.category.default" />
<;/service>
<;receiver android:name="com.yyx.qd.BootBroadcastReceiver">
<;intent-filter>
<;action android:name="android.intent.action.BOOT_COMPLETED"/>
<;category android:name="android.intent.category.LAUNCHER" />
<;/intent-filter>
<;/receiver>
<;activity
android:name="com.yyx.qd.MainActivity"
android:label="@string/app_name" >;
<intent-filter>
<;action android:name="android.intent.action.MAIN" />
<;category android:name="android.intent.category.LAUNCHER" />
<;/intent-filter>
<;/activity>
<;/application>
</manifest>
如需要加入开机就自动运行一次,在onReceive 中加入如下代码。
try {
Log.v("tag", "第一次开机启动!");
PackageManager pm = context.getPackageManager();
String packageName = "com.vst.live";
// String packageName = "com.speedsoftware.rootexplorer";
Intent myIntent = pm.getLaunchIntentForPackage(packageName);
if (myIntent != null){
context.startActivity(myIntent);
}
} catch (Exception e) {
e.printStackTrace();
Log.v("tag", "应用启动bug了!");
}
编译后使用模拟器来调试代码,安装后第一次开机启动 logcat输出如下信息
开机时启动mainservice,执行oncreate 一系列操作,当启动了应用后我们需要关掉服务。
方便调试不用每次都去重启模拟器。使用adb命令来启动服务。
adb shell am startservice com.yyx.qd/.MainService
注意如果服务没有被关掉,第二次启动就不会从oncreate 开始了,可以查询相关service启动顺序,我这里是关掉了服务的,需要重头开始启动
如上图。
开机启动可以在程序运行里看到启动的服务,如下图。
开机中
开机查看进程
启动后
延时可以使用AlarmManager(闹钟服务)来做,效果会更准确,sleep wait 等等,误差很大的,这里是一个小程序,能实现功能,能够正常运行就行了。
可以把程序做个自定义功能,安装后选择需要启动的软件,那样会更好一些。
还有可以在一段时间内去监听那个app是否退出,如果在那个时间范围内退出了就启动。