Android12 Settings搜索功能屏蔽某个App

06-01 620阅读

Android12 Settings搜索功能屏蔽某个App

1.前言:

之前在Android12Rom定制需求中做了屏蔽Settings某个App的入口,有网络和互联网、已连接的设备、电池和存储,但是在搜索的时候还是能看到入口,所以感觉体验不是很好,于是根据要求屏蔽这几个3App的搜索功能,这里记录一下修改过程。

2.屏蔽存储:

源码路径:package/apps/settings/src/com/android/settings/deviceinfo/storage/StorageDashboardFragment

核心修改:

  public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
            new BaseSearchIndexProvider(R.xml.storage_dashboard_fragment) {
                @Override
                public boolean isPageSearchEnabled(Context context) {
                    return false; // 禁用搜索
                }
            };
/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.android.settings.deviceinfo;
import android.app.Activity;
import android.app.settings.SettingsEnums;
import android.app.usage.StorageStatsManager;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.UserHandle;
import android.os.UserManager;
import android.os.storage.StorageManager;
import android.os.storage.VolumeInfo;
import android.provider.SearchIndexableResource;
import android.util.SparseArray;
import android.view.View;
import androidx.annotation.VisibleForTesting;
import androidx.loader.app.LoaderManager;
import androidx.loader.content.Loader;
import androidx.preference.Preference;
import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.dashboard.profileselector.ProfileSelectFragment;
import com.android.settings.deviceinfo.storage.AutomaticStorageManagementSwitchPreferenceController;
import com.android.settings.deviceinfo.storage.CachedStorageValuesHelper;
import com.android.settings.deviceinfo.storage.SecondaryUserController;
import com.android.settings.deviceinfo.storage.StorageAsyncLoader;
import com.android.settings.deviceinfo.storage.StorageItemPreferenceController;
import com.android.settings.deviceinfo.storage.UserIconLoader;
import com.android.settings.deviceinfo.storage.VolumeSizesLoader;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.widget.EntityHeaderController;
import com.android.settingslib.applications.StorageStatsSource;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.deviceinfo.PrivateStorageInfo;
import com.android.settingslib.deviceinfo.StorageManagerVolumeProvider;
import com.android.settingslib.search.SearchIndexable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@SearchIndexable
public class StorageDashboardFragment extends DashboardFragment
        implements
        LoaderManager.LoaderCallbacks {
    private static final String TAG = "StorageDashboardFrag";
    private static final String SUMMARY_PREF_KEY = "storage_summary";
    private static final int STORAGE_JOB_ID = 0;
    private static final int ICON_JOB_ID = 1;
    private static final int VOLUME_SIZE_JOB_ID = 2;
    private VolumeInfo mVolume;
    private PrivateStorageInfo mStorageInfo;
    private SparseArray mAppsResult;
    private CachedStorageValuesHelper mCachedStorageValuesHelper;
    private StorageItemPreferenceController mPreferenceController;
    private PrivateVolumeOptionMenuController mOptionMenuController;
    private List mSecondaryUsers;
    private boolean mPersonalOnly;
    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        // Initialize the storage sizes that we can quickly calc.
        final Activity activity = getActivity();
        StorageManager sm = activity.getSystemService(StorageManager.class);
        mVolume = Utils.maybeInitializeVolume(sm, getArguments());
        mPersonalOnly = getArguments().getInt(ProfileSelectFragment.EXTRA_PROFILE)
                == ProfileSelectFragment.ProfileType.PERSONAL;
        if (mVolume == null) {
            activity.finish();
            return;
        }
        initializeOptionsMenu(activity);
        if (mPersonalOnly) {
            final Preference summary = getPreferenceScreen().findPreference(SUMMARY_PREF_KEY);
            if (summary != null) {
                summary.setVisible(false);
            }
        }
    }
    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        use(AutomaticStorageManagementSwitchPreferenceController.class).setFragmentManager(
                getFragmentManager());
    }
    @VisibleForTesting
    void initializeOptionsMenu(Activity activity) {
        mOptionMenuController = new PrivateVolumeOptionMenuController(
                activity, mVolume, activity.getPackageManager());
        getSettingsLifecycle().addObserver(mOptionMenuController);
        setHasOptionsMenu(true);
        activity.invalidateOptionsMenu();
    }
    @Override
    public void onViewCreated(View v, Bundle savedInstanceState) {
        super.onViewCreated(v, savedInstanceState);
        initializeCacheProvider();
        maybeSetLoading(isQuotaSupported());
        final Activity activity = getActivity();
        EntityHeaderController.newInstance(activity, this /*fragment*/,
                null /* header view */)
                .setRecyclerView(getListView(), getSettingsLifecycle())
                .styleActionBar(activity);
    }
    @Override
    public void onResume() {
        super.onResume();
        getLoaderManager().restartLoader(STORAGE_JOB_ID, Bundle.EMPTY, this);
        getLoaderManager()
                .restartLoader(VOLUME_SIZE_JOB_ID, Bundle.EMPTY, new VolumeSizeCallbacks());
        getLoaderManager().restartLoader(ICON_JOB_ID, Bundle.EMPTY, new IconLoaderCallbacks());
    }
    @Override
    public int getHelpResource() {
        return R.string.help_url_storage_dashboard;
    }
    private void onReceivedSizes() {
        boolean stopLoading = false;
        if (mStorageInfo != null) {
            long privateUsedBytes = mStorageInfo.totalBytes - mStorageInfo.freeBytes;
            mPreferenceController.setVolume(mVolume);
            mPreferenceController.setUsedSize(privateUsedBytes);
            mPreferenceController.setTotalSize(mStorageInfo.totalBytes);
            for (int i = 0, size = mSecondaryUsers.size(); i  UserIconLoader.loadUserIconsWithContext(getContext()));
        }
        @Override
        public void onLoadFinished(
                Loader loader, SparseArray data) {
            mSecondaryUsers
                    .stream()
                    .filter(controller -> controller instanceof UserIconLoader.UserIconHandler)
                    .forEach(
                            controller ->
                                    ((UserIconLoader.UserIconHandler) controller)
                                            .handleUserIcons(data));
        }
        @Override
        public void onLoaderReset(Loader loader) {
        }
    }
    public final class VolumeSizeCallbacks
            implements LoaderManager.LoaderCallbacks {
        @Override
        public Loader onCreateLoader(int id, Bundle args) {
            Context context = getContext();
            StorageManager sm = context.getSystemService(StorageManager.class);
            StorageManagerVolumeProvider smvp = new StorageManagerVolumeProvider(sm);
            final StorageStatsManager stats = context.getSystemService(StorageStatsManager.class);
            return new VolumeSizesLoader(context, smvp, stats, mVolume);
        }
        @Override
        public void onLoaderReset(Loader loader) {
        }
        @Override
        public void onLoadFinished(
                Loader loader, PrivateStorageInfo privateStorageInfo) {
            if (privateStorageInfo == null) {
                getActivity().finish();
                return;
            }
            mStorageInfo = privateStorageInfo;
            maybeCacheFreshValues();
            onReceivedSizes();
        }
    }
}

2.屏蔽已连接的设备:

源码路径:package/apps/settings/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragment

关键修改如下:

    /**
     * For Search.
     */
    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
            new BaseSearchIndexProvider(R.xml.connected_devices){
                @Override
                public boolean isPageSearchEnabled(Context context) {
                    return false; // 禁用搜索
                }
            };
/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.android.settings.connecteddevice;
import android.app.settings.SettingsEnums;
import android.content.Context;
import android.net.Uri;
import android.provider.DeviceConfig;
import androidx.annotation.VisibleForTesting;
import com.android.settings.R;
import com.android.settings.core.SettingsUIDeviceConfig;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.slices.SlicePreferenceController;
import com.android.settingslib.search.SearchIndexable;
@SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC)
public class ConnectedDeviceDashboardFragment extends DashboardFragment {
    private static final String TAG = "ConnectedDeviceFrag";
    @VisibleForTesting
    static final String KEY_CONNECTED_DEVICES = "connected_device_list";
    @VisibleForTesting
    static final String KEY_AVAILABLE_DEVICES = "available_device_list";
    @Override
    public int getMetricsCategory() {
        return SettingsEnums.SETTINGS_CONNECTED_DEVICE_CATEGORY;
    }
    @Override
    protected String getLogTag() {
        return TAG;
    }
    @Override
    protected boolean isParalleledControllers() {
        return true;
    }
    @Override
    public int getHelpResource() {
        return R.string.help_url_connected_devices;
    }
    @Override
    protected int getPreferenceScreenResId() {
        return R.xml.connected_devices;
    }
    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        final boolean nearbyEnabled = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SETTINGS_UI,
                SettingsUIDeviceConfig.BT_NEAR_BY_SUGGESTION_ENABLED, true);
        use(AvailableMediaDeviceGroupController.class).init(this);
        use(ConnectedDeviceGroupController.class).init(this);
        use(PreviouslyConnectedDevicePreferenceController.class).init(this);
        use(SlicePreferenceController.class).setSliceUri(nearbyEnabled
                ? Uri.parse(getString(R.string.config_nearby_devices_slice_uri))
                : null);
    }
    /**
     * For Search.
     */
    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
            new BaseSearchIndexProvider(R.xml.connected_devices){
                @Override
                public boolean isPageSearchEnabled(Context context) {
                    return false; // 禁用搜索
                }
            };
}

3.屏蔽网络和互联网:

源码路径:package/apps/settings/src/com/android/settings/network/NetworkDashboardFragment

关键修改方法如下:

在getNonIndexableKeysFromProvider()方法添加过滤

    
           public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
            new BaseSearchIndexProvider(R.xml.network_and_internet) {
            @Override
            public List createPreferenceControllers(Context
                    context) {
                return buildPreferenceControllers(context, null /* lifecycle */,
                        null /* metricsFeatureProvider */, null /* fragment */,
                        null /* mobilePlanHost */);
            }
            @Override
            public boolean isPageSearchEnabled(Context context) {
                return false; // 禁用搜索
            }
        };
/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.android.settings.network;
import static com.android.settings.network.MobilePlanPreferenceController.MANAGE_MOBILE_PLAN_DIALOG_ID;
import android.app.Dialog;
import android.app.settings.SettingsEnums;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment;
import com.android.settings.R;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.network.MobilePlanPreferenceController.MobilePlanPreferenceHost;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.wifi.WifiMasterSwitchPreferenceController;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.search.SearchIndexable;
import java.util.ArrayList;
import java.util.List;
@SearchIndexable
public class NetworkDashboardFragment extends DashboardFragment implements
        MobilePlanPreferenceHost {
    private static final String TAG = "NetworkDashboardFrag";
    @Override
    public int getMetricsCategory() {
        return SettingsEnums.SETTINGS_NETWORK_CATEGORY;
    }
    @Override
    protected String getLogTag() {
        return TAG;
    }
    @Override
    protected int getPreferenceScreenResId() {
        return R.xml.network_and_internet;
    }
    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        use(MultiNetworkHeaderController.class).init(getSettingsLifecycle());
        use(AirplaneModePreferenceController.class).setFragment(this);
        getSettingsLifecycle().addObserver(use(AllInOneTetherPreferenceController.class));
    }
    @Override
    public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
        super.onCreatePreferences(savedInstanceState, rootKey);
        use(AllInOneTetherPreferenceController.class).initEnabler(getSettingsLifecycle());
    }
    @Override
    public int getHelpResource() {
        return R.string.help_url_network_dashboard;
    }
    @Override
    protected List createPreferenceControllers(Context context) {
        return buildPreferenceControllers(context, getSettingsLifecycle(), mMetricsFeatureProvider,
                this /* fragment */, this /* mobilePlanHost */);
    }
    @Override
    protected boolean isParalleledControllers() {
        return true;
    }
    private static List buildPreferenceControllers(Context context,
            Lifecycle lifecycle, MetricsFeatureProvider metricsFeatureProvider, Fragment fragment,
            MobilePlanPreferenceHost mobilePlanHost) {
        final MobilePlanPreferenceController mobilePlanPreferenceController =
                new MobilePlanPreferenceController(context, mobilePlanHost);
        final WifiMasterSwitchPreferenceController wifiPreferenceController =
                new WifiMasterSwitchPreferenceController(context, metricsFeatureProvider);
        final VpnPreferenceController vpnPreferenceController =
                new VpnPreferenceController(context);
        final PrivateDnsPreferenceController privateDnsPreferenceController =
                new PrivateDnsPreferenceController(context);
        if (lifecycle != null) {
            lifecycle.addObserver(mobilePlanPreferenceController);
            lifecycle.addObserver(wifiPreferenceController);
            lifecycle.addObserver(vpnPreferenceController);
            lifecycle.addObserver(privateDnsPreferenceController);
        }
        final List controllers = new ArrayList();
        controllers.add(new MobileNetworkSummaryController(context, lifecycle));
        controllers.add(new TetherPreferenceController(context, lifecycle));
        controllers.add(vpnPreferenceController);
        controllers.add(new ProxyPreferenceController(context));
        controllers.add(mobilePlanPreferenceController);
        controllers.add(wifiPreferenceController);
        controllers.add(privateDnsPreferenceController);
        return controllers;
    }
    @Override
    public void showMobilePlanMessageDialog() {
        showDialog(MANAGE_MOBILE_PLAN_DIALOG_ID);
    }
    @Override
    public Dialog onCreateDialog(int dialogId) {
        Log.d(TAG, "onCreateDialog: dialogId=" + dialogId);
        switch (dialogId) {
            case MANAGE_MOBILE_PLAN_DIALOG_ID:
                final MobilePlanPreferenceController controller =
                        use(MobilePlanPreferenceController.class);
                return new AlertDialog.Builder(getActivity())
                        .setMessage(controller.getMobilePlanDialogMessage())
                        .setCancelable(false)
                        .setPositiveButton(com.android.internal.R.string.ok,
                                (dialog, id) -> controller.setMobilePlanDialogMessage(null))
                        .create();
        }
        return super.onCreateDialog(dialogId);
    }
    @Override
    public int getDialogMetricsCategory(int dialogId) {
        if (MANAGE_MOBILE_PLAN_DIALOG_ID == dialogId) {
            return SettingsEnums.DIALOG_MANAGE_MOBILE_PLAN;
        }
        return 0;
    }
    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
            new BaseSearchIndexProvider(R.xml.network_and_internet) {
                @Override
                public List createPreferenceControllers(Context
                        context) {
                    return buildPreferenceControllers(context, null /* lifecycle */,
                            null /* metricsFeatureProvider */, null /* fragment */,
                            null /* mobilePlanHost */);
                }
                @Override
                public boolean isPageSearchEnabled(Context context) {
                    return false; // 禁用搜索
                }
            };
}

4.屏蔽电池:

源码路径:package/apps/settings/src/com/android/settings/fuelgauge/PowerUsageSummary

关键修改方法:

public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
        new BaseSearchIndexProvider(R.xml.power_usage_summary){
            @Override
            public boolean isPageSearchEnabled(Context context) {
                return false; // 禁用搜索
            }
        };
/*
 * Copyright (C) 2009 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.android.settings.fuelgauge;
import static com.android.settings.fuelgauge.BatteryBroadcastReceiver.BatteryUpdateType;
import android.app.settings.SettingsEnums;
import android.content.Context;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.provider.Settings.Global;
import android.text.format.Formatter;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnLongClickListener;
import android.widget.TextView;
import androidx.annotation.VisibleForTesting;
import androidx.loader.app.LoaderManager;
import androidx.loader.app.LoaderManager.LoaderCallbacks;
import androidx.loader.content.Loader;
import com.android.settings.R;
import com.android.settings.SettingsActivity;
import com.android.settings.Utils;
import com.android.settings.core.SubSettingLauncher;
import com.android.settings.fuelgauge.batterytip.BatteryTipLoader;
import com.android.settings.fuelgauge.batterytip.BatteryTipPreferenceController;
import com.android.settings.fuelgauge.batterytip.tips.BatteryTip;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settingslib.fuelgauge.EstimateKt;
import com.android.settingslib.search.SearchIndexable;
import com.android.settingslib.utils.PowerUtil;
import com.android.settingslib.utils.StringUtil;
import com.android.settingslib.widget.LayoutPreference;
import java.util.List;
/**
 * Displays a list of apps and subsystems that consume power, ordered by how much power was consumed
 * since the last time it was unplugged.
 */
@SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC)
public class PowerUsageSummary extends PowerUsageBase implements OnLongClickListener,
        BatteryTipPreferenceController.BatteryTipListener {
    static final String TAG = "PowerUsageSummary";
    private static final String KEY_BATTERY_HEADER = "battery_header";
    private static final String KEY_SCREEN_USAGE = "screen_usage";
    private static final String KEY_TIME_SINCE_LAST_FULL_CHARGE = "last_full_charge";
    @VisibleForTesting
    static final int BATTERY_INFO_LOADER = 1;
    @VisibleForTesting
    static final int BATTERY_TIP_LOADER = 2;
    @VisibleForTesting
    static final int MENU_ADVANCED_BATTERY = Menu.FIRST + 1;
    public static final int DEBUG_INFO_LOADER = 3;
    @VisibleForTesting
    PowerGaugePreference mScreenUsagePref;
    @VisibleForTesting
    PowerGaugePreference mLastFullChargePref;
    @VisibleForTesting
    PowerUsageFeatureProvider mPowerFeatureProvider;
    @VisibleForTesting
    BatteryUtils mBatteryUtils;
    @VisibleForTesting
    LayoutPreference mBatteryLayoutPref;
    @VisibleForTesting
    BatteryInfo mBatteryInfo;
    @VisibleForTesting
    BatteryHeaderPreferenceController mBatteryHeaderPreferenceController;
    @VisibleForTesting
    boolean mNeedUpdateBatteryTip;
    @VisibleForTesting
    BatteryTipPreferenceController mBatteryTipPreferenceController;
    @VisibleForTesting
    final ContentObserver mSettingsObserver = new ContentObserver(new Handler()) {
        @Override
        public void onChange(boolean selfChange, Uri uri) {
            restartBatteryInfoLoader();
        }
    };
    @VisibleForTesting
    LoaderManager.LoaderCallbacks mBatteryInfoLoaderCallbacks =
            new LoaderManager.LoaderCallbacks() {
                @Override
                public Loader onCreateLoader(int i, Bundle bundle) {
                    return new BatteryInfoLoader(getContext(), mStatsHelper);
                }
                @Override
                public void onLoadFinished(Loader loader, BatteryInfo batteryInfo) {
                    mBatteryHeaderPreferenceController.updateHeaderPreference(batteryInfo);
                    mBatteryInfo = batteryInfo;
                    updateLastFullChargePreference();
                }
                @Override
                public void onLoaderReset(Loader loader) {
                    // do nothing
                }
            };
    LoaderManager.LoaderCallbacks mBatteryInfoDebugLoaderCallbacks =
            new LoaderCallbacks() {
                @Override
                public Loader onCreateLoader(int i, Bundle bundle) {
                    return new DebugEstimatesLoader(getContext(), mStatsHelper);
                }
                @Override
                public void onLoadFinished(Loader loader,
                        List batteryInfos) {
                    updateViews(batteryInfos);
                }
                @Override
                public void onLoaderReset(Loader loader) {
                }
            };
    protected void updateViews(List batteryInfos) {
        final BatteryMeterView batteryView = mBatteryLayoutPref
                .findViewById(R.id.battery_header_icon);
        final TextView percentRemaining =
                mBatteryLayoutPref.findViewById(R.id.battery_percent);
        final TextView summary1 = mBatteryLayoutPref.findViewById(R.id.summary1);
        BatteryInfo oldInfo = batteryInfos.get(0);
        BatteryInfo newInfo = batteryInfos.get(1);
        percentRemaining.setText(Utils.formatPercentage(oldInfo.batteryLevel));
        // set the text to the old estimate (copied from battery info). Note that this
        // can sometimes say 0 time remaining because battery stats requires the phone
        // be unplugged for a period of time before being willing ot make an estimate.
        final String OldEstimateString = mPowerFeatureProvider.getOldEstimateDebugString(
                Formatter.formatShortElapsedTime(getContext(),
                        PowerUtil.convertUsToMs(oldInfo.remainingTimeUs)));
        final String NewEstimateString = mPowerFeatureProvider.getEnhancedEstimateDebugString(
                Formatter.formatShortElapsedTime(getContext(),
                        PowerUtil.convertUsToMs(newInfo.remainingTimeUs)));
        summary1.setText(OldEstimateString + "\n" + NewEstimateString);
        batteryView.setBatteryLevel(oldInfo.batteryLevel);
        batteryView.setCharging(!oldInfo.discharging);
    }
    private LoaderManager.LoaderCallbacks mBatteryTipsCallbacks =
            new LoaderManager.LoaderCallbacks() {
                @Override
                public Loader onCreateLoader(int id, Bundle args) {
                    return new BatteryTipLoader(getContext(), mStatsHelper);
                }
                @Override
                public void onLoadFinished(Loader loader,
                        List data) {
                    mBatteryTipPreferenceController.updateBatteryTips(data);
                }
                @Override
                public void onLoaderReset(Loader loader) {
                }
            };
    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        final SettingsActivity activity = (SettingsActivity) getActivity();
        mBatteryHeaderPreferenceController = use(BatteryHeaderPreferenceController.class);
        mBatteryHeaderPreferenceController.setActivity(activity);
        mBatteryHeaderPreferenceController.setFragment(this);
        mBatteryHeaderPreferenceController.setLifecycle(getSettingsLifecycle());
        mBatteryTipPreferenceController = use(BatteryTipPreferenceController.class);
        mBatteryTipPreferenceController.setActivity(activity);
        mBatteryTipPreferenceController.setFragment(this);
        mBatteryTipPreferenceController.setBatteryTipListener(this::onBatteryTipHandled);
    }
    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        setAnimationAllowed(true);
        initFeatureProvider();
        mBatteryLayoutPref = (LayoutPreference) findPreference(KEY_BATTERY_HEADER);
        mScreenUsagePref = (PowerGaugePreference) findPreference(KEY_SCREEN_USAGE);
        mLastFullChargePref = (PowerGaugePreference) findPreference(
                KEY_TIME_SINCE_LAST_FULL_CHARGE);
        mBatteryUtils = BatteryUtils.getInstance(getContext());
        if (Utils.isBatteryPresent(getContext())) {
            restartBatteryInfoLoader();
        }
        mBatteryTipPreferenceController.restoreInstanceState(icicle);
        updateBatteryTipFlag(icicle);
    }
    @Override
    public void onResume() {
        super.onResume();
        getContentResolver().registerContentObserver(
                Global.getUriFor(Global.BATTERY_ESTIMATES_LAST_UPDATE_TIME),
                false,
                mSettingsObserver);
    }
    @Override
    public void onPause() {
        getContentResolver().unregisterContentObserver(mSettingsObserver);
        super.onPause();
    }
    @Override
    public int getMetricsCategory() {
        return SettingsEnums.FUELGAUGE_POWER_USAGE_SUMMARY_V2;
    }
    @Override
    protected String getLogTag() {
        return TAG;
    }
    @Override
    protected int getPreferenceScreenResId() {
        return R.xml.power_usage_summary;
    }
    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        menu.add(Menu.NONE, MENU_ADVANCED_BATTERY, Menu.NONE, R.string.advanced_battery_title);
        super.onCreateOptionsMenu(menu, inflater);
    }
    @Override
    public int getHelpResource() {
        return R.string.help_url_battery;
    }
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case MENU_ADVANCED_BATTERY:
                new SubSettingLauncher(getContext())
                        .setDestination(PowerUsageAdvanced.class.getName())
                        .setSourceMetricsCategory(getMetricsCategory())
                        .setTitleRes(R.string.advanced_battery_title)
                        .launch();
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }
    protected void refreshUi(@BatteryUpdateType int refreshType) {
        final Context context = getContext();
        if (context == null) {
            return;
        }
        // Skip refreshing UI if battery is not present.
        if (!mIsBatteryPresent) {
            return;
        }
        // Skip BatteryTipLoader if device is rotated or only battery level change
        if (mNeedUpdateBatteryTip
                && refreshType != BatteryUpdateType.BATTERY_LEVEL) {
            restartBatteryTipLoader();
        } else {
            mNeedUpdateBatteryTip = true;
        }
        // reload BatteryInfo and updateUI
        restartBatteryInfoLoader();
        updateLastFullChargePreference();
        mScreenUsagePref.setSubtitle(StringUtil.formatElapsedTime(getContext(),
                mBatteryUtils.calculateScreenUsageTime(mStatsHelper), false));
    }
    @VisibleForTesting
    void restartBatteryTipLoader() {
        getLoaderManager().restartLoader(BATTERY_TIP_LOADER, Bundle.EMPTY, mBatteryTipsCallbacks);
    }
    @VisibleForTesting
    void setBatteryLayoutPreference(LayoutPreference layoutPreference) {
        mBatteryLayoutPref = layoutPreference;
    }
    @VisibleForTesting
    void updateLastFullChargePreference() {
        if (mBatteryInfo != null && mBatteryInfo.averageTimeToDischarge
                != EstimateKt.AVERAGE_TIME_TO_DISCHARGE_UNKNOWN) {
            mLastFullChargePref.setTitle(R.string.battery_full_charge_last);
            mLastFullChargePref.setSubtitle(
                    StringUtil.formatElapsedTime(getContext(), mBatteryInfo.averageTimeToDischarge,
                            false /* withSeconds */));
        } else {
            final long lastFullChargeTime = mBatteryUtils.calculateLastFullChargeTime(mStatsHelper,
                    System.currentTimeMillis());
            mLastFullChargePref.setTitle(R.string.battery_last_full_charge);
            mLastFullChargePref.setSubtitle(
                    StringUtil.formatRelativeTime(getContext(), lastFullChargeTime,
                            false /* withSeconds */));
        }
    }
    @VisibleForTesting
    void showBothEstimates() {
        final Context context = getContext();
        if (context == null
                || !mPowerFeatureProvider.isEnhancedBatteryPredictionEnabled(context)) {
            return;
        }
        getLoaderManager().restartLoader(DEBUG_INFO_LOADER, Bundle.EMPTY,
                mBatteryInfoDebugLoaderCallbacks);
    }
    @VisibleForTesting
    void initFeatureProvider() {
        final Context context = getContext();
        mPowerFeatureProvider = FeatureFactory.getFactory(context)
                .getPowerUsageFeatureProvider(context);
    }
    @VisibleForTesting
    void restartBatteryInfoLoader() {
        if (getContext() == null) {
            return;
        }
        // Skip restartBatteryInfoLoader if battery is not present.
        if (!mIsBatteryPresent) {
            return;
        }
        getLoaderManager().restartLoader(BATTERY_INFO_LOADER, Bundle.EMPTY,
                mBatteryInfoLoaderCallbacks);
        if (mPowerFeatureProvider.isEstimateDebugEnabled()) {
            // Set long click action for summary to show debug info
            View header = mBatteryLayoutPref.findViewById(R.id.summary1);
            header.setOnLongClickListener(this);
        }
    }
    @VisibleForTesting
    void updateBatteryTipFlag(Bundle icicle) {
        mNeedUpdateBatteryTip = icicle == null || mBatteryTipPreferenceController.needUpdate();
    }
    @Override
    public boolean onLongClick(View view) {
        showBothEstimates();
        view.setOnLongClickListener(null);
        return true;
    }
    @Override
    protected void restartBatteryStatsLoader(@BatteryUpdateType int refreshType) {
        super.restartBatteryStatsLoader(refreshType);
        // Update battery header if battery is present.
        if (mIsBatteryPresent) {
            mBatteryHeaderPreferenceController.quickUpdateHeaderPreference();
        }
    }
    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        mBatteryTipPreferenceController.saveInstanceState(outState);
    }
    @Override
    public void onBatteryTipHandled(BatteryTip batteryTip) {
        restartBatteryTipLoader();
    }
    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
            new BaseSearchIndexProvider(R.xml.power_usage_summary){
                @Override
                public boolean isPageSearchEnabled(Context context) {
                    return false; // 禁用搜索
                }
            };
}

5.屏蔽入口:

源码路径:package/apps/settings/src/com/android/settings/DashboardFragmentRegistry

核心修改方法:注销以上几个App的入口:

        PARENT_TO_CATEGORY_KEY_MAP = new ArrayMap();
        PARENT_TO_CATEGORY_KEY_MAP.put(TopLevelSettings.class.getName(),
                CategoryKey.CATEGORY_HOMEPAGE);
/*        PARENT_TO_CATEGORY_KEY_MAP.put(
                NetworkDashboardFragment.class.getName(), CategoryKey.CATEGORY_NETWORK);
        PARENT_TO_CATEGORY_KEY_MAP.put(ConnectedDeviceDashboardFragment.class.getName(),
                CategoryKey.CATEGORY_CONNECT);
        PARENT_TO_CATEGORY_KEY_MAP.put(AdvancedConnectedDeviceDashboardFragment.class.getName(),
                CategoryKey.CATEGORY_DEVICE);*/
        PARENT_TO_CATEGORY_KEY_MAP.put(AppAndNotificationDashboardFragment.class.getName(),
                CategoryKey.CATEGORY_APPS);
  /*      PARENT_TO_CATEGORY_KEY_MAP.put(PowerUsageSummary.class.getName(),
                CategoryKey.CATEGORY_BATTERY);*/
        PARENT_TO_CATEGORY_KEY_MAP.put(DisplaySettings.class.getName(),
                CategoryKey.CATEGORY_DISPLAY);
        PARENT_TO_CATEGORY_KEY_MAP.put(SoundSettings.class.getName(),
                CategoryKey.CATEGORY_SOUND);
   /*     PARENT_TO_CATEGORY_KEY_MAP.put(StorageDashboardFragment.class.getName(),
                CategoryKey.CATEGORY_STORAGE);*/
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.android.settings.dashboard;
import android.util.ArrayMap;
import com.android.settings.DisplaySettings;
import com.android.settings.LegalSettings;
import com.android.settings.accounts.AccountDashboardFragment;
import com.android.settings.accounts.AccountDetailDashboardFragment;
import com.android.settings.applications.AppAndNotificationDashboardFragment;
import com.android.settings.connecteddevice.AdvancedConnectedDeviceDashboardFragment;
import com.android.settings.connecteddevice.ConnectedDeviceDashboardFragment;
import com.android.settings.development.DevelopmentSettingsDashboardFragment;
import com.android.settings.deviceinfo.StorageDashboardFragment;
import com.android.settings.deviceinfo.aboutphone.MyDeviceInfoFragment;
import com.android.settings.display.NightDisplaySettings;
import com.android.settings.enterprise.EnterprisePrivacySettings;
import com.android.settings.fuelgauge.PowerUsageSummary;
import com.android.settings.fuelgauge.SmartBatterySettings;
import com.android.settings.fuelgauge.batterysaver.BatterySaverSettings;
import com.android.settings.gestures.GestureSettings;
import com.android.settings.homepage.TopLevelSettings;
import com.android.settings.language.LanguageAndInputSettings;
import com.android.settings.network.NetworkDashboardFragment;
import com.android.settings.notification.ConfigureNotificationSettings;
import com.android.settings.notification.SoundSettings;
import com.android.settings.notification.zen.ZenModeSettings;
import com.android.settings.privacy.PrivacyDashboardFragment;
import com.android.settings.security.LockscreenDashboardFragment;
import com.android.settings.security.SecuritySettings;
import com.android.settings.system.SystemDashboardFragment;
import com.android.settingslib.drawer.CategoryKey;
import java.util.Map;
/**
 * A registry to keep track of which page hosts which category.
 */
public class DashboardFragmentRegistry {
    /**
     * Map from parent fragment to category key. The parent fragment hosts child with
     * category_key.
     */
    public static final Map PARENT_TO_CATEGORY_KEY_MAP;
    /**
     * Map from category_key to parent. This is a helper to look up which fragment hosts the
     * category_key.
     */
    public static final Map CATEGORY_KEY_TO_PARENT_MAP;
    static {
        PARENT_TO_CATEGORY_KEY_MAP = new ArrayMap();
        PARENT_TO_CATEGORY_KEY_MAP.put(TopLevelSettings.class.getName(),
                CategoryKey.CATEGORY_HOMEPAGE);
        PARENT_TO_CATEGORY_KEY_MAP.put(
                NetworkDashboardFragment.class.getName(), CategoryKey.CATEGORY_NETWORK);
        PARENT_TO_CATEGORY_KEY_MAP.put(ConnectedDeviceDashboardFragment.class.getName(),
                CategoryKey.CATEGORY_CONNECT);
        PARENT_TO_CATEGORY_KEY_MAP.put(AdvancedConnectedDeviceDashboardFragment.class.getName(),
                CategoryKey.CATEGORY_DEVICE);
        PARENT_TO_CATEGORY_KEY_MAP.put(AppAndNotificationDashboardFragment.class.getName(),
                CategoryKey.CATEGORY_APPS);
        PARENT_TO_CATEGORY_KEY_MAP.put(PowerUsageSummary.class.getName(),
                CategoryKey.CATEGORY_BATTERY);
        PARENT_TO_CATEGORY_KEY_MAP.put(DisplaySettings.class.getName(),
                CategoryKey.CATEGORY_DISPLAY);
        PARENT_TO_CATEGORY_KEY_MAP.put(SoundSettings.class.getName(),
                CategoryKey.CATEGORY_SOUND);
        PARENT_TO_CATEGORY_KEY_MAP.put(StorageDashboardFragment.class.getName(),
                CategoryKey.CATEGORY_STORAGE);
        PARENT_TO_CATEGORY_KEY_MAP.put(SecuritySettings.class.getName(),
                CategoryKey.CATEGORY_SECURITY);
        PARENT_TO_CATEGORY_KEY_MAP.put(AccountDetailDashboardFragment.class.getName(),
                CategoryKey.CATEGORY_ACCOUNT_DETAIL);
        PARENT_TO_CATEGORY_KEY_MAP.put(AccountDashboardFragment.class.getName(),
                CategoryKey.CATEGORY_ACCOUNT);
        PARENT_TO_CATEGORY_KEY_MAP.put(
                SystemDashboardFragment.class.getName(), CategoryKey.CATEGORY_SYSTEM);
        PARENT_TO_CATEGORY_KEY_MAP.put(LanguageAndInputSettings.class.getName(),
                CategoryKey.CATEGORY_SYSTEM_LANGUAGE);
        PARENT_TO_CATEGORY_KEY_MAP.put(DevelopmentSettingsDashboardFragment.class.getName(),
                CategoryKey.CATEGORY_SYSTEM_DEVELOPMENT);
        PARENT_TO_CATEGORY_KEY_MAP.put(ConfigureNotificationSettings.class.getName(),
                CategoryKey.CATEGORY_NOTIFICATIONS);
        PARENT_TO_CATEGORY_KEY_MAP.put(LockscreenDashboardFragment.class.getName(),
                CategoryKey.CATEGORY_SECURITY_LOCKSCREEN);
        PARENT_TO_CATEGORY_KEY_MAP.put(ZenModeSettings.class.getName(),
                CategoryKey.CATEGORY_DO_NOT_DISTURB);
        PARENT_TO_CATEGORY_KEY_MAP.put(GestureSettings.class.getName(),
                CategoryKey.CATEGORY_GESTURES);
        PARENT_TO_CATEGORY_KEY_MAP.put(NightDisplaySettings.class.getName(),
                CategoryKey.CATEGORY_NIGHT_DISPLAY);
        PARENT_TO_CATEGORY_KEY_MAP.put(PrivacyDashboardFragment.class.getName(),
                CategoryKey.CATEGORY_PRIVACY);
        PARENT_TO_CATEGORY_KEY_MAP.put(EnterprisePrivacySettings.class.getName(),
                CategoryKey.CATEGORY_ENTERPRISE_PRIVACY);
        PARENT_TO_CATEGORY_KEY_MAP.put(LegalSettings.class.getName(),
                CategoryKey.CATEGORY_ABOUT_LEGAL);
        PARENT_TO_CATEGORY_KEY_MAP.put(MyDeviceInfoFragment.class.getName(),
                CategoryKey.CATEGORY_MY_DEVICE_INFO);
        PARENT_TO_CATEGORY_KEY_MAP.put(BatterySaverSettings.class.getName(),
                CategoryKey.CATEGORY_BATTERY_SAVER_SETTINGS);
        PARENT_TO_CATEGORY_KEY_MAP.put(SmartBatterySettings.class.getName(),
                CategoryKey.CATEGORY_SMART_BATTERY_SETTINGS);
        CATEGORY_KEY_TO_PARENT_MAP = new ArrayMap(PARENT_TO_CATEGORY_KEY_MAP.size());
        for (Map.Entry parentToKey : PARENT_TO_CATEGORY_KEY_MAP.entrySet()) {
            CATEGORY_KEY_TO_PARENT_MAP.put(parentToKey.getValue(), parentToKey.getKey());
        }
        // For injection index, redirect CATEGORY_ACCOUNT_DETAIL to AccountDashboardFragment.
        CATEGORY_KEY_TO_PARENT_MAP.put(CategoryKey.CATEGORY_ACCOUNT_DETAIL,
                AccountDashboardFragment.class.getName());
    }
}

6.修改搜索Provider:

源码路径:package/apps/settings/src/com/android/settings/SettingsSearchIndexablesProvider

关键修改如下:

在getNonIndexableKeysFromProvider()方法添加如下过滤:

 nonIndexableKeys.add(CategoryKey.CATEGORY_NETWORK);
        nonIndexableKeys.add(CategoryKey.CATEGORY_CONNECT);
        nonIndexableKeys.add(CategoryKey.CATEGORY_DEVICE);
        nonIndexableKeys.add(CategoryKey.CATEGORY_BATTERY);
        nonIndexableKeys.add(CategoryKey.CATEGORY_STORAGE);
/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.android.settings.search;
import static android.provider.SearchIndexablesContract.COLUMN_INDEX_NON_INDEXABLE_KEYS_KEY_VALUE;
import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_CLASS_NAME;
import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_ENTRIES;
import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_ICON_RESID;
import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_INTENT_ACTION;
import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_INTENT_TARGET_CLASS;
import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_INTENT_TARGET_PACKAGE;
import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_KEY;
import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_KEYWORDS;
import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_SCREEN_TITLE;
import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_SUMMARY_OFF;
import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_SUMMARY_ON;
import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_TITLE;
import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_USER_ID;
import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_CLASS_NAME;
import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_ICON_RESID;
import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_INTENT_ACTION;
import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_INTENT_TARGET_CLASS;
import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_INTENT_TARGET_PACKAGE;
import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_RANK;
import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_RESID;
import static android.provider.SearchIndexablesContract.INDEXABLES_RAW_COLUMNS;
import static android.provider.SearchIndexablesContract.INDEXABLES_XML_RES_COLUMNS;
import static android.provider.SearchIndexablesContract.NON_INDEXABLES_KEYS_COLUMNS;
import static android.provider.SearchIndexablesContract.SITE_MAP_COLUMNS;
import static android.provider.SearchIndexablesContract.SLICE_URI_PAIRS_COLUMNS;
import static com.android.settings.dashboard.DashboardFragmentRegistry.CATEGORY_KEY_TO_PARENT_MAP;
import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.database.MatrixCursor;
import android.net.Uri;
import android.provider.SearchIndexableResource;
import android.provider.SearchIndexablesContract;
import android.provider.SearchIndexablesProvider;
import android.provider.SettingsSlicesContract;
import android.text.TextUtils;
import android.util.ArraySet;
import android.util.Log;
import androidx.annotation.Nullable;
import androidx.slice.SliceViewManager;
import com.android.internal.annotations.VisibleForTesting;
import com.android.settings.R;
import com.android.settings.SettingsActivity;
import com.android.settings.dashboard.DashboardFeatureProvider;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.slices.SettingsSliceProvider;
import com.android.settingslib.drawer.ActivityTile;
import com.android.settingslib.drawer.CategoryKey;
import com.android.settingslib.drawer.DashboardCategory;
import com.android.settingslib.drawer.Tile;
import com.android.settingslib.search.Indexable;
import com.android.settingslib.search.SearchIndexableData;
import com.android.settingslib.search.SearchIndexableRaw;
import com.android.settingslib.drawer.CategoryKey;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
public class SettingsSearchIndexablesProvider extends SearchIndexablesProvider {
    public static final boolean DEBUG = false;
    /**
     * Flag for a system property which checks if we should crash if there are issues in the
     * indexing pipeline.
     */
    public static final String SYSPROP_CRASH_ON_ERROR =
            "debug.com.android.settings.search.crash_on_error";
    private static final String TAG = "SettingsSearchProvider";
    private static final Collection INVALID_KEYS;
    static {
        INVALID_KEYS = new ArraySet();
        INVALID_KEYS.add(null);
        INVALID_KEYS.add("");
    }
    @Override
    public boolean onCreate() {
        return true;
    }
    @Override
    public Cursor queryXmlResources(String[] projection) {
        final MatrixCursor cursor = new MatrixCursor(INDEXABLES_XML_RES_COLUMNS);
        final List resources =
                getSearchIndexableResourcesFromProvider(getContext());
        for (SearchIndexableResource val : resources) {
            final Object[] ref = new Object[INDEXABLES_XML_RES_COLUMNS.length];
            ref[COLUMN_INDEX_XML_RES_RANK] = val.rank;
            ref[COLUMN_INDEX_XML_RES_RESID] = val.xmlResId;
            ref[COLUMN_INDEX_XML_RES_CLASS_NAME] = val.className;
            ref[COLUMN_INDEX_XML_RES_ICON_RESID] = val.iconResId;
            ref[COLUMN_INDEX_XML_RES_INTENT_ACTION] = val.intentAction;
            ref[COLUMN_INDEX_XML_RES_INTENT_TARGET_PACKAGE] = val.intentTargetPackage;
            ref[COLUMN_INDEX_XML_RES_INTENT_TARGET_CLASS] = null; // intent target class
            cursor.addRow(ref);
        }
        return cursor;
    }
    /**
     * Gets a Cursor of RawData. We use those data in search indexing time
     */
    @Override
    public Cursor queryRawData(String[] projection) {
        final MatrixCursor cursor = new MatrixCursor(INDEXABLES_RAW_COLUMNS);
        final List raws = getSearchIndexableRawFromProvider(getContext());
        for (SearchIndexableRaw val : raws) {
            cursor.addRow(createIndexableRawColumnObjects(val));
        }
        return cursor;
    }
    /**
     * Gets a combined list non-indexable keys that come from providers inside of settings.
     * The non-indexable keys are used in Settings search at both index and update time to verify
     * the validity of results in the database.
     */
    @Override
    public Cursor queryNonIndexableKeys(String[] projection) {
        final MatrixCursor cursor = new MatrixCursor(NON_INDEXABLES_KEYS_COLUMNS);
        final List nonIndexableKeys = getNonIndexableKeysFromProvider(getContext());
        for (String nik : nonIndexableKeys) {
            final Object[] ref = new Object[NON_INDEXABLES_KEYS_COLUMNS.length];
            ref[COLUMN_INDEX_NON_INDEXABLE_KEYS_KEY_VALUE] = nik;
            cursor.addRow(ref);
        }
        return cursor;
    }
    /**
     * Gets a Cursor of dynamic Raw data similar to queryRawData. We use those data in search query
     * time
     */
    @Nullable
    @Override
    public Cursor queryDynamicRawData(String[] projection) {
        final Context context = getContext();
        final List rawList = new ArrayList();
        rawList.addAll(getDynamicSearchIndexableRawFromProvider(context));
        rawList.addAll(getInjectionIndexableRawData(context));
        final MatrixCursor cursor = new MatrixCursor(INDEXABLES_RAW_COLUMNS);
        for (SearchIndexableRaw raw : rawList) {
            cursor.addRow(createIndexableRawColumnObjects(raw));
        }
        return cursor;
    }
    @Override
    public Cursor querySiteMapPairs() {
        final MatrixCursor cursor = new MatrixCursor(SITE_MAP_COLUMNS);
        final Context context = getContext();
        // Loop through all IA categories and pages and build additional SiteMapPairs
        final List categories = FeatureFactory.getFactory(context)
                .getDashboardFeatureProvider(context).getAllCategories();
        for (DashboardCategory category : categories) {
            // Use the category key to look up parent (which page hosts this key)
            final String parentClass = CATEGORY_KEY_TO_PARENT_MAP.get(category.key);
            if (parentClass == null) {
                continue;
            }
            // Build parent-child class pairs for all children listed under this key.
            for (Tile tile : category.getTiles()) {
                String childClass = null;
                CharSequence childTitle = "";
                if (tile.getMetaData() != null) {
                    childClass = tile.getMetaData().getString(
                            SettingsActivity.META_DATA_KEY_FRAGMENT_CLASS);
                }
                if (childClass == null) {
                    childClass = tile.getComponentName();
                    childTitle = tile.getTitle(getContext());
                }
                if (childClass == null) {
                    continue;
                }
                cursor.newRow()
                        .add(SearchIndexablesContract.SiteMapColumns.PARENT_CLASS, parentClass)
                        .add(SearchIndexablesContract.SiteMapColumns.CHILD_CLASS, childClass)
                        .add(SearchIndexablesContract.SiteMapColumns.CHILD_TITLE, childTitle);
            }
        }
        // Loop through custom site map registry to build additional SiteMapPairs
        for (String childClass : CustomSiteMapRegistry.CUSTOM_SITE_MAP.keySet()) {
            final String parentClass = CustomSiteMapRegistry.CUSTOM_SITE_MAP.get(childClass);
            cursor.newRow()
                    .add(SearchIndexablesContract.SiteMapColumns.PARENT_CLASS, parentClass)
                    .add(SearchIndexablesContract.SiteMapColumns.CHILD_CLASS, childClass);
        }
        // Done.
        return cursor;
    }
    @Override
    public Cursor querySliceUriPairs() {
        final SliceViewManager manager = SliceViewManager.getInstance(getContext());
        final MatrixCursor cursor = new MatrixCursor(SLICE_URI_PAIRS_COLUMNS);
        final String queryUri = getContext().getString(R.string.config_non_public_slice_query_uri);
        final Uri baseUri = !TextUtils.isEmpty(queryUri) ? Uri.parse(queryUri)
                : new Uri.Builder()
                        .scheme(ContentResolver.SCHEME_CONTENT)
                        .authority(SettingsSliceProvider.SLICE_AUTHORITY)
                        .build();
        final Uri platformBaseUri =
                new Uri.Builder()
                        .scheme(ContentResolver.SCHEME_CONTENT)
                        .authority(SettingsSlicesContract.AUTHORITY)
                        .build();
        final Collection sliceUris = manager.getSliceDescendants(baseUri);
        sliceUris.addAll(manager.getSliceDescendants(platformBaseUri));
        for (Uri uri : sliceUris) {
            cursor.newRow()
                    .add(SearchIndexablesContract.SliceUriPairColumns.KEY, uri.getLastPathSegment())
                    .add(SearchIndexablesContract.SliceUriPairColumns.SLICE_URI, uri);
        }
        return cursor;
    }
    private List getNonIndexableKeysFromProvider(Context context) {
        final Collection bundles = FeatureFactory.getFactory(context)
                .getSearchFeatureProvider().getSearchIndexableResources().getProviderValues();
        final List nonIndexableKeys = new ArrayList();
        nonIndexableKeys.add(CategoryKey.CATEGORY_NETWORK);
        nonIndexableKeys.add(CategoryKey.CATEGORY_CONNECT);
        nonIndexableKeys.add(CategoryKey.CATEGORY_DEVICE);
        nonIndexableKeys.add(CategoryKey.CATEGORY_BATTERY);
        nonIndexableKeys.add(CategoryKey.CATEGORY_STORAGE);
        for (SearchIndexableData bundle : bundles) {
            final long startTime = System.currentTimeMillis();
            Indexable.SearchIndexProvider provider = bundle.getSearchIndexProvider();
            List providerNonIndexableKeys;
            try {
                providerNonIndexableKeys = provider.getNonIndexableKeys(context);
            } catch (Exception e) {
                // Catch a generic crash. In the absence of the catch, the background thread will
                // silently fail anyway, so we aren't losing information by catching the exception.
                // We crash when the system property exists so that we can test if crashes need to
                // be fixed.
                // The gain is that if there is a crash in a specific controller, we don't lose all
                // non-indexable keys, but we can still find specific crashes in development.
                if (System.getProperty(SYSPROP_CRASH_ON_ERROR) != null) {
                    throw new RuntimeException(e);
                }
                Log.e(TAG, "Error trying to get non-indexable keys from: "
                        + bundle.getTargetClass().getName(), e);
                continue;
            }
            if (providerNonIndexableKeys == null || providerNonIndexableKeys.isEmpty()) {
                if (DEBUG) {
                    final long totalTime = System.currentTimeMillis() - startTime;
                    Log.d(TAG, "No indexable, total time " + totalTime);
                }
                continue;
            }
            if (providerNonIndexableKeys.removeAll(INVALID_KEYS)) {
                Log.v(TAG, provider + " tried to add an empty non-indexable key");
            }
            if (DEBUG) {
                final long totalTime = System.currentTimeMillis() - startTime;
                Log.d(TAG, "Non-indexables " + providerNonIndexableKeys.size() + ", total time "
                        + totalTime);
            }
            nonIndexableKeys.addAll(providerNonIndexableKeys);
        }
        return nonIndexableKeys;
    }
    private List getSearchIndexableResourcesFromProvider(Context context) {
        final Collection bundles = FeatureFactory.getFactory(context)
                .getSearchFeatureProvider().getSearchIndexableResources().getProviderValues();
        List resourceList = new ArrayList();
        for (SearchIndexableData bundle : bundles) {
            Indexable.SearchIndexProvider provider = bundle.getSearchIndexProvider();
            final List resList =
                    provider.getXmlResourcesToIndex(context, true);
            if (resList == null) {
                continue;
            }
            for (SearchIndexableResource item : resList) {
                item.className = TextUtils.isEmpty(item.className)
                        ? bundle.getTargetClass().getName()
                        : item.className;
            }
            resourceList.addAll(resList);
        }
        return resourceList;
    }
    private List getSearchIndexableRawFromProvider(Context context) {
        final Collection bundles = FeatureFactory.getFactory(context)
                .getSearchFeatureProvider().getSearchIndexableResources().getProviderValues();
        final List rawList = new ArrayList();
        for (SearchIndexableData bundle : bundles) {
            Indexable.SearchIndexProvider provider = bundle.getSearchIndexProvider();
            final List providerRaws = provider.getRawDataToIndex(context,
                    true /* enabled */);
            if (providerRaws == null) {
                continue;
            }
            for (SearchIndexableRaw raw : providerRaws) {
                // The classname and intent information comes from the PreIndexData
                // This will be more clear when provider conversion is done at PreIndex time.
                raw.className = bundle.getTargetClass().getName();
            }
            rawList.addAll(providerRaws);
        }
        return rawList;
    }
    private List getDynamicSearchIndexableRawFromProvider(Context context) {
        final Collection bundles = FeatureFactory.getFactory(context)
                .getSearchFeatureProvider().getSearchIndexableResources().getProviderValues();
        final List rawList = new ArrayList();
        for (SearchIndexableData bundle : bundles) {
            final Indexable.SearchIndexProvider provider = bundle.getSearchIndexProvider();
            final List providerRaws =
                    provider.getDynamicRawDataToIndex(context, true /* enabled */);
            if (providerRaws == null) {
                continue;
            }
            for (SearchIndexableRaw raw : providerRaws) {
                // The classname and intent information comes from the PreIndexData
                // This will be more clear when provider conversion is done at PreIndex time.
                raw.className = bundle.getTargetClass().getName();
            }
            rawList.addAll(providerRaws);
        }
        return rawList;
    }
    private List getInjectionIndexableRawData(Context context) {
        final DashboardFeatureProvider dashboardFeatureProvider =
                FeatureFactory.getFactory(context).getDashboardFeatureProvider(context);
        final List rawList = new ArrayList();
        final String currentPackageName = context.getPackageName();
        for (DashboardCategory category : dashboardFeatureProvider.getAllCategories()) {
            // add start 屏蔽某些App
            if (category.key.equals(CategoryKey.CATEGORY_NETWORK) ||
                    category.key.equals(CategoryKey.CATEGORY_CONNECT) ||
                    category.key.equals(CategoryKey.CATEGORY_DEVICE) ||
                    category.key.equals(CategoryKey.CATEGORY_BATTERY) ||
                    category.key.equals(CategoryKey.CATEGORY_STORAGE)) {
                continue;
            }
            //add end
            for (Tile tile : category.getTiles()) {
                if (!isEligibleForIndexing(currentPackageName, tile)) {
                    continue;
                }
                final SearchIndexableRaw raw = new SearchIndexableRaw(context);
                final CharSequence title = tile.getTitle(context);
                raw.title = TextUtils.isEmpty(title) ? null : title.toString();
                if (TextUtils.isEmpty(raw.title)) {
                    continue;
                }
                raw.key = dashboardFeatureProvider.getDashboardKeyForTile(tile);
                final CharSequence summary = tile.getSummary(context);
                raw.summaryOn = TextUtils.isEmpty(summary) ? null : summary.toString();
                raw.summaryOff = raw.summaryOn;
                raw.className = CATEGORY_KEY_TO_PARENT_MAP.get(tile.getCategory());
                rawList.add(raw);
            }
        }
        return rawList;
    }
    @VisibleForTesting
    boolean isEligibleForIndexing(String packageName, Tile tile) {
        // 屏蔽特定 Tile
        if (tile.getCategory().equals(CategoryKey.CATEGORY_NETWORK) ||
                tile.getCategory().equals(CategoryKey.CATEGORY_CONNECT) ||
                tile.getCategory().equals(CategoryKey.CATEGORY_DEVICE) ||
                tile.getCategory().equals(CategoryKey.CATEGORY_BATTERY) ||
                tile.getCategory().equals(CategoryKey.CATEGORY_STORAGE)) {
            return false;
        }
        if (TextUtils.equals(packageName, tile.getPackageName())
                && tile instanceof ActivityTile) {
            // Skip Settings injected items because they should be indexed in the sub-pages.
            return false;
        }
        if (TextUtils.equals(tile.getCategory(), CategoryKey.CATEGORY_HOMEPAGE)) {
            // Skip homepage injected items since we would like to index their target activity.
            return false;
        }
        return true;
    }
    private static Object[] createIndexableRawColumnObjects(SearchIndexableRaw raw) {
        final Object[] ref = new Object[INDEXABLES_RAW_COLUMNS.length];
        ref[COLUMN_INDEX_RAW_TITLE] = raw.title;
        ref[COLUMN_INDEX_RAW_SUMMARY_ON] = raw.summaryOn;
        ref[COLUMN_INDEX_RAW_SUMMARY_OFF] = raw.summaryOff;
        ref[COLUMN_INDEX_RAW_ENTRIES] = raw.entries;
        ref[COLUMN_INDEX_RAW_KEYWORDS] = raw.keywords;
        ref[COLUMN_INDEX_RAW_SCREEN_TITLE] = raw.screenTitle;
        ref[COLUMN_INDEX_RAW_CLASS_NAME] = raw.className;
        ref[COLUMN_INDEX_RAW_ICON_RESID] = raw.iconResId;
        ref[COLUMN_INDEX_RAW_INTENT_ACTION] = raw.intentAction;
        ref[COLUMN_INDEX_RAW_INTENT_TARGET_PACKAGE] = raw.intentTargetPackage;
        ref[COLUMN_INDEX_RAW_INTENT_TARGET_CLASS] = raw.intentTargetClass;
        ref[COLUMN_INDEX_RAW_KEY] = raw.key;
        ref[COLUMN_INDEX_RAW_USER_ID] = raw.userId;
        return ref;
    }
}

7.修改getInjectionIndexableRawData()方法:

private List getInjectionIndexableRawData(Context context) {
    final DashboardFeatureProvider dashboardFeatureProvider =
            FeatureFactory.getFactory(context).getDashboardFeatureProvider(context);
    final List rawList = new ArrayList();
    final String currentPackageName = context.getPackageName();
    for (DashboardCategory category : dashboardFeatureProvider.getAllCategories()) {
        // add start 屏蔽某些App
        if (category.key.equals(CategoryKey.CATEGORY_NETWORK) ||
                category.key.equals(CategoryKey.CATEGORY_CONNECT) ||
                category.key.equals(CategoryKey.CATEGORY_DEVICE) ||
                category.key.equals(CategoryKey.CATEGORY_BATTERY) ||
                category.key.equals(CategoryKey.CATEGORY_STORAGE)) {
            continue;
        }
        //add end
        for (Tile tile : category.getTiles()) {
            if (!isEligibleForIndexing(currentPackageName, tile)) {
                continue;
            }
            final SearchIndexableRaw raw = new SearchIndexableRaw(context);
            final CharSequence title = tile.getTitle(context);
            raw.title = TextUtils.isEmpty(title) ? null : title.toString();
            if (TextUtils.isEmpty(raw.title)) {
                continue;
            }
            raw.key = dashboardFeatureProvider.getDashboardKeyForTile(tile);
            final CharSequence summary = tile.getSummary(context);
            raw.summaryOn = TextUtils.isEmpty(summary) ? null : summary.toString();
            raw.summaryOff = raw.summaryOn;
            raw.className = CATEGORY_KEY_TO_PARENT_MAP.get(tile.getCategory());
            rawList.add(raw);
        }
    }
    return rawList;
}

8.修改isEligibleForIndexing方法:

@VisibleForTesting
boolean isEligibleForIndexing(String packageName, Tile tile) {
    // 屏蔽特定 Tile
    if (tile.getCategory().equals(CategoryKey.CATEGORY_NETWORK) ||
            tile.getCategory().equals(CategoryKey.CATEGORY_CONNECT) ||
            tile.getCategory().equals(CategoryKey.CATEGORY_DEVICE) ||
            tile.getCategory().equals(CategoryKey.CATEGORY_BATTERY) ||
            tile.getCategory().equals(CategoryKey.CATEGORY_STORAGE)) {
        return false;
    }
    if (TextUtils.equals(packageName, tile.getPackageName())
            && tile instanceof ActivityTile) {
        // Skip Settings injected items because they should be indexed in the sub-pages.
        return false;
    }
    if (TextUtils.equals(tile.getCategory(), CategoryKey.CATEGORY_HOMEPAGE)) {
        // Skip homepage injected items since we would like to index their target activity.
        return false;
    }
    return true;
}

9.实现效果如下:

Android12 Settings搜索功能屏蔽某个App

Android12 Settings搜索功能屏蔽某个App

Android12 Settings搜索功能屏蔽某个App

Android12 Settings搜索功能屏蔽某个App

10.总结:

从上面的截图可以看到不管是搜索关键字还是具体的App,都没有出现网络和互联网、已连接的设备、存储、电池四个App的入口,基本上这几个App不会在Setting是搜索中出现,至此上面的问题得到解决。

  • 找到问题原因和提出解决方案
  • 编码实施,打包镜像进行验证
  • 在Setting中搜索前面几个App,基本上都不会出现
  • 这些要屏蔽的App可以根据需求来实现,但是如果关键字搜索出来 太多App入口,没必要全都屏蔽,这样修改的话后期如果不需要屏蔽改动太多,所以建议修改几个主要的App搜索入口即可.
免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们。

目录[+]

取消
微信二维码
微信二维码
支付宝二维码