jQuery鼠标指针特效

Android 系统适配无源码app

Android系统,无源码apk分辨率适配

demo1:某个应用的字体大小和UI显示,不适配当前设备的屏幕dpi

先来看一个问题:app启动,onResume中是否可以测量宽高?
如果是activity 启动后第一次进入onResume 生命周期,那么获取到的View的宽高是错误的;
如果是从其他activity回到当前activity而执行的onResume方法,那么就能够获取到View的宽高

为什么?

先找到系统调用 onResume 的地方,read f*** source code
./frameworks/base/core/java/android/app/ActivityThread.java

handleResumeActivity() {
    //...
    r = performResumeActivity(token, clearHide, reason);//调用 onResume()
    //...
    wm.addView(decor, l);// WindowManager添加Decor(decor是DecorView)
    //...
}

可以看到View的添加是要在执行完onResume()之后的,所以我们调整某个应用的字体大小和UI显示最好是在它之前

frameworks/base/core/java/android/app/Activity.java

 
protected void onCreate(@Nullable Bundle savedInstanceState) {
     ...
    mRestoredFromBundle = savedInstanceState != null;
    mCalled = true;
 
	//add text
    ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
    List<ActivityManager.RunningTaskInfo> runningTasks = am.getRunningTasks(1);
    if (runningTasks != null && !runningTasks.isEmpty()) {
        ComponentName topActivity = runningTasks.get(0).topActivity;
        String packageName = topActivity.getPackageName();
 
        if ("com.android.deskclock".equals(packageName)) {
            Resources resources = getResources();
 
            if (resources != null) {
                Configuration configuration = resources.getConfiguration();
                
                //适配字体
                if(configuration != null){
                    if(configuration.fontScale != 1.5f){
                        configuration.fontScale = 1.5f;
                        resources.updateConfiguration(configuration,resources.getDisplayMetrics());
                    }
                }
 
                if (configuration != null) {
                    DisplayMetrics displayMetrics = new DisplayMetrics();
                    getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
                    int densityDpi = displayMetrics.densityDpi;
                    
                    // 适配 dpi
                    if (densityDpi != 240) {
                        configuration.densityDpi = 240;
                        resources.updateConfiguration(configuration, resources.getDisplayMetrics());
                    }
                }
            }
        }
    }
    //add text
 }

Android 11 系统修改第三方应用的DPI
onResume中是否可以测量宽高

无源码app修改在Launcher3上显示的app图标

1.系统层修改,可以让系统内所有显示该app图标的地方都改了
/frameworks/base/core/java/android/content/pm/parsing/ParsingPackageUtils.java

parseBaseApk(){
    ...
     final TypedArray manifestArray = res.obtainAttributes(parser, R.styleable.AndroidManifest);
        try {
            final boolean isCoreApp =
                    parser.getAttributeBooleanValue(null, "coreApp", false);
            final ParsingPackage pkg = mCallback.startParsingPackage(
                    pkgName, apkPath, codePath, manifestArray, isCoreApp);
            final ParseResult<ParsingPackage> result =
                    parseBaseApkTags(input, pkg, manifestArray, res, parser, flags);
            if (result.isError()) {
                return result;
            }

            return input.success(pkg);
        } finally {
            manifestArray.recycle();
        }
    ...
}
-> parseBaseApkTags() -> parseBaseApplication() -> parseBaseAppBasicFlags(){
    ...
     // Resource ID
     .setBanner(resId(R.styleable.AndroidManifestApplication_banner, sa))
     .setDescriptionRes(resId(R.styleable.AndroidManifestApplication_description, sa))
     .setIconRes(resId(R.styleable.AndroidManifestApplication_icon, sa))// app应用图标,熟悉的AndroidManifest
     .setLogo(resId(R.styleable.AndroidManifestApplication_logo, sa))
     .setNetworkSecurityConfigRes(resId(R.styleable.AndroidManifestApplication_networkSecurityConfig, sa))
     .setRoundIconRes(resId(R.styleable.AndroidManifestApplication_roundIcon, sa))
     .setTheme(resId(R.styleable.AndroidManifestApplication_theme, sa))
      // Strings
     .setClassLoaderName(string(R.styleable.AndroidManifestApplication_classLoader, sa))
     ...
     .setPermission(nonConfigString(0, R.styleable.AndroidManifestApplication_permission, sa));
    //因为它是链式调用,不方便在上面添加拦截函数,最后替换
    //add text
    String packageName = pkg.getPackageName();
    if(packageName != null && packageName.equals("com.android.settings")){
        pkg.setIconRes(com.android.internal.R.drawable.perm_group_camera);//ic_battery
    }
    //add text
}

./frameworks/base/core/res/res/values/symbols.xml::  <java-symbol type="drawable" name="perm_group_camera" />

Android 11.0 PackageManagerService(二)APK扫描过程

2.Launcher3层面修改,在Launcher3层面修改界面上面显示的icon被修改了,setting和系统安装应用界面等还是原来的图

packages/apps/Launcher3/src/com/android/launcher3/BubbleTextView.java

    @UiThread
    protected void applyIconAndLabel(ItemInfoWithIcon info) {
        boolean useTheme = mDisplay == DISPLAY_WORKSPACE || mDisplay == DISPLAY_FOLDER
                || mDisplay == DISPLAY_TASKBAR;
        int flags = useTheme ? FLAG_THEMED : 0;
        if (mHideBadge) {
            flags |= FLAG_NO_BADGE;
        }
        FastBitmapDrawable iconDrawable = info.newIcon(getContext(), flags);
        mDotParams.appColor = iconDrawable.getIconColor();
        mDotParams.dotColor = getContext().getResources()
                .getColor(android.R.color.system_accent3_200, getContext().getTheme());
        //add text
		String pkg = info.getIntent().getComponent().getPackageName();
		String cls = info.getIntent().getComponent().getClassName();
		if("com.android.text".equals(pkg)){
			Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.BS_player);
				setIcon(new FastBitmapDrawable(bitmap));
		}else{
			  setIcon(iconDrawable);
		}
        //add text
        applyLabel(info);
    }

Android系统开发
Android第三方无源码应用图标icon定制

posted @ 2024-07-26 17:20  僵小七  阅读(10)  评论(0编辑  收藏  举报