APP添加自启动权限,重启设备后自动打开APP。
1.AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.mofang.call.callphone">
<!-- 声明前台服务的权限 -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<!-- 注册 BOOT_COMPLETED 广播接收器 -->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application
android:name=".App"
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:extractNativeLibs="true"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:requestLegacyExternalStorage="true"
android:roundIcon="@mipmap/ic_launcher"
android:supportsRtl="true"
android:theme="@style/Theme.MFCallPhone"
android:usesCleartextTraffic="true"
tools:targetApi="31">
<service android:name=".MyAppLaunchService"
android:exported="true" />
<!-- 注册接收 BOOT_COMPLETED 广播的接收器 -->
<receiver
android:name=".BootReceiver"
android:enabled="true"
android:exported="true"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
</manifest>
2.BootReceiver
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.os.Build
/// 创建一个接收 BOOT_COMPLETED 广播的接收器类 BootReceiver。
class BootReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
if (intent.action == Intent.ACTION_BOOT_COMPLETED) {
// 启动你的服务或活动
val serviceIntent = Intent(context, MyAppLaunchService::class.java)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(serviceIntent)
} else {
context.startService(serviceIntent)
}
}
}
}
3.MyAppLaunchService
import android.annotation.SuppressLint
import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.app.Service
import android.content.Intent
import android.os.Build
import android.os.IBinder
import androidx.core.app.NotificationCompat
/// 创建一个服务(例如 MyAppLaunchService),在设备重启后由 BootReceiver 启动。
class MyAppLaunchService : Service() {
override fun onCreate() {
super.onCreate()
createNotificationChannel()
}
override fun onBind(intent: Intent?): IBinder? {
return null
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
// 你的业务逻辑...
// 启动前台服务
startForegroundService()
// 启动应用的主活动
restartApp()
return START_STICKY
}
private fun restartApp() {
val packageManager = packageManager
val intent = packageManager.getLaunchIntentForPackage(packageName)
if (intent != null) {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
startActivity(intent)
}
}
private fun createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val serviceChannel = NotificationChannel(
MyForegroundService.CHANNEL_ID,
"Foreground Service Channel",
NotificationManager.IMPORTANCE_DEFAULT
)
val manager = getSystemService(NotificationManager::class.java)
manager.createNotificationChannel(serviceChannel)
}
}
@SuppressLint("ForegroundServiceType")
private fun startForegroundService() {
val notificationIntent = Intent(this, StartPageActivity::class.java)//MainActivity::class.java)
val pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent,
PendingIntent.FLAG_IMMUTABLE)//0
val notification: Notification = NotificationCompat.Builder(this,
MyForegroundService.CHANNEL_ID
)
//.setContentTitle("前台服务")
//.setContentText("前台保活服务") // 你的应用程序在前台运行
.setSmallIcon(R.mipmap.icon_home_2_s)
.setContentIntent(pendingIntent)
.build()
startForeground(1, notification)
}
}
注意调用startForegroundService时有可能的报错
在 Android 8.0(API 26)及更高版本中,如果你调用 startForegroundService 方法启动服务,服务必须在短时间内调用 startForeground 方法来显示通知,否则系统会抛出 RemoteServiceException。
报错:
FATAL EXCEPTION: main
Process: com.my.call.callphone, PID: 3202
android.app.RemoteServiceException: Context.startForegroundService() did not then call Service.startForeground(): ServiceRecord{3336361 u0 com.mofang.call.callphone/.MyAppLaunchService}
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1970)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7386)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:980)
解决:
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
NSLog("启动4")
// 你的业务逻辑...
// 启动前台服务
startForegroundService()
// 启动应用的主活动
restartApp()
return START_STICKY
}