【干货】Android系统定制基础篇:第二部分(Launcher3支持键盘切换焦点、开发者模式密码确认、禁止非预装应用安装、配置时间)

news2024/11/24 2:16:07

1、Android Launcher3支持键盘切换焦点

Android Launcher3 默认并不支持键盘操作,无法切换焦点,在一些需要支持键盘或遥控操作的设备中无法使用,因些对 Launcher3 做简单修改,使其支持键盘切换焦点。

diff --git a/packages/apps/Launcher3/res/layout/all_apps.xml b/packages/apps/Launcher3/res/layout/all_apps.xml
old mode 100644
new mode 100755
diff --git a/packages/apps/Launcher3/res/layout/all_apps_icon.xml b/packages/apps/Launcher3/res/layout/all_apps_ic
index 3c2f842..1c22ec3 100755
--- a/packages/apps/Launcher3/res/layout/all_apps_icon.xml
+++ b/packages/apps/Launcher3/res/layout/all_apps_icon.xml
@@ -24,5 +24,7 @@
     launcher:iconDisplay="all_apps"
     launcher:centerVertically="true"
     android:paddingLeft="@dimen/dynamic_grid_cell_padding_x"
-    android:paddingRight="@dimen/dynamic_grid_cell_padding_x" />
+    android:paddingRight="@dimen/dynamic_grid_cell_padding_x"
+    android:focusable="true"
+    android:focusableInTouchMode="false" />
 
diff --git a/packages/apps/Launcher3/res/layout/page_indicator.xml b/packages/apps/Launcher3/res/layout/page_indic
old mode 100644
new mode 100755
diff --git a/packages/apps/Launcher3/res/layout/search_container_workspace.xml b/packages/apps/Launcher3/res/layou
old mode 100644
new mode 100755
index 1c617b1..161431f
--- a/packages/apps/Launcher3/res/layout/search_container_workspace.xml
+++ b/packages/apps/Launcher3/res/layout/search_container_workspace.xml
@@ -22,9 +22,11 @@
         android:id="@id/search_container_workspace"
         android:padding="0dp" >
 
-    <fragment
-        android:name="com.android.launcher3.qsb.QsbContainerView$QsbFragment"
-        android:layout_width="match_parent"
-        android:tag="qsb_view"
-        android:layout_height="match_parent"/>
+    <!--Modified by shenhb@topband.com.cn,remove search box.-->
+    <!--<fragment-->
+        <!--android:name="com.android.launcher3.qsb.QsbContainerView$QsbFragment"-->
+        <!--android:layout_width="match_parent"-->
+        <!--android:tag="qsb_view"-->
+        <!--android:layout_height="match_parent"/>-->
+    <!--End of modify-->
 </com.android.launcher3.qsb.QsbContainerView>
\ No newline at end of file
diff --git a/packages/apps/Launcher3/src/com/android/launcher3/Workspace.java b/packages/apps/Launcher3/src/com/an
old mode 100644
new mode 100755
index 6ce3ad6..8a03091
--- a/packages/apps/Launcher3/src/com/android/launcher3/Workspace.java
+++ b/packages/apps/Launcher3/src/com/android/launcher3/Workspace.java
@@ -606,11 +606,13 @@ public class Workspace extends PagedView
                     .inflate(R.layout.search_container_workspace,firstPage, false);
         }
 
+        /* Modified by shenhb@topband.com.cn,remove search box.
         CellLayout.LayoutParams lp = new CellLayout.LayoutParams(0, 0, firstPage.getCountX(), 1);
         lp.canReorder = false;
         if (!firstPage.addViewToCellLayout(qsb, 0, R.id.search_container_workspace, lp, true)) {
             Log.e(TAG, "Failed to add to item at (0, 0) to CellLayout");
         }
+        End of Modify */
     }
 
     public void removeAllWorkspaceScreens() {
diff --git a/packages/apps/Launcher3/src/com/android/launcher3/config/BaseFlags.java b/packages/apps/Launcher3/src
old mode 100644
new mode 100755
index 6a4cbcb..5bc4df8
--- a/packages/apps/Launcher3/src/com/android/launcher3/config/BaseFlags.java
+++ b/packages/apps/Launcher3/src/com/android/launcher3/config/BaseFlags.java
@@ -51,7 +51,7 @@ abstract class BaseFlags {
     // Feature flag to enable moving the QSB on the 0th screen of the workspace.
     public static final boolean QSB_ON_FIRST_SCREEN = true;
     // When enabled the all-apps icon is not added to the hotseat.
-    public static final boolean NO_ALL_APPS_ICON = true;
+    public static final boolean NO_ALL_APPS_ICON = false;
     // When enabled fling down gesture on the first workspace triggers search.
     public static final boolean PULLDOWN_SEARCH = false;
     // When enabled the status bar may show dark icons based on the top of the wallpaper.

2、Android打开开发者模式需要密码确认

在安全性要求比较高的产品中,一般会默认关闭『adb调试』,同时禁止用户打开『adb调试』功能。在Android8.1中默认禁止『adb调试』只需要将下面属性:

persist.sys.usb.config=mtp,adb

改为:

persist.sys.usb.config=mtp

Android默认通过连续点击『版本号』可以打开『开发者选项』,在『开发者选项』中可以打开『adb调试』,所以要禁止用户打开『adb调试』功能,我们在用户点击『版本号』时弹出管理员密码对话框,只有输入正确的管理员密码才可以打开『开发者选项』。修改如下:

diff --git a/packages/apps/Settings/src/com/android/settings/deviceinfo/BuildNumberPreferenceController.java b/pac
index 7a00163..d9b41a4 100755
--- a/packages/apps/Settings/src/com/android/settings/deviceinfo/BuildNumberPreferenceController.java
+++ b/packages/apps/Settings/src/com/android/settings/deviceinfo/BuildNumberPreferenceController.java
@@ -18,17 +18,22 @@ package com.android.settings.deviceinfo;
 
 import android.app.Activity;
 import android.app.Fragment;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.DialogInterface;
 import android.content.Context;
 import android.content.Intent;
 import android.os.Build;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.os.SystemProperties;
 import android.support.v7.preference.Preference;
 import android.support.v7.preference.PreferenceScreen;
 import android.text.BidiFormatter;
 import android.text.TextUtils;
 import android.util.Pair;
 import android.widget.Toast;
+import android.widget.EditText;
 
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settings.R;
@@ -63,6 +68,9 @@ public class BuildNumberPreferenceController extends AbstractPreferenceControlle
     private boolean mDebuggingFeaturesDisallowedBySystem;
     private int mDevHitCountdown;
     private boolean mProcessingLastDevHit;
+    
+    private boolean isAuthenticated = false;
+    private Dialog mPasswordDialog;
 
     public BuildNumberPreferenceController(Context context, Activity activity, Fragment fragment,
             Lifecycle lifecycle) {
@@ -114,7 +122,34 @@ public class BuildNumberPreferenceController extends AbstractPreferenceControlle
 
     @Override
     public boolean handlePreferenceTreeClick(Preference preference) {
-        /*
+        final String password = SystemProperties.get("ro.topband.password", "");
+        if (!isAuthenticated && !TextUtils.isEmpty(password) 
+            && (mPasswordDialog == null || !mPasswordDialog.isShowing())) {
+            EditText editText = new EditText(mContext);
+            mPasswordDialog = new AlertDialog.Builder(mContext)
+                .setTitle(R.string.password_dialog_title)
+                .setView(editText)
+                .setPositiveButton(R.string.dialog_ok, new DialogInterface.OnClickListener() {
+                    @Override
+                    public void onClick(DialogInterface dialog, int which) {
+                        String text = editText.getText().toString();
+                        if (TextUtils.equals(text, password)) {
+                            isAuthenticated = true;
+                        } else {
+                            Toast.makeText(mContext, R.string.password_error, Toast.LENGTH_SHORT).show();
+                        }
+                    }
+                })
+                .setNegativeButton(R.string.dialog_cancel, new DialogInterface.OnClickListener() {
+                    @Override
+                    public void onClick(DialogInterface dialog, int i) {
+                        dialog.dismiss();
+                    }
+                }).create();
+            mPasswordDialog.show();
+            return false;
+        }
+
         if (!TextUtils.equals(preference.getKey(), KEY_BUILD_NUMBER)) {
             return false;
         }
@@ -191,7 +226,6 @@ public class BuildNumberPreferenceController extends AbstractPreferenceControlle
                     Pair.create(MetricsEvent.FIELD_SETTINGS_BUILD_NUMBER_DEVELOPER_MODE_ENABLED,
                             1));
         }
-        */
         return true;
     }

弹窗预览:
在这里插入图片描述密码通过下面属性配置:

ro.topband.password=123456

3、Android禁止非预装应用安装

禁止非预装应用安装,应用安装时提取文件包名,判断系统是否有预装此应用,如果没有预装则结束安装流程。此方案修改 PackageInstaller,不影响adb安装应用。

合入下面修改前请先合入 Android静默安装 这次修改,因为两者共用了从provider Uri中提取文件路径的方法。

diff --git a/packages/apps/PackageInstaller/src/com/android/packageinstaller/InstallStart.java b/packages/apps/Pac
index cbf8c41..2edf99b 100755
--- a/packages/apps/PackageInstaller/src/com/android/packageinstaller/InstallStart.java
+++ b/packages/apps/PackageInstaller/src/com/android/packageinstaller/InstallStart.java
@@ -116,6 +116,15 @@ public class InstallStart extends Activity {
             }
         }
 
+        if (TextUtils.equals(SystemProperties.get("ro.unallow_install", "0"), "1")) {
+            if (!isPreInstallApp(path)) {
+                Log.w(LOG_TAG, "The app is not allowed to be installed without pre-installed.");
+                setResult(RESULT_CANCELED);
+                finish();
+                return;
+            }
+        }
+
         if (isSilentInstall(intent, path)) {
             Log.i(LOG_TAG, "silent install path: " + path);
             getPackageManager().installPackage(Uri.fromFile(new File(path)),
@@ -369,4 +378,29 @@ public class InstallStart extends Activity {
             Log.i(LOG_TAG, packageName + " silent installed.");
         }
     }
+
+    private boolean isPreInstallApp(String path) {
+        Log.i(LOG_TAG, "isPreInstallApp, path=" + path);
+
+        PackageInfo pi = null;
+        if (!TextUtils.isEmpty(path)) {
+            File sourceFile = new File(path);
+            PackageParser.Package parsed = PackageUtil.getPackageInfo(this, sourceFile);
+            if (parsed != null) {
+                PackageInfo pkgInfo = PackageParser.generatePackageInfo(parsed, null,
+                        PackageManager.GET_PERMISSIONS, 0, 0, null,
+                        new PackageUserState());
+                if (pkgInfo != null) {
+                    try {
+                        PackageManager pm = getApplicationContext().getPackageManager();
+                        pi = pm.getPackageInfo(pkgInfo.packageName, 0);
+                    } catch (Exception e) {
+                        Log.w(LOG_TAG, "isPreInstallAPp, error: " + e.getMessage());
+                    }
+                }
+            }
+        }
+
+        return (pi != null);
+    }
 }

属性:

# 禁止非预装应用安装,0:允许,1:禁止
ro.unallow_install=1

4、Android配置初始时间

Android默认初始时间是1970年,首次开机后通过网络同步时间。有时候我们期望默认时间为最近时间,因此通过下面修改来定制通过属性『ro.earliest_time』配置Android初始时间。

diff --git a/frameworks/base/services/java/com/android/server/SystemServer.java b/frameworks/base/services/java/co
index a7bc916..a96f881 100755
--- a/frameworks/base/services/java/com/android/server/SystemServer.java
+++ b/frameworks/base/services/java/com/android/server/SystemServer.java
@@ -50,6 +50,7 @@ import android.util.DisplayMetrics;
 import android.util.EventLog;
 import android.util.Slog;
 import android.view.WindowManager;
+import android.text.TextUtils;
 
 import com.android.internal.R;
 import com.android.internal.app.NightDisplayController;
@@ -145,7 +146,7 @@ public final class SystemServer {
 
     // The earliest supported time.  We pick one day into 1970, to
     // give any timezone code room without going into negative time.
-    private static final long EARLIEST_SUPPORTED_TIME = 86400 * 1000;
+    private static final long EARLIEST_SUPPORTED_TIME = 1577836800L * 1000; //2020-01-01 08:00:00 // 86400 * 1000
 
     /*
      * Implementation class names. TODO: Move them to a codegen class or load
@@ -280,14 +281,6 @@ public final class SystemServer {
     private void run() {
         try {
             traceBeginAndSlog("InitBeforeStartServices");
-            // If a device's clock is before 1970 (before 0), a lot of
-            // APIs crash dealing with negative numbers, notably
-            // java.io.File#setLastModified, so instead we fake it and
-            // hope that time from cell towers or NTP fixes it shortly.
-            if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
-                Slog.w(TAG, "System clock is before 1970; setting to 1970.");
-                SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
-            }
 
             //
             // Default the timezone property to GMT if not set.
@@ -393,6 +386,23 @@ public final class SystemServer {
             startCoreServices();
             startOtherServices();
             SystemServerInitThreadPool.shutdown();
+            
+            // Modify by ayst.shen@foxmail.com, for configure the initial time.
+            // If a device's clock is before 1970 (before 0), a lot of
+            // APIs crash dealing with negative numbers, notably
+            // java.io.File#setLastModified, so instead we fake it and
+            // hope that time from cell towers or NTP fixes it shortly.
+            long earliestTime = EARLIEST_SUPPORTED_TIME;
+            String earliestTimeStr = SystemProperties.get("ro.earliest_time", "");
+            if (!TextUtils.isEmpty(earliestTimeStr)) {
+                earliestTime = Long.parseLong(earliestTimeStr);
+            }
+            Slog.i(TAG, "Earliest supported time: " + earliestTime);
+            if (System.currentTimeMillis() < earliestTime) {
+                Slog.w(TAG, "System clock is before 1970; setting to 1970.");
+                SystemClock.setCurrentTimeMillis(earliestTime);
+            }
+            // Modify the end
         } catch (Throwable ex) {
             Slog.e("System", "******************************************");
             Slog.e("System", "************ Failure starting system services", ex);

配置属性
通过 在线时间戳转换 工具将目标日期转为时间戳,比如日期:2020-01-01 08:00:00,转换为时间戳:1577836800000。

# 2020-01-01 08:00:00
ro.earliest_time=1577836800000

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/667502.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

在字节跳动做了5年软件测试,无情被辞,想给划水的兄弟提个醒

先简单交代一下背景吧&#xff0c;某不知名 985 的本硕&#xff0c;17 年毕业加入字节&#xff0c;以“人员优化”的名义无情被裁员&#xff0c;之后跳槽到了有赞&#xff0c;一直从事软件测试的工作。之前没有实习经历&#xff0c;算是5年的工作经验吧。 这5年之间完成了一次…

JS-快速入门

目录 变量原生数据类型模板字符串字符串的内置属性、方法数组数组创建方式数组值操作获取值添加值删除值判断是否是数组获取值的索引 对象创建对象&#xff0c;为对象创建新属性对象值存到同名常(变)量中 对象数组和JSON创建对象数组对象数组取值对象数组转JSON数据 if条件语句…

ELK技术堆栈(yum安装部署)

ELK技术堆栈&#xff08;yum安装部署&#xff09; 目录 ELK技术堆栈可以应用于各种场景 ELK的工作原理如下&#xff1a; 它由三个核心组件组成&#xff1a; 部署步骤&#xff1a;&#xff08;单台部署&#xff09; 环境部署&#xff1a; 安装JAVA环境&#xff1a;&#…

数据库系统概述——第十章 数据库恢复技术(知识点复习+练习题)

&#x1f31f;博主&#xff1a;命运之光 &#x1f984;专栏&#xff1a;离散数学考前复习&#xff08;知识点题&#xff09; &#x1f353;专栏&#xff1a;概率论期末速成&#xff08;一套卷&#xff09; &#x1f433;专栏&#xff1a;数字电路考前复习 &#x1f99a;专栏&am…

单页面应用是什么?优缺点?如何弥补缺点

文章目录 导文单页面应用是什么&#xff1f;优点&#xff1a;缺点&#xff1a;弥补缺点的方法&#xff1a; 导文 Web单页应用就是指只有一个Web页面作为入口的应用 在浏览器中运行期间不会重新加载页面。也就是说浏览器一开始会加载它必需的thml、css和js 之后所有的交互操作都…

Godot 4 源码分析 - 命令行参数

粗看Godot 4的源码&#xff0c;稍微调试一下&#xff0c;发现一大堆的命令行参数。在widechar_main中 Error err Main::setup(argv_utf8[0], argc - 1, &argv_utf8[1]); Main::setup中&#xff0c;各命令行参数加入到List<Stirng> args中&#xff0c;并通过OS::get…

技术引领 踏浪而行 2023 A+CLUB 北京峰会 | 活动回顾

6月10日&#xff0c;“技术引领 踏浪而行”2023 ACLUB 北京峰会活动圆满举办&#xff0c;近70家机构超百人参会&#xff0c;其中北京及周边地区优秀私募占比八成。私募、券商、专家学者、业内先进解决方案&#xff08;包括算力、存储、网络、软件&#xff09;供应商从不同角度分…

【2023unity游戏制作-mango的冒险】-7.玩法实现

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;uni…

0805曲面及其方程-向量代数与空间解析几何

文章目录 1 曲面研究的基本问题2 旋转曲面3 柱面4 二次曲面4.1 定义4.2 研究方法4.3 九种二次曲面 结语 1 曲面研究的基本问题 曲面研究的两个基本问题&#xff1a; 已知一曲面作为点的几何轨迹时&#xff0c;建立这曲面的方程&#xff1b;已知x,y和z直接的一个方程时&#x…

如何在 Ubuntu 上实现 Nuxeo 与 ONLYOFFICE 文档集成

1. 概览 我们持续提供一系列易于使用的教程&#xff0c;向大家介绍如何将开源办公套件 ONLYOFFICE 文档集成到第三方 Web 服务中。ONLYOFFICE 文档根据 AGPLv.3 许可分发&#xff0c;包含处理文本文档、电子表格和演示文稿的编辑器&#xff0c;提供全套编辑及格式设置工具&…

Linux之进程间通信之管道

进程间通信的目的: 1、数据传输&#xff1a;一个进程需要将它的数据发售那个给另外一个进程。 2、资源共享&#xff1a;多个进程之间需要共享同样的资源。 3、通知事件&#xff1a;一个进程需要向另外一个或者一组进程发送消息&#xff0c;通知它们发生了某种事件(比如&…

java中避免使用“isSuccess“作为变量名的原因和解决方法

阿里巴巴Java开发手册的说法 在阿里巴巴Java开发手册中关于这一点&#xff0c;有过一个『强制性』规定&#xff1a; 其他原因 另外根据Java命名约定&#xff0c;方法名应该以动词开头&#xff0c;而变量名应该以名词或形容词开头。使用"isSuccess"作为变量名可能…

AAAI 2023 | 语言模型如何增强视觉模型的零样本能力 ?

文章链接&#xff1a;https://arxiv.org/abs/2207.01328 项目地址&#xff1a;https://github.com/zjukg/DUET 该论文设计了一种新的零样本学习范式&#xff0c;通过迁移语言模型中的先验语义知识&#xff0c;与视觉模型的特征感知能力进行对齐&#xff0c;以增强后者对于未见过…

nacos集成springcloud实现配置中心功能

1. 在nacos控制台创建namespace 2. 创建SpringCloud项目 大家注意springboot和springcloud的版本对应&#xff0c;可以去官网查看。 https://spring.io/projects/spring-cloud#learn <properties><java.version>11</java.version><poi.version>5.2.…

VSCode使用CodeWhisperer(AI编程)

安装AWS Toolkit插件&#xff0c;点击侧边插件搜索并安装 2.点击aws ->CodeWhisperer ->Start 3.在下拉菜单中点击Use a personal email to sign up and sign in with AWS Builder ID 4.点Copy Code and Proceed&#xff0c;这会自动复制一些东西 5. 收到提示打开外部网…

高德API JS 地图获取多个坐标点的中心点

高德API JS 地图获取多个坐标点的中心点 一、需求 我需要&#xff1a; 在地图上展示多个地点地图缩放到合适的大小&#xff0c;要求刚好能显示全部点位边缘留有一部分间隔。 做成如图所示这样。 二、需要用到的 AMap 类库 经过一下午的研究&#xff0c;弄出来了。 需要以…

【计算机网络自顶向下】简答题习题总结(一)

计算机网络是什么 两个及以上具有独立操作系统的计算机通过某些介质连接成的相互共享软硬件资源的集合体。 计算机网络两大功能 连通性和共享 如何描述Internet 分为两方面 具体构成 计算机互连设备、通信链路、分组交换设备 提供服务&#xff1a; 提供网络应用基础架构为分布式…

计网第二章实验2:DNS

DNS实验pdf下载地址(科学上网)&#xff1a;Wireshark_DNS_v7.0 (umass.edu) 实验前置知识 nslookup命令 nslookup –option1 –option2 host-to-find dns-server 如果dns-server不指定的话那么就是默认的&#xff1a;本地DNS服务器 选项其一 -typeNS or -typeA 所代表的意思不…

文心一言 VS 讯飞星火 VS chatgpt (43)-- 算法导论5.4 7题

七、为使特征序列长度的下界变得更精确&#xff0c;请说明在 n 次硬币的公平抛掷中&#xff0c;不出现比Ign - 2lglgn 更长的连续正面特征序列的概率小于 1/n。 文心一言&#xff1a; 在 n 次硬币的公平抛掷中&#xff0c;每个硬币正、反面朝上的概率均为 1/2。让我们考虑一个…

【人工智能技术专题】「入门到精通系列教程」零基础带你进军人工智能领域的全流程技术体系和实战指南(LLM、AGI和AIGC都是什么)

零基础带你掌握人工智能全流程技术体系和实战指南&#xff08;LLM、AGI和AIGC都是什么&#xff09; 前言专栏介绍专栏说明学习大纲前提条件面向读者学习目标核心重点三连问核心学习目标和方向 什么是LLM大语言模型概念定义训练方式机器学习的类型LLM与无监督学习什么是无监督学…