Settingsモジュール

8296 ワード

詳細
需要:Settingsメインインタフェースを管理制御し、ある暗号を入力し、Settingsの指定項目を隠す(Wifi、Bluetoothなど).別の一連の暗号を入力し、Settingsでアイテムを非表示にして表示を復元します.
/packages/app/Settings/com/android/settings/SettingsActivity.java
SettingsActivityではitemの一部の制御があります.
doUpdateTilesList(){
        PackageManager pm = getPackageManager();
        final UserManager um = UserManager.get(this);
        final boolean isAdmin = um.isAdminUser();

        String packageName = getPackageName();
        setTileEnabled(new ComponentName(packageName, WifiSettingsActivity.class.getName()),
                pm.hasSystemFeature(PackageManager.FEATURE_WIFI), isAdmin, pm);

        setTileEnabled(new ComponentName(packageName,
                Settings.BluetoothSettingsActivity.class.getName()),
                pm.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH), isAdmin, pm);

        setTileEnabled(new ComponentName(packageName,
                Settings.DataUsageSummaryActivity.class.getName()),
                Utils.isBandwidthControlEnabled(), isAdmin, pm);

        setTileEnabled(new ComponentName(packageName,
                Settings.SimSettingsActivity.class.getName()),
                Utils.showSimCardTile(this), isAdmin, pm);
        //location
        setTileEnabled(new ComponentName(packageName,
                Settings.LocationSettingsActivity.class.getName()),
                false, isAdmin, pm);

        setTileEnabled(new ComponentName(packageName,
                Settings.PowerUsageSummaryActivity.class.getName()),
                mBatteryPresent, isAdmin, pm);

        setTileEnabled(new ComponentName(packageName,
                Settings.UserSettingsActivity.class.getName()),
                UserHandle.MU_ENABLED && UserManager.supportsMultipleUsers()
                && !Utils.isMonkeyRunning(), isAdmin, pm);

        setTileEnabled(new ComponentName(packageName,
                        Settings.WirelessSettingsActivity.class.getName()),
                !UserManager.isDeviceInDemoMode(this), isAdmin, pm);

        setTileEnabled(new ComponentName(packageName,
                        Settings.DateTimeSettingsActivity.class.getName()),
                !UserManager.isDeviceInDemoMode(this), isAdmin, pm);
        NfcAdapter adapter = NfcAdapter.getDefaultAdapter(this);
        setTileEnabled(new ComponentName(packageName,
                        Settings.PaymentSettingsActivity.class.getName()),
                pm.hasSystemFeature(PackageManager.FEATURE_NFC)
                        && pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION)
                        && adapter != null && adapter.isEnabled(), isAdmin, pm);

        setTileEnabled(new ComponentName(packageName,
                Settings.PrintSettingsActivity.class.getName()),
                pm.hasSystemFeature(PackageManager.FEATURE_PRINTING), isAdmin, pm);

        final boolean showDev = mDevelopmentPreferences.getBoolean(
                    DevelopmentSettings.PREF_SHOW, android.os.Build.TYPE.equals("eng"))
                && !um.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES);
        setTileEnabled(new ComponentName(packageName,
                        Settings.DevelopmentSettingsActivity.class.getName()),
                showDev, isAdmin, pm);
       if(!SystemProperties.get("ro.build.characteristics","null").equals("tablet")) {
           setTileEnabled(new ComponentName(packageName,
                           Settings.ScreenshotSettingsActivity.class.getName()),
                   false, isAdmin, pm);
       }
}

   
ここでは、欠落したsettings項目を自分で追加して表示/非表示を制御できます.上流を検索することもできます.
ここで表示はpmである.hasSystemFeature(PackageManager.FEATURE_PRINTING)のようなタイプで、非表示はfalseです.しかし,コード解読により,ここではitemの表示と非表示の一部しか制御できず,すべてのitemに対する管理が達成できないことが分かった.ここでは正しい修正点ではありません.
Settingsの表示プロセスを追跡し続けると、すべてのitemがSettingsActivityを継承し、AndroidManifestを通過していることがわかりました.xmlの構成項目は、指定したfragmentを割り当てます.これは読み取りがあります

            
                
                
            
            
        

このようなプロパティ値を使用して、この操作を完了します.具体的なプロセス追跡はここでは詳細ではありません.
フレームワークのTileUtils.JAvaクラスではCategoryの取得、作成などの操作が行われます.これはSettingsに描画される主なプロパティです.
    public static ListgetCategories(Context context,
            HashMap, Tile> cache) {
        final long startTime = System.currentTimeMillis();
        boolean setup = Global.getInt(context.getContentResolver(), Global.DEVICE_PROVISIONED, 0)
                != 0;
        ArrayList tiles = new ArrayList<>();
        UserManager userManager = UserManager.get(context);
        for (UserHandle user : userManager.getUserProfiles()) {
            // TODO: Needs much optimization, too many PM queries going on here.
            if (user.getIdentifier() == ActivityManager.getCurrentUser()) {
                // Only add Settings for this user.
                getTilesForAction(context, user, SETTINGS_ACTION, cache, null, tiles, true);
                getTilesForAction(context, user, OPERATOR_SETTINGS, cache,
                        OPERATOR_DEFAULT_CATEGORY, tiles, false);
                getTilesForAction(context, user, MANUFACTURER_SETTINGS, cache,
                        MANUFACTURER_DEFAULT_CATEGORY, tiles, false);
            }
            if (setup) {
                getTilesForAction(context, user, EXTRA_SETTINGS_ACTION, cache, null, tiles, false);
            }
        }
        boolean isSupportBluetooth = "true".equals(SystemProperties.get("ro.rk.bt_enable"));
        HashMap categoryMap = new HashMap<>();
        for (Tile tile : tiles) {
            DashboardCategory category = categoryMap.get(tile.category);
            if (category == null) {
                category = createCategory(context, tile.category);
                if (category == null) {
                    Log.w(LOG_TAG, "Couldn't find category " + tile.category);
                    continue;
                }
                categoryMap.put(category.key, category);
            }
            Intent tileIntent = tile.intent;
            if(!isSupportBluetooth && tileIntent != null && tileIntent.toString().contains("com.android.settings/.Settings$BluetoothSettingsActivity"))
                continue;
            category.addTile(tile);
        }
        ArrayList categories = new ArrayList<>(categoryMap.values());
        for (DashboardCategory category : categories) {
            Collections.sort(category.tiles, TILE_COMPARATOR);
        }
        Collections.sort(categories, CATEGORY_COMPARATOR);
        if (DEBUG_TIMING) Log.d(LOG_TAG, "getCategories took "
                + (System.currentTimeMillis() - startTime) + " ms");
        return categories;
    }

getCategories()のtileからComponent情報:tileを取得できます.intent.getComponent()
シールドが必要なComponentをフィルタリングすることで,このフローを踏まずに関連itemのシールド操作を完了できる.
暗号は計算機のonEqualsまたはダイヤルで入力された指定文字列を取得し、SystemPropertiesで制御し、Settingsの非表示と表示を管理することができます.