主页 > 软件开发  > 

Lineageos22.1(Android15)开机向导制作

Lineageos22.1(Android15)开机向导制作
一、前言

开机向导原理其实就是将特定的category的Activity加入ComponentResolver,如下

<category android:name="android.intent.category.SETUP_WIZARD"/>

然后我们开机启动的时候,FallbackHome结束,然后启动Launcher的时候,就会找到对应的开机向导Activity页面。所以我们现定制我们自己的应用。

二、定制MyApp

1.清单文件,定义好权限和Launcer相关的category

<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android /apk/res/android" xmlns:tools="http://schemas.android /tools"> <uses-permission android:name="android.permission.WRITE_SETTINGS" tools:ignore="ProtectedPermissions" /> <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" tools:ignore="ProtectedPermissions" /> <application android:allowBackup="true" android:dataExtractionRules="@xml/data_extraction_rules" android:fullBackupContent="@xml/backup_rules" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.MyProvision2" tools:targetApi="31"> <activity android:name=".MainActivity" android:exported="true" android:label="@string/app_name" android:theme="@style/Theme.MyProvision2"> <intent-filter android:priority="2"> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.HOME"/> <category android:name="android.intent.category.DEFAULT"/> <category android:name="android.intent.category.SETUP_WIZARD"/> </intent-filter> </activity> </application> </manifest>

2.MainActivity,简单一个页面,点击之后完成配置

package com.example.myprovision2 import android.content.ComponentName import android.content.pm.PackageManager import android.os.Bundle import android.provider.Settings import androidx.activity.ComponentActivity import androidx.activity pose.setContent import androidx.activity.enableEdgeToEdge import androidx pose.foundation.Image import androidx pose.foundation.clickable import androidx pose.foundation.layout.Box import androidx pose.foundation.layout.fillMaxSize import androidx pose.foundation.layout.padding import androidx pose.material3.OutlinedButton import androidx pose.material3.Scaffold import androidx pose.material3.Text import androidx pose.runtime.Composable import androidx pose.ui.Alignment import androidx pose.ui.Modifier import androidx pose.ui.layout.ContentScale import androidx pose.ui.res.painterResource import androidx pose.ui.tooling.preview.Preview import com.example.myprovision2.ui.theme.MyProvision2Theme class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) enableEdgeToEdge() setContent { MyProvision2Theme { Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding -> Greeting( name = "Android", modifier = Modifier.padding(innerPadding) ) Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) { Image(modifier=Modifier.fillMaxSize(),painter = painterResource(R.drawable.pic), contentScale = ContentScale.FillBounds, contentDescription = "") OutlinedButton(onClick = { finishSetup() }) { Text(text = "FINISH SET UP", ) } } } } } } private fun finishSetup() { setProvisioningState() disableSelfAndFinish() } private fun disableSelfAndFinish() { // remove this activity from the package manager. val pm = packageManager val name: ComponentName = ComponentName(this, MainActivity::class.java) pm.setComponentEnabledSetting( name, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP ) // terminate the activity. finish() } private fun setProvisioningState() { // Settings // Log.i(TAG, "Setting provisioning state") // Add a persistent setting to allow other apps to know the device has been provisioned. Settings.Global.putInt(contentResolver, Settings.Global.DEVICE_PROVISIONED, 1) Settings.Secure.putInt(contentResolver, Settings.Secure.USER_SETUP_COMPLETE, 1) } } @Composable fun Greeting(name: String, modifier: Modifier = Modifier) { Text( text = "Hello $name!", modifier = modifier ) } @Preview(showBackground = true) @Composable fun GreetingPreview() { MyProvision2Theme { Greeting("Android") } }

3.这里有特殊的权限,需要在system/etc/permissions内配置,我们准备一下权限的xml com.example.myprovision2.xml

<?xml version="1.0" encoding="utf-8"?> <!-- ~ Copyright (C) 2019 The Android Open Source Project ~ ~ Licensed under the Apache License, Version 2.0 (the "License"); ~ you may not use this file except in compliance with the License. ~ You may obtain a copy of the License at ~ ~ http:// .apache.org/licenses/LICENSE-2.0 ~ ~ Unless required by applicable law or agreed to in writing, software ~ distributed under the License is distributed on an "AS IS" BASIS, ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ~ See the License for the specific language governing permissions and ~ limitations under the License --> <permissions> <privapp-permissions package="com.example.myprovision2"> <permission name="android.permission.WRITE_SECURE_SETTINGS"/> </privapp-permissions> </permissions>

4.修改Android.bp

android_app_import { name: "MyApp", // this needs to be a privileged application privileged: true, // Make sure the build system doesn't try to resign the APK dex_preopt: { enabled: false, }, arch: { arm: { apk: "MyApp.apk", }, arm64: { apk: "MyApp.apk", }, x86: { apk: "MyApp.apk", }, x86_64: { apk: "MyApp.apk", }, }, certificate: "platform", required: [ "MyAppPermissions" ], } // 定义 XML 文件复制规则 prebuilt_etc { name: "MyAppPermissions", // 模块唯一标识 src: "com.example.myprovision2.xml", // 源文件路径(相对于当前 Android.bp ) sub_dir: "permissions", // 指定 system/etc 下的子目录 filename: "com.example.myprovision2.xml", // 目标文件名(可重命名) }

完成之后我们make MyApp就会自动复制权限xml到对应目录下。

三、验证

我们push apk和xml到对应目录下之后,然后重启设备。这里重启之前还需要重置一下变量

adb shell settings put secure user_setup_complete 0

这样解锁有就可以正常启动我们自定义的开机向导了。

标签:

Lineageos22.1(Android15)开机向导制作由讯客互联软件开发栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“Lineageos22.1(Android15)开机向导制作