Android——锁定launch - 原生Browser启动 -引导provision

2021-05-14 AndroidR 开机向导完成标志位 当开机完成后会对标志位进行写值 packages/apps/Provision/src/com/android/DefaultActivity.java Settings.Global.putInt(getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 1); Settings.Secure.putInt(getContentResolver(), Settings.Secure.USER_SETUP_COMPLETE, 1); 对. 阅读详情

     前段时间做了一个功能,就是锁定主launch,机器上只能跑我们定义的launch,当时没注意影响,

最近发现就是因为在AMS中加了这个锁定过滤条件导致原生Browser无法启动了,

把我郁闷的,当时怎么想都觉得奇怪,这完全不相关的两件事怎么会影响到~ 这里记录一下



                                                                              撰写不易,转载请注明出处: http://blog.youkuaiyun.com/jscese/article/details/41015941



锁定主launch

    启动android系统launch的过程原理可参考Android——启动过程详解 中的HOME启动,

 这个网上的方法比较多,最常见的就是修改原生的 CATEGORY_HOME 变量或者添加一个新的变量来做筛选条件,需要修改源码中出现CATEGORY_HOME的地方.

比如我在/frameworks/base/core/java/android/content/Intent.java 中把CATEGORY_HOME 改为:

public static final String CATEGORY_HOME = "android.intent.category.JSCESE_HOME";

这样的话在源码中其它地方使用的 CATEGORY_HOME 变量都可以不动,整体编译需要使用 make update-api更新api.

然后只需要把我们想要当作launch的apk的AndroidManifest.xml文件中:

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

//改为

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

这样一来只有定义了andorid.intent.category.JSCESE_HOME 这个category的launch 才能被系统当作HOME launch启动起来!

貌似一看没有任何问题~





原生Browser启动

    像上面介绍的那样可以正常锁定住我们指定的launch,但是问题来了~,当启动Browser的时候直接就退出来了,启动其它的apk,或者使用其它的浏览器都能正常运行,

我一查发现退出原因是在BrowserActivity.java中的:

private boolean shouldIgnoreIntents() {

...

  ignore |= mKeyguardManager.inKeyguardRestrictedInputMode();   //这里为 true !代表键盘锁定 导致程序finish

return ignore;

}

最后一路跟踪调试,WindowManagerService——>PhoneWindowManager——>KeyguardViewMediator中的:

    /**
     * Given the state of the keyguard, is the input restricted?
     * Input is restricted when the keyguard is showing, or when the keyguard
     * was suppressed by an app that disabled the keyguard or we haven't been provisioned yet.
     */
    public boolean isInputRestricted() {
    	Log.d(TAG,"jscese display mShowing =="+mShowing+"  "+mNeedToReshowWhenReenabled+"  "+!mUpdateMonitor.isDeviceProvisioned());
        return mShowing || mNeedToReshowWhenReenabled || !mUpdateMonitor.isDeviceProvisioned();
    }

我发现 !mUpdateMonitor.isDeviceProvisioned()==true !

追根溯源到KeyguardUpdateMonitor.java中的:

mDeviceProvisioned = Settings.Global.getInt(
                mContext.getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 0) != 0;

问题就出在这里,这里得到的是 0 ~

我果断的到setting.db中去查了下global表中的device_provisioned:

select * from global where name='device_provisioned';

果然在db中的值为 0 ! 查询方法可参考:Android——sqlite3 基本命令操作

源码全局一搜,发现在/packages/apps/Provision/src/com/android/provision/DefaultActivity.java 中有这么一行:

 Settings.Global.putInt(getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 1);

马蛋,我瞬间明白了前因后果,我看这个DefaultActivity.java 也眼熟... 原来是漏掉了这个真正的 系统第一  apk ~





引导provision

 这个引导apk一般被很多人忽视,这次我也忽视掉了,最开始接触android的时候还知道这东西,久没接触给忘掉了~

这个apk是作为android第一引导apk的,AndroidManifest.xml中和一般的launch一样定义的:

            <intent-filter android:priority="1">
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.HOME" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>

所以其实在 AMS中的 startHomeActivityLocked 启动HOME activity的时候,这个 provision的 DefaultActivity也是被查询出来的,

而且因为优先级=1 高于 一般的launch,而被直接启动,不算作多HOME launch.

看下这个 DefaultActivity.java:

/**
 * Application that sets the provisioned bit, like SetupWizard does.
 */
public class DefaultActivity extends Activity {

    @Override
    protected void onCreate(Bundle icicle) {
        super.onCreate(icicle);

        // Add a persistent setting to allow other apps to know the device has been provisioned.
        Settings.Global.putInt(getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 1);   // 这里设置了一个状态值 ,也就是上面说到的 device_provisioned,代表升级完成,设备准备好了~

        // remove this activity from the package manager.
        PackageManager pm = getPackageManager();
        ComponentName name = new ComponentName(this, DefaultActivity.class);
        pm.setComponentEnabledSetting(name, PackageManager.COMPONENT_ENABLED_STATE_DISABLED,   //这个是直接从packagemanager中 把自己剔除,也就是说 这个activity 只启动这么一次
                PackageManager.DONT_KILL_APP);

        // terminate the activity.
        finish();
    }
}

这个引导除了设置准备完成标志,把自己屏蔽掉之外没做什么其它操作,

DEVICE_PROVISIONED:

上面有说道设置进了setting.db的global表里面,这个标志很重要,像上面就是因为键盘检测这个标志还为 0 ,导致键盘是锁定的状态,无法使用Browser,

另外还有 锁屏程序不会锁屏;对HOME key的处理也不同;电话也是打不进来的


另外从PackageManager中剔除的操作保存在 /data/system目录下的packages.xml中


另外注释上有看到 这个activity 是用来做设置向导的~所以一些第一次起机需要做的一些操作可以加在这里让其启动:

Intent intent = new Intent();
ComponentName componentName = new ComponentName("com.xxx.xxx", "com.xxx.xxx.yourAcitvity");
intent.setComponent(componentName);
startactivity(intent); 

也有直接在这里直接查询HOME的 ,然后跳转指定的 launch~


像我上面说的那种锁定launch,就是因为启动时漏掉了这个引导provision,所以无法启动Browser,而且还有其它的功能隐患!

解决办法就是把这个Provision的AndroidManifest.xml 也:

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

//改为

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





Intent隐式启动,Activity启动选择框

  当使用intent隐式启动activity时,都是通过PackageManager 查询满足条件的activity,如果有不只一项满足,那么就会弹出一个dialog,让用户选择!

上面说到的多个HOME launch状态下,想要锁定我自己的launch也是出于这个原因!

大体记录一下流程:

 一般启动一个activity时都是context.startActivity(intent)之类的,初步调用到/frameworks/base/core/java/android/app/ContextImpl.java:

    @Override
    public void startActivity(Intent intent, Bundle options) {
        warnIfCallingFromSystemProcess();
        if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
            throw new AndroidRuntimeException(
                    "Calling startActivity() from outside of an Activity "
                    + " context requires the FLAG_ACTIVITY_NEW_TASK flag."
                    + " Is this really what you want?");
        }
        mMainThread.getInstrumentation().execStartActivity(
            getOuterContext(), mMainThread.getApplicationThread(), null,
            (Activity)null, intent, -1, options);
    }

调用到同目录下的Instrumentation.java中的execStartActivity,再调用ActivityManagerNative.getDefault().startActivity(*);

很明显接下来就是调用到AMS中的startAcitivity

    public final int startActivity(IApplicationThread caller,
            Intent intent, String resolvedType, IBinder resultTo,
            String resultWho, int requestCode, int startFlags,
            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
        return startActivityAsUser(caller, intent, resolvedType, resultTo, resultWho, requestCode,
                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
    }

    public final int startActivityAsUser(IApplicationThread caller,
            Intent intent, String resolvedType, IBinder resultTo,
            String resultWho, int requestCode, int startFlags,
            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
        enforceNotIsolatedCaller("startActivity");
        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
                false, true, "startActivity", null);
        return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
                resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
                null, null, options, userId);
    }

调用到/frameworks/base/services/java/com/android/server/am/ActivityStack.java中:

final int startActivityMayWait(IApplicationThread caller, int callingUid,
            Intent intent, String resolvedType, IBinder resultTo,
            String resultWho, int requestCode, int startFlags, String profileFile,
            ParcelFileDescriptor profileFd, WaitResult outResult, Configuration config,
            Bundle options, int userId) {

...

   newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_NEW_APP,
                                aInfo.packageName);
                        newIntent.setFlags(intent.getFlags());
                        newIntent.setClassName("android",
                                HeavyWeightSwitcherActivity.class.getName());  //可以看到符合上面的一系列判定条件之后,发现如果是多个activity满足条件,在这里就先启动了一个选择activity
                        intent = newIntent;

...

   int res = startActivityLocked(caller, intent, resolvedType,
                    aInfo, resultTo, resultWho, requestCode, callingPid, callingUid,
                    startFlags, options, componentSpecified, null);

...

return res;

}

可以看下/frameworks/base/core/java/com/android/internal/app/HeavyWeightSwitcherActivity.java:

/**
 * This activity is displayed when the system attempts to start an Intent for
 * which there is more than one matching activity, allowing the user to decide
 * which to go to.  It is not normally used directly by application developers.
 */
public class HeavyWeightSwitcherActivity extends Activity {
    /** The PendingIntent of the new activity being launched. */
    public static final String KEY_INTENT = "intent";
    /** Set if the caller is requesting a result. */
    public static final String KEY_HAS_RESULT = "has_result";
    /** Package of current heavy-weight app. */
    public static final String KEY_CUR_APP = "cur_app";
    /** Task that current heavy-weight activity is running in. */
    public static final String KEY_CUR_TASK = "cur_task";
    /** Package of newly requested heavy-weight app. */
    public static final String KEY_NEW_APP = "new_app";
    


注释写的很明白~





Android开机向导setupwizard,设置系统语言,WiFi向导 Android的框架设计有考虑到开机向导这一场景,因此我们实现开机向导参考Android的Provision.apk Provision: MSM8976/repo/packages/apps/Provision 它的主要作用是作为开机引导用户进行一些基本设置.在原生的 android 系统中,provision非常的简单,只有一个空白的 activity,这个主要就是留给 厂商自己定制开机向 阅读详情

相关推荐

Autodesk激活无无网络选项?许可类型与脱机激活排查修复指南

软件许可激活是保障正版授权正常使用的核心环节,常见的授权模式包括单机版许可和网络版许可,两者在认证机制和应用场景上有所区别。单机版离线授权依托 FlexNet Licensing Service 等底层服务组件,在断网或内网环境下为用户提供可靠的技术支持与授权验证路径。然而在实际部署中,激活窗口并不总是显示“无网络激活方式”入口,这可能与许可类型选择、网络环境干扰、组件安装残留或系统时间偏差有关。理解入口的动态呈现逻辑与排查顺序,有助于在 AutoCAD、Revit 等 Autodesk 产品中高效解决脱机

weixin_28709649的博客 355

关于Android P Auto锁屏Global.DEVICE_PROVISIONED

在Android P的Auto版本中,多用户会根据Global.DEVICE_PROVISIONED的值选择一个导航栏的锁屏画面。 官网解释: https://developer.android.com/reference/android/provider/Settings.Global#DEVICE_PROVISIONED DEVICE_PROVISIONED Added in API leve...

Sunxiaolin2016的博客 4857

Camera(5)metadata

Metadata 是整个 Android camera 中类似于高楼大厦中的管道系统一样,贯穿了整个 Camera 的 Framework 和 vendor HAL。Metadata 里面包含了所有的控制、参数、返回值等等。Metadata分为Android原生的Metadata和芯片商或者用户自定义的Metadata,即Android Tag和Vendor Tag。Vendor Tag在Hal中定义,并在camx和chi目录中使用。

qq_55893245的博客 3052

Android Provision(开机向导setupwizard程序)

但是在原生的 android 系统中,这个 provision 非常的简单,只有一个空白的 activity,这个主要就是留给 厂商自己定制的(像 google 的 nexus 进行让里你登陆 google 帐号,连接WiFi等等一些功能)。之所以会关注DEVICE_PROVISIONED这个标记,是因为当用户操作完的App 的时候我设置了这个标记,等其他逻辑,导致外部程序进入的时候黑屏,为了排查原因,所以就从这入手了。这个组件只会运行一次,所以我们如果没有格式化/data目录,这个组件就会被禁止。

Venus 的博客 2867

STM32 IIC电量计LTC2944

LTC2944是一款电池电量计,设计用于端电压为3.6V至60V的多节电池。它测量电池充电和放电、电池电压、电流和自身温度。精密模拟库仑计数器通过电池正极端子与负载或充电器之间的检测电阻器对电流进行积分。电池电压、电池电流和硅温度由内部ADC测量。

baidu_34971492的博客 3161

【Prometheus】prometheus结合cAdvisor监控docker容器运行状态,并且实现实时告警通知

Docker的监控,可以使用Docker自带的stats命令来获取当前主机上运行中的容器的资源使用情况。 例如:容器的CPU使用率、内存占用、网络IO以及磁盘IO等指标。

景天科技苑 6万+

Google APK ANR 解决方案

极力推荐文章:欢迎收藏Android 干货分享阅读五分钟,每日十点,和您一起终身学习,这里是程序员Android本篇文章主要介绍Android开发中的部分GMS...

程序员Android 918

Openclaw错误分析与解决方案之:All models are temporarily rate-limited. Please try again in a few minutes

Openclaw错误分析与解决方案之: All models are temporarily rate-limited. Please try again in a few minutes.

多媒体编程、网络编程、系统编程、网络安全编程、驱动编程 1619

android 默认打开数据网络设置,android系统开机向导无法启动数据进行上网

由于android系统开机向导界面比较特殊,会通过Settings.Global.DEVICE_PROVISIONED 属性来控制,刷完机第一次启启动此值会默认为0 ,开机向导结束后会设置为1,系统很多地方会根据此值来控制opt/telephony/src/java/com/android/internal/telephony/dataconnection/DcTracker.javaopt/te...

weixin_39612038的博客 1330

独家改进|基于YOLO26的轻量级检测网络:参数量减半,精度不降反升

不要全层替换深度可分离卷积:P5深层对语义特征要求高,用标准卷积效果更好,只在P2、P3浅层用DWConv性价比最高注意力不是越多越好:每个阶段加一个就够,加在模块输出端,不要插在模块中间,否则部署容易出现算子不兼容问题轻量模型训练别贪快:初始学习率一定要调低,不然很容易前期震荡,后期收敛不上,精度卡在瓶颈小目标场景优先保留P2分支:如果对速度要求不是极致,保留P2检测头,小目标收益远大于速度损失。

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 220

倍福CX9020(WINCE 7)控制器使用方法和操作

CX9020系列是倍福控制器中较为经济的,操作系统为Windows Embedded Compact 7(简称WINCE7或WINEC7),相对高端控制器(WINES7以上系统),操作系统古老而简洁,上位机软件的编写困难很多,本文是笔者在使用过程中摸索的流程,旨在为CX9020系列的新用户提供参考,也可供其他CE系统的控制器参考。本文中大部分截图采用倍福中国的培训文档,这是由于笔者是在流程走通后再写这篇文章,不想再恢复出厂设置走一遍截图。因笔者在写这篇文章时使用倍福控制器经验并不丰富,难免有纰漏,请读者批评

weixin_41883890的博客 4287

android provision

今天说说Provision这个APK,可能很多朋友都不知道有这个APK存在。Provision的作用很简单,就是一个系统初始化引导程序,原生的Android里面Provision只做了一件事,就是写入一个DEVICE_PROVISIONED标记。不过这个标记作用很大,这个标记只会在系统全新升级(双清)的时候写入一次,代表了Android系统升级准备完成,可以正常工作。   之所以会关注DEVIC

shenmay2012的专栏 1万+

PCIe-Orders set Blocks之symbol对齐

有序集的使用场合很多,如在链路link阶段,进入polling后,便开始有序集的发送。一个 Ordered Set Block 包含一个同步头,后跟一个有序集。多通道链路的所有 Lane 必须同时传输相同的有序集,而且有序集的第一个符号定义了有序集的类型。但在PCIE中,8GT/s及以上的速率,采用的是128b/130b编码。128-bit是想要传输的payload,实际会传输130-bit,多出来的2-bit就是sync header。Block有两种,通过Sync header区分:10b:表示data

weixin_44700185的博客 813

Android中Device Provisioned引起的问题分析

下载正式版本软件,第一次开机做完SetupWizard之后无法锁屏,HOME键和MENU键无效,重启后恢复正常。

宋金时的专栏 6817

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

Android系统中默认值的意义列表

系统中默认值的意义列表 序号 default.xml中名称 类型 settings数据库列名 意义 1 def_dim_screen bool dim_screen 是否自动关屏,默认true 2 def_screen_off_timeout integer sc

yayax的专栏 4453

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

Android settings

setting数据库主要使用 SettingsProvider+DatabaseHelper 实现,类似的实现还有 通讯录、通话记录frameworks\base\packages\SettingsProvider\src\com\android\providers\settings\SettingsProvider.javaframeworks\base\packages\SettingsProvider\src\com\android\providers\settings\DatabaseHelper.

xiaowang_lj的博客 5265

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

安卓源码学习之【开机向导定制 OOBE/Provision源码分析】

是 “”(开箱体验)的缩写。它指的是用户在首次使用 Android 设备时所经历的初始设置过程。Provision 在 Android 系统中是一个关键的,主要用于设备首次启动或系统升级后执行基础配置,确保设备进入可用状态,引导用户进入初始化的操作,就是开机向导。Provision就是谷歌为我们设计的一个 OOBE 示例,Provision其中 DefaultActivity 就是引导页的默认 Activity:将该 Activity 排除在最近任务列表(Recent Tasks)之外。

WriteBug001的博客 2354

Android 自定义开机引导最强篇 provision

设置相关标记位可以让其他服务知道设备可用,如锁屏服务可用,启用Home键功能等,将该Activity禁用可以让下次开机时我们的应用不会再起来而直接启动桌面,finish就不用做解释,开机引导走完了就该销毁自己了。属性的Launcher,在Pixel手机上,作为开机向导的应用是Google的。应用,这是谷歌的应用,代码不在AOSP中,在AOSP中有一个包名为。的代码移到自己的项目,走完我们自己的引导流程后设置相关属性,然后把。具体代码实现,让自己的应用比Launcher先起来的方式,

Venus 的博客 4151

Settings属性读写

Settings系统属性存储均为xml,分三种:global,system,secure

xianrenli38的博客 1797

《深入理解Android 卷III》第七章 深入理解SystemUI(完整版)

第7章 深入理解SystemUI 本章主要内容: ·探讨状态栏与导航栏的启动过程 ·介绍状态栏中的通知信息、系统状态图标等信息的管理与显示原理 ·介绍导航栏中的虚拟按键、SearchPanel的工作原理 ·介绍SystemUIVisibility 本章涉及的源代码文件名及位置: ·SystemServer....

xzc的博客 3555

进入设置--关于手机-点击版本号,发现无反应,不能进入开发者模式

ATO版本上存在该问题,非ATO版本正常。 在Settings/src/com/android/settings/deviceinfo/BuildNumberPreferenceController.java下打印log,发现: @Override public boolean handlePreferenceTreeClick(Preference preferenc...

IceSea7 6764

Android判断用户是否已完成设置向导(开机向导)

Android判断用户是否已完成设置向导(开机向导) inline val Context.isDeviceProvisioned: Boolean get() = Settings.Global.getInt(contentResolver, Settings.Global.DEVICE_PROVISIONED, 0) == 1

C_biubiubiu的博客 2241

Android11 provision引导程序私有权限配置

LOCAL_REQUIRED_MODULES := privapp_whitelist_com.xxx.provision 引用配置的私有权限。现象:自己开发的provision设置 “user_setup_complete”不生效。1、使用Android studio 开发自己的provision.apk。目录:frameworks\base\data\etc。2、配置应用程序权限,参考系统provision权限配置。在同目录下的Android.bp文件中配置。2、Android.mk文件。

qq_16815415的博客 1105

[问题记录] Android裁剪Provision应用后无法打开开发者选项

最近在做RK平台的内置应用裁剪,按照需求最终决定了裁剪列表,大概减少了系统img包100M的体积。在后面几天的测试开发中,发现了一个问题:从原生设置中打开关于,点击版本号,无法打开开发者模式了。

tahliaL 929

Android仿系统provision应用实现开机向导

背景:TV首次开机实现遥控对焦、连接wifi等指导性功能应用需要的功能 :1.设置相关属性让自己早于Launcher起来;2.设置开机引导已经走完的标记位。

qq_44203816的博客 927

Android无法打开开发者模式

Android10的系统,一台设备无法通过点击设备版本打开开发者模式,通过正常设备点击时的文案"You are now a developer!这个函数很长,分析源码可以发现有很多条件可以触发函数返回,针对我的情况,通过debug发现是Utils.isDeviceProvisioned(mContext)没有满足,跟进去可以看到时一个设置项被改变了。因为拆设备通过usb线连接了设备,并且设备可以识别出来,所以可以直接通过adb 命令修改此参数。如果连接不上usb线,可以写一个APP通过代码修改此设置。

dfqin的专栏 1899
上一篇: Android——4.2.2 文件系统目录分析
下一篇: Android——4.2 - 3G移植之路之 AT 通信 (四)
南丶烟
博客等级 码龄14年 569粉丝 98原创
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值