Android10.0(Q) 默认应用设置(电话、短信、浏览器、主屏幕应用)

简介: Android10.0(Q) 默认应用设置(电话、短信、浏览器、主屏幕应用)

有些时候系统里预装了两个电话、桌面这样的应用,开机启动后系统会弹框让你选择使用那一个。


在系统设置中应用和通知里发现有默认应用选项,点进去发现是在 PermissionController 中


默认列表界面


adb shell dumpsys window | findstr mCurrentFocus


mCurrentFocus=Window{ffb6aca u0 com.android.permissioncontroller/com.android.packageinstaller.role.ui.DefaultAppListActivity}


默认应用详情界面


adb shell dumpsys window | findstr mCurrentFocus


mCurrentFocus=Window{d2fceb3 u0 com.android.permissioncontroller/com.android.packageinstaller.role.ui.DefaultAppActivity}


点击 Preference 切换是最终调用的代码走到 setRoleHolderAsUser()


vendor\mediatek\proprietary\packages\apps\PermissionController\src\com\android\packageinstaller\role\ui\ManageRoleHolderStateLiveData.java

public void setRoleHolderAsUser(@NonNull String roleName, @NonNull String packageName,
            boolean add, int flags, @NonNull UserHandle user, @NonNull Context context) {
        if (getValue() != STATE_IDLE) {
            Log.e(LOG_TAG, "Already (tried) managing role holders, requested role: " + roleName
                    + ", requested package: " + packageName);
            return;
        }
        if (DEBUG) {
            Log.i(LOG_TAG, (add ? "Adding" : "Removing") + " package as role holder, role: "
                    + roleName + ", package: " + packageName);
        }
        mLastPackageName = packageName;
        mLastAdd = add;
        mLastFlags = flags;
        mLastUser = user;
        setValue(STATE_WORKING);
        RoleManager roleManager = context.getSystemService(RoleManager.class);
        Executor executor = context.getMainExecutor();
        Consumer<Boolean> callback = successful -> {
            if (successful) {
                if (DEBUG) {
                    Log.i(LOG_TAG, "Package " + (add ? "added" : "removed")
                            + " as role holder, role: " + roleName + ", package: " + packageName);
                }
                setValue(STATE_SUCCESS);
            } else {
                if (DEBUG) {
                    Log.i(LOG_TAG, "Failed to " + (add ? "add" : "remove")
                            + " package as role holder, role: " + roleName + ", package: "
                            + packageName);
                }
                setValue(STATE_FAILURE);
            }
        };
        if (add) {
            roleManager.addRoleHolderAsUser(roleName, packageName, flags, user, executor, callback);
        } else {
            roleManager.removeRoleHolderAsUser(roleName, packageName, flags, user, executor,
                    callback);
        }
    }

核心方法就是这个,那我们就可以仿照它来了,在 PermissionController 中监听开机广播,直接调用改方法设置默认应用就好。


各默认应用对应的 roleName 如下,改造一下 setRoleHolderAsUser(),传递 roleName 和 packageName


电话


role: android.app.role.DIALER, package: com.android.dialer


短信


role: android.app.role.SMS, package: com.android.mms


主屏幕


role: android.app.role.HOME, package: com.android.launcher3


浏览器


role: android.app.role.BROWSER, package: com.android.browser


vendor\mediatek\proprietary\packages\apps\PermissionController\AndroidManifest.xml


     <receiver android:name="com.android.packageinstaller.TemporaryFileManager"
        android:exported="true">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
        </intent-filter>
    </receiver>

vendor\mediatek\proprietary\packages\apps\PermissionController\src\com\android\packageinstaller\TemporaryFileManager.java

package com.android.packageinstaller;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.SystemClock;
import android.util.Log;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import com.android.packageinstaller.permission.model.AppPermissionGroup;
import com.android.packageinstaller.permission.model.AppPermissions;
import com.android.packageinstaller.permission.model.Permission;
import com.android.packageinstaller.permission.utils.ArrayUtils;
import com.android.packageinstaller.permission.utils.Utils;
import java.util.List;
import java.io.File;
import java.io.IOException;
import android.app.role.RoleManager;
import android.os.UserHandle;
import android.os.Process;
import java.util.concurrent.Executor;
import java.util.function.Consumer;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
/**
 * Manages files of the package installer and resets state during boot.
 */
public class TemporaryFileManager extends BroadcastReceiver {
    private static final String LOG_TAG = TemporaryFileManager.class.getSimpleName();
    private  void setBootFlag(Context context, int flag){
       SharedPreferences sharedPreferences = context.getSharedPreferences("boot_CONFIG", 
            Context.MODE_PRIVATE);
       Editor editor = sharedPreferences.edit();
       editor.putInt("boot_flag", flag).commit();
    }
    private  boolean isFirstBoot(Context context){
        SharedPreferences sharedPreferences = context.getSharedPreferences("boot_CONFIG", 
            Context.MODE_PRIVATE);
       return sharedPreferences.getInt("boot_flag", 0) == 0;
    }
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.e("permission", "action==="+ intent.getAction());
        if (isFirstBoot(context)) {
            setRoleHolderAsUser(context, "com.android.dialer");
            setBootFlag(context, 1);
        }
        long systemBootTime = System.currentTimeMillis() - SystemClock.elapsedRealtime();
        File[] filesOnBoot = context.getNoBackupFilesDir().listFiles();
        if (filesOnBoot == null) {
            return;
        }
        for (int i = 0; i < filesOnBoot.length; i++) {
            File fileOnBoot = filesOnBoot[i];
            if (systemBootTime > fileOnBoot.lastModified()) {
                boolean wasDeleted = fileOnBoot.delete();
                if (!wasDeleted) {
                    Log.w(LOG_TAG, "Could not delete " + fileOnBoot.getName() + " onBoot");
                }
            } else {
                Log.w(LOG_TAG, fileOnBoot.getName() + " was created before onBoot broadcast was "
                        + "received");
            }
        }
    }
    public void setRoleHolderAsUser(Context context, String packageName) {
        String roleName = "android.app.role.DIALER";
        boolean add = true;
        int flags = 0;
        UserHandle user = Process.myUserHandle();
        Log.i("permission", (add ? "Adding" : "Removing") + " package as role holder, role: "
                    + roleName + ", package: " + packageName);
        RoleManager roleManager = context.getSystemService(RoleManager.class);
        Executor executor = context.getMainExecutor();
        Consumer<Boolean> callback = successful -> {
            if (successful) {
                Log.d("permission", "Package " + (add ? "added" : "removed")
                            + " as role holder, role: " + roleName + ", package: " + packageName);
            } else {
                Log.d("permission", "Failed to " + (add ? "add" : "remove")
                            + " package as role holder, role: " + roleName + ", package: "
                            + packageName);
            }
        };
        roleManager.addRoleHolderAsUser(roleName, packageName, flags, user, executor, callback);
        Log.i("permission", "addRoleHolderAsUser done");
    }
}


目录
相关文章
|
3天前
|
IDE Java 开发工具
深入探索安卓应用开发:从环境搭建到第一个"Hello, World!"应用
本文将引导读者完成安卓应用开发的初步入门,包括安装必要的开发工具、配置开发环境、创建第一个简单的安卓项目,以及解释其背后的一些基本概念。通过一步步的指导和解释,本文旨在为安卓开发新手提供一个清晰、易懂的起点,帮助读者顺利地迈出安卓开发的第一步。
174 64
|
3天前
|
存储 Java Android开发
探索安卓应用开发:构建你的第一个"Hello World"应用
【9月更文挑战第24天】在本文中,我们将踏上一段激动人心的旅程,深入安卓应用开发的奥秘。通过一个简单而经典的“Hello World”项目,我们将解锁安卓应用开发的基础概念和步骤。无论你是编程新手还是希望扩展技能的老手,这篇文章都将为你提供一次实操体验。从搭建开发环境到运行你的应用,每一步都清晰易懂,确保你能顺利地迈出安卓开发的第一步。让我们开始吧,探索如何将一行简单的代码转变为一个功能齐全的安卓应用!
|
8天前
|
开发框架 搜索推荐 开发工具
打造个性化安卓应用:从零开始的Flutter之旅
【8月更文挑战第51天】本文是一篇面向初学者的Flutter入门教程,旨在通过简单易懂的语言和实际代码示例,引导读者步入跨平台移动应用开发的世界。文章首先介绍了Flutter的基本概念和优势,然后逐步展示了如何搭建开发环境、创建第一个Flutter应用,并实现了一个简单的待办事项列表。最后,文章探讨了Flutter在实现高性能和美观界面方面的潜力,鼓励读者发挥创意,探索更多可能。
53 15
|
8天前
|
Java Android开发 UED
🧠Android多线程与异步编程实战!告别卡顿,让应用响应如丝般顺滑!🧵
在Android开发中,为应对复杂应用场景和繁重计算任务,多线程与异步编程成为保证UI流畅性的关键。本文将介绍Android中的多线程基础,包括Thread、Handler、Looper、AsyncTask及ExecutorService等,并通过示例代码展示其实用性。AsyncTask适用于简单后台操作,而ExecutorService则能更好地管理复杂并发任务。合理运用这些技术,可显著提升应用性能和用户体验,避免内存泄漏和线程安全问题,确保UI更新顺畅。
27 5
|
9天前
|
前端开发 Java 数据库
💡Android开发者必看!掌握这5大框架,轻松打造爆款应用不是梦!🏆
在Android开发领域,框架犹如指路明灯,助力开发者加速应用开发并提升品质。本文将介绍五大必备框架:Retrofit简化网络请求,Room优化数据库访问,MVVM架构提高代码可维护性,Dagger 2管理依赖注入,Jetpack Compose革新UI开发。掌握这些框架,助你在竞争激烈的市场中脱颖而出,打造爆款应用。
61 3
|
9天前
|
存储 API Android开发
"解锁Android权限迷宫:一场惊心动魄的动态权限请求之旅,让你的应用从平凡跃升至用户心尖的宠儿!"
随着Android系统的更新,权限管理成为应用开发的关键。尤其在Android 6.0(API 级别 23)后,动态权限请求机制的引入提升了用户隐私保护,要求开发者进行更精细的权限管理。
28 2
|
10天前
|
搜索推荐 Java 测试技术
打造个性化安卓应用:从设计到发布的完全指南
【9月更文挑战第17天】在这个数字时代,拥有一款个性化的安卓应用无疑是展现创意、实现梦想的一大步。本文将带你走进安卓应用的开发世界,从设计理念的孕育到实际代码的编写,再到最终的应用发布,我们将一步步揭开应用开发的神秘面纱。无论你是编程新手还是希望提升现有技能,这篇文章都将是你的宝贵资源。让我们开始这段激动人心的旅程吧!
|
1天前
|
JavaScript 前端开发
js之浏览器对象|28
js之浏览器对象|28
|
1月前
|
机器学习/深度学习 人工智能 前端开发
【人工智能】利用TensorFlow.js在浏览器中实现一个基本的情感分析系统
使用TensorFlow.js在浏览器中进行情感分析是一个非常实用的应用场景。TensorFlow.js 是一个用于在JavaScript环境中训练和部署机器学习模型的库,使得开发者能够在客户端直接运行复杂的机器学习任务。对于情感分析,我们可以使用预先训练好的模型来识别文本中的积极、消极或中性情感。
60 4
【人工智能】利用TensorFlow.js在浏览器中实现一个基本的情感分析系统
|
28天前
|
机器学习/深度学习 存储 前端开发
实战揭秘:如何借助TensorFlow.js的强大力量,轻松将高效能的机器学习模型无缝集成到Web浏览器中,从而打造智能化的前端应用并优化用户体验
【8月更文挑战第31天】将机器学习模型集成到Web应用中,可让用户在浏览器内体验智能化功能。TensorFlow.js作为在客户端浏览器中运行的库,提供了强大支持。本文通过问答形式详细介绍如何使用TensorFlow.js将机器学习模型带入Web浏览器,并通过具体示例代码展示最佳实践。首先,需在HTML文件中引入TensorFlow.js库;接着,可通过加载预训练模型如MobileNet实现图像分类;然后,编写代码处理图像识别并显示结果;此外,还介绍了如何训练自定义模型及优化模型性能的方法,包括模型量化、剪枝和压缩等。
29 1