[Android]APP自启动

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
    }

猜你喜欢

转载自blog.csdn.net/u012881779/article/details/145770467
今日推荐