基于迅为RK3568开发板全国产平台,快速实现APP开机自启动技术分享
应用场景:
在一些场景中需要系统启动以后就让应用程序运行起来,如闸机打卡系统,智能点餐系统,广告机系统等等。这个需求叫做自启动。
除全国产版本核心板以外,RK3568 核心板还有工业级,商业级,连接器和邮票孔多种版本。全国产版本核心板与其他版本核心板完全兼容。可以支持国产和非国产核心板的无缝切换,助力产品升级和国产化项目落地。
RK3568 Android11实现APP 自启动技术分享
平台:迅为iTOP-3568 开发板
■ 第一步:添加自启服务
修改RK3568 Android11 源码frameworks\base\core\java\com\android\internal\app\ResolverActivity.java 文件,添加如下蓝色字体的代码。
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.Executor;
import java.util.function.Consumer;
import android.os.SystemProperties;
import android.app.role.RoleManager;
/**
* This activity is displayed when the system attempts to start an Intent for
@@ -341,6 +345,18 @@ public class ResolverActivity extends Activity implements
protected void onCreate(Bundle savedInstanceState, Intent intent,
CharSequence title, int defaultTitleRes, Intent[] initialIntents,
List<ResolveInfo> rList, boolean supportsAlwaysUseOption) {
String LauncherPkg = SystemProperties.get("persist.sys.def_launherpag");
if(LauncherPkg!=null/* && !isDefaultLauncher(this,LauncherPkg)*/){
Log.v("defaultLauncher","-----found default launcher pkg:"+LauncherPkg);
setDefaltLauncher(this,LauncherPkg);
startDefaultLauncher(this,LauncherPkg);
finish();
return;
}
setTheme(appliedThemeResId());
super.onCreate(savedInstanceState);
@@ -433,6 +449,47 @@ public class ResolverActivity extends Activity implements
intent.getAction()+ ":" + intent.getType() + ":"
+ (categories != null ? Arrays.toString(categories.toArray()) : ""));
}
public void setDefaltLauncher(Context context, String packageName) {
String roleName = "android.app.role.HOME";
boolean add = true;
int flags = 0;
UserHandle user = android.os.Process.myUserHandle();
RoleManager roleManager = context.getSystemService(RoleManager.class);
Executor executor = context.getMainExecutor();
Consumer< Boolean > callback = successful -> {
if (successful) {
Log.v("defaultLauncher","set Defalt Launcher successful");
} else {
Log.v("defaultLauncher","set Defalt Launcher failed");
}
};
roleManager.addRoleHolderAsUser(roleName, packageName, flags, user, executor, callback);
}
public void startDefaultLauncher(Context context, String packageName) {
Intent intent = new Intent();
PackageManager pm = context.getPackageManager();
intent = pm.getLaunchIntentForPackage(packageName);
if (intent != null)
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
try {
context.startActivity(intent);
} catch (Exception e) {
Log.v("defaultLauncher","start Default Launcher failed,not find package:"+packageName);
}
}
public boolean isDefaultLauncher(Context context,String launcherPkg){
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
ResolveInfo resolveInfo = context.getPackageManager().resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);
String currentHomePackage = resolveInfo.activityInfo.packageName;
Log.v("defaultLauncher","-currentHomePackage:"+currentHomePackage);
return launcherPkg.equals(currentHomePackage);
}
private boolean isIntentPicker() {
return getClass().equals(ResolverActivity.class);
■ 第二步:添加 APP
接下来将需要自启动的APP 放到 device/rockchip/rk356x/rk3568_r/preinstall_del/ 目录下,如果没有 preinstall_del 目录的话需要手动新建一个 preinstall_del 目录即可,然后添加以下文件 Android.mk,xxx.apk(APP),preinstall.mk 这三个文件。
Android.mk 文件内容如下所示:
include $(call all-subdir-makefiles)
preinstall.mk 文件内容:
PRODUCT_PACKAGES += xxx
xxx 为 APP 名字,例如 demo.apk。这份目录不仅是APK 的预装指定位置,当您希望新增 APK 进行预装时,可将该 APK 文件复制至“preinstall_del/”目录下,并随后将 APK 的名称增补至“preinstall.mk”配置文件中,以完成预安装的准备工作。这样的操作确保了 APK 能够按照预期被系统识别并预装至目标设备中。
■ 第三步:添加APP 包名
修改RK3568Android11 源码文件 device/rockchip/rk356x/rk3568_r/rk3568_r.mk, 例如包名为:com.example.demo,在 rk3568_r.mk 中下面蓝色字体代码。
PRODUCT_PROPERTY_OVERRIDES += persist.sys.timezone=Asia/Shanghai
PRODUCT_PROPERTY_OVERRIDES += ro.vendor.hdmirotationlock=true
#PRODUCT_PROPERTY_OVERRIDES += vendor.hwc.device.primary=HDMI-A-1
PRODUCT_PROPERTY_OVERRIDES += vendor.hwc.device.primary=DSI
PRODUCT_PROPERTY_OVERRIDES += persist.sys.def_launherpag=com.example.demo
修改完毕之后,保存修改的文件,重新编译Android 源码,然后烧写 Android 镜像进行测试。