目录
本文导读
因为业务需要,项目中需要实现 APP 跟随系统开机后自动运行,环境是:minSdkVersion 17、targetSdkVersion 28、Android Studio 3.1.2,本人手机 系统为 Android 5.1.1。
网络上有太多的文章介绍 Android 应用如何根据系统开机自动运行,但是实际操作起来会发现并没有说的那么简单。
所以本文先将所有的注意事项介绍在前,然后再讲具体的实现。
1)注意事项 1:在全局配置文件:AndroidManifest.xml 中
1.1)android:installLocation="internalOnly":表示程序只能被安装在内存中,如果内存为空,则程序将不能成功安装,因为安装在 SD 卡中时会接收不到系统的广播消息(暂时未验证)
1.2)<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />:添加允许程序随系统开机而自动运行的权限
1.3)<!--注册接收系统开机广播消息的广播接收者-->
<receiver
android:name=".broadcastReceiver.MyBroadcastReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.HOME" />
</intent-filter>
</receiver>
2)注意事项 2 :就是手机上的设置问题。为了防止恶意软件随意的开机自启,拖慢系统的开机速度,损害用户体验,通常手机上类似 “手机管家” 等软件默认是不允许它们开机自启的,这也是本人反反复复测试失败的原因。
因为 Android 系统是开源的,所以各大手机厂商可能略有不同,以本人的 Nubia(努比亚) 手机为例,它默认出厂自带一个 "手机管家" 软件,如下所示,必须将自己需要开机自启的应用设置为通过,否则测试一个下午也不见成功。
3)注意事项 3:开机自启的 APP 安装后启动系统时,第一次要手动开启 APP,后面再次开机时,APP 就能正常自启了。
应用开机自启
1、原理就不多说了,网上很多文章都已经说过了,核心就是因为 Android 系统在很多时刻都会给所有的应用广播消息,比如 系统开机、电量低,网络状态变化等,只需自己静态注册广播接收者,然后接收系统发出的广播消息然后处理即可。
2、代码其实非常简单,就是这些细节问题导致容易导致失败,效果如下,系统开机后,启动 APP,现在开始上代码。
布局文件 activity_main.xml 文件内容如下,就是 helloWorld 默认生成的内容,
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
自定义广播接收者 继承 android.content.BroadcastReceiver:
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.widget.Toast;
import com.lct.www.yuan.MainActivity;
/**
* 自定义 广播接收者
* 继承 android.content.BroadcastReceiver
*/
public class MyBroadcastReceiver extends BroadcastReceiver {
private final String ACTION_BOOT = "android.intent.action.BOOT_COMPLETED";
/**
* 接收广播消息后都会进入 onReceive 方法,然后要做的就是对相应的消息做出相应的处理
*
* @param context 表示广播接收器所运行的上下文
* @param intent 表示广播接收器收到的Intent
*/
@Override
public void onReceive(Context context, Intent intent) {
Log.i("Wmx logs::", intent.getAction());
Toast.makeText(context, intent.getAction(), Toast.LENGTH_LONG).show();
/**
* 如果 系统 启动的消息,则启动 APP 主页活动
*/
if (ACTION_BOOT.equals(intent.getAction())) {
Intent intentMainActivity = new Intent(context, MainActivity.class);
intentMainActivity.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intentMainActivity);
Toast.makeText(context, "开机完毕~", Toast.LENGTH_LONG).show();
}
}
}
主活动 MainActivity.java 内容如下:
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
Log.i("Wmx logs::", "活动创建...");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
/**
* 当活动被销毁时
*/
@Override
protected void onDestroy() {
Log.i("Wmx logs::", "活动销毁...");
super.onDestroy();
/**注销 unregisterReceiver(),否则可能引起内存泄露。*/
}
}
全局配置文件 AndroidManifest.xml 内容如下:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.lct.www.yuan"
android:installLocation="internalOnly">
<!--添加允许程序开机自动运行权限-->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<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>
<!--注册接收系统开机广播消息的广播接收者-->
<receiver
android:name=".broadcastReceiver.MyBroadcastReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.HOME" />
</intent-filter>
</receiver>
</application>
</manifest>
本文环境:minSdkVersion 17、targetSdkVersion 28、Android Studio 3.1.2,本人手机 系统为 Android 5.1.1,代码完全亲测有效。
开机自启的 APP 安装后启动系统时,第一次要手动开启 APP,后面再次开机时,APP 就能正常自启了。
常用系统事件
有许多系统产生的事件被定义为类 Intent 中的静态常量值。下面的表格列举了重要的系统事件。
事件常量 | 描述 |
---|---|
android.intent.action.BATTERY_CHANGED | 持久的广播,包含电池的充电状态,级别和其他信息。 |
android.intent.action.BATTERY_LOW | 标识设备的低电量条件。 |
android.intent.action.BATTERY_OKAY | 标识电池在电量低之后,现在已经好了。 |
android.intent.action.BOOT_COMPLETED | 在系统完成启动后广播一次。 |
android.intent.action.BUG_REPORT | 显示报告bug的活动。 |
android.intent.action.CALL | 执行呼叫数据指定的某人。 |
android.intent.action.CALL_BUTTON | 用户点击"呼叫"按钮打开拨号器或者其他拨号的合适界面。 |
android.intent.action.DATE_CHANGED | 日期发生改变。 |
android.intent.action.REBOOT | 设备重启。 |