现在很多公司都开始做智能硬件产品,主要是在Android开发板上面开发应用app,尤其这两年物联网越来越火,这方面的需求越来越多,目前公司也是做智能公交站台的,需要开发的app实现开机自启动,异常崩溃重新启动,版本升级静默安装并自动打开,定时开关机,感觉都要跟Android系统打交道,查了很多资料,开发的时候也遇到很多坑,终于整合完成了,现在连夜分享出去,希望能够帮到大家:
首先把实现这些功所要用到的权限全部加入清单文件中:
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_FRAME_BUFFER" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.REBOOT" />
<uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
<uses-permission android:name="android.permission.DEVICE_POWER" />
<uses-permission android:name="android.permission.SHUTDOWN" />
<uses-permission android:name="android.permission.READ_FRAME_BUFFER" />
<uses-permission android:name="android.permission.WRITE_MEDIA_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.SERIAL_PORT" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
<uses-permission android:name="android.permission.INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.INSTALL_LOCATION_PROVIDER" />
<uses-permission android:name="android.permission.DELETE_PACKAGES" />
1,开机自启动:开启一个广播监控就好了
<uses-permission
android
:name=
"android.permission.READ_MEDIA_STORAGE"
/>
<uses-permission
android
:name=
"android.permission.SET_TIME"
/>
<uses-permission
android
:name=
"android.permission.STATUS_BAR"
/>
<uses-permission
android
:name=
"android.permission.ACCESS_FINE_LOCATION"
/>
<uses-permission
android
:name=
"android.permission.ACCESS_CACHE_FILESYSTEM"
/>
<uses-permission
android
:name=
"android.permission.DELETE_CACHE_FILES"
/>
<uses-permission
android
:name=
"android.permission.MODIFY_SOUND_SETTINGS"
/>
<uses-permission
android
:name=
"android.permission.MODIFY_AUDIO_SETTINGS"
/>
/**
* 我们通过广播来启动Activity的时候如果不设置intent的FLAG_ACTIVITY_NEW_TASK属性,就会报这个异常:
* android.util.AndroidRuntimeException:
* Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag.
* 就是说在activity上下文之外调用startActivity需要FLAG_ACTIVITY_NEW_TASK属性。
*
* @author Administrator
*/
public class BootCompletedReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//UpdateActivity.class是程序启动的主Activity
Intent intent1 = new Intent(context, UpdateActivity.class);
intent1.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent1);
}
}
还要在清单文件中注册广播:
<!-- Android 开机自启动示例程序。使用广播方式接受,采用Android自带存储SharedPreferences存储开机自启动的设置。 -->
<!-- 开机自启动广播接受 -->
<receiver android:name=".receiver.BootCompletedReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.HOME" />
</intent-filter>
</receiver>
2,app崩溃自启动:在程序入口Application中实现。
不过有些异常崩溃,但是进程并没有杀死,这种请款就没效果了,可以参考兄弟博客(看门狗的实现):
public class BaseApplication extends Application {
public static Context mContext;
public static Context getContext() {
return mContext;
}
@Override
public void onCreate() {
super.onCreate();
//获取全局上下文
mContext = getApplicationContext();
//程序崩溃异常捕获并自动重启
Thread.setDefaultUncaughtExceptionHandler(restartHandler);
}
private Thread.UncaughtExceptionHandler restartHandler = new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread t, Throwable e) {
Intent intent = new Intent(mContext, UpdateActivity.class);
//重启应用,得使用PendingIntent
PendingIntent restartIntent = PendingIntent.getActivity(mContext, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
mAlarmManager.set(AlarmManager.RTC, System.currentTimeMillis() + 2000,
restartIntent); // 2秒钟后重启应用
//退出程序
android.os.Process.killProcess(android.os.Process.myPid()); //结束当前进程
}
};
}
3,apk实现静默安装和自动打开,这个需要系统签名,不过做智能硬件开发都会有系统签名的,也很简单,这里就不说了:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:sharedUserId="android:sharedUserId="android.uid.system"">
需要的权限
<uses-permission android:name="android.permission.INSTALL_LOCATION_PROVIDER" />
<uses-permission android:name="android.permission.INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.DELETE_PACKAGES" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
方法:
/**
* 说明:
*
* android.os.Process.killProcess(android.os.Process.myPid());如果不加,最后不会提示完成、打开。
*
* intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);如果不加,最后安装完成,点打开,无法打开新版本应用。
*/
private void installAPK() {
//apkPath是程序从服务器上面下载的安装包存储位置
String apkPath = Environment.getExternalStorageDirectory().getPath().toString() + File.separator + "test.apk";
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setDataAndType(Uri.fromFile(new File(apkPath)), "application/vnd.android.package-archive");
startActivity(intent);
android.os.Process.killProcess(android.os.Process.myPid());
}
4,实现自动开关机功能见博客:
只有关机功能,开机功能没有实现不过Android开发板可以通过电源管理实现自动开机。
总结:这几个功能基本都要用到系统签名,上面有很多权限都是需要系统签名才有效的,很多会报错,提示就是要系统签名才能使用,这个不影响程序的开发,不签名也可以运行程序,这种报错可以忽略。
有不当之处请给与提示。目前这些功能全部整合到公司项目中。