原生Settings search屏蔽關(guān)鍵詞

基于Android 11的原理:

新增:

通過@SearchIndexable 和 SEARCH_INDEX_DATA_PROVIDER 插入search_index.db中

@SearchIndexable
public class DeviceAdminSettings extends DashboardFragment {
    static final String TAG = "DeviceAdminSettings";

    public int getMetricsCategory() {
        return SettingsEnums.DEVICE_ADMIN_SETTINGS;
    }

    @Override
    protected int getPreferenceScreenResId() {
        return R.xml.device_admin_settings;
    }

    @Override
    protected String getLogTag() {
        return TAG;
    }

    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
            new BaseSearchIndexProvider(R.xml.device_admin_settings);
}

SlicesIndexer 數(shù)據(jù)存儲核心類

/**
 * Manages the conversion of {@link DashboardFragment} and {@link BasePreferenceController} to
 * indexable data {@link SliceData} to be stored for Slices.
 */
class SlicesIndexer implements Runnable {

    private static final String TAG = "SlicesIndexer";

    private Context mContext;

    private SlicesDatabaseHelper mHelper;

    public SlicesIndexer(Context context) {
        mContext = context;
        mHelper = SlicesDatabaseHelper.getInstance(mContext);
    }

    /**
     * Asynchronously index slice data from {@link #indexSliceData()}.
     */
    @Override
    public void run() {
        indexSliceData();
    }

    /**
     * Synchronously takes data obtained from {@link SliceDataConverter} and indexes it into a
     * SQLite database
     */
    protected void indexSliceData() {
        if (mHelper.isSliceDataIndexed()) {
            Log.d(TAG, "Slices already indexed - returning.");
            return;
        }

        final SQLiteDatabase database = mHelper.getWritableDatabase();

        long startTime = System.currentTimeMillis();
        database.beginTransaction();
        try {
            mHelper.reconstruct(database);
            List<SliceData> indexData = getSliceData();
            insertSliceData(database, indexData);

            mHelper.setIndexedState();

            // TODO (b/71503044) Log indexing time.
            Log.d(TAG,
                    "Indexing slices database took: " + (System.currentTimeMillis() - startTime));
            database.setTransactionSuccessful();
        } finally {
            database.endTransaction();
        }
    }

    @VisibleForTesting
    List<SliceData> getSliceData() {
        return FeatureFactory.getFactory(mContext)
                .getSlicesFeatureProvider()
                .getSliceDataConverter(mContext)
                .getSliceData();
    }

    @VisibleForTesting
    void insertSliceData(SQLiteDatabase database, List<SliceData> indexData) {
        ContentValues values;

        for (SliceData dataRow : indexData) {
            values = new ContentValues();
            values.put(IndexColumns.KEY, dataRow.getKey());
            values.put(IndexColumns.SLICE_URI, dataRow.getUri().toSafeString());
            values.put(IndexColumns.TITLE, dataRow.getTitle());
            values.put(IndexColumns.SUMMARY, dataRow.getSummary());
            final CharSequence screenTitle = dataRow.getScreenTitle();
            if (screenTitle != null) {
                values.put(IndexColumns.SCREENTITLE, screenTitle.toString());
            }
            values.put(IndexColumns.KEYWORDS, dataRow.getKeywords());
            values.put(IndexColumns.ICON_RESOURCE, dataRow.getIconResource());
            values.put(IndexColumns.FRAGMENT, dataRow.getFragmentClassName());
            values.put(IndexColumns.CONTROLLER, dataRow.getPreferenceController());
            values.put(IndexColumns.SLICE_TYPE, dataRow.getSliceType());
            values.put(IndexColumns.UNAVAILABLE_SLICE_SUBTITLE,
                    dataRow.getUnavailableSliceSubtitle());
            values.put(IndexColumns.PUBLIC_SLICE, dataRow.isPublicSlice());

            database.replaceOrThrow(Tables.TABLE_SLICES_INDEX, null /* nullColumnHack */,
                    values);
        }
    }
}

屏蔽:

使用settings:searchable="false" 添加到過濾關(guān)鍵詞列表

<com.android.settingslib.widget.FooterPreference
        android:key="auto_brightness_footer"
        android:title="@string/auto_brightness_description"
        android:selectable="false"
        settings:searchable="false" />

可通過SettingsSearchIndexablesProvider查看所有被過濾的key

/**
     * 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<String> 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);
            //這里增加log打印
        }

        return cursor;
    }

注意事項:

  1. 原有的功能類不能注釋@SearchIndexable 和 SEARCH_INDEX_DATA_PROVIDER,否則無法添加到過濾關(guān)鍵詞列表,可以通過settings:isPreferenceVisible="false"隱藏;
    2.PreferenceScreen 和 Preference都可以使用settings:searchable="false",否則可能出現(xiàn)不能徹底屏蔽;
    3.如果升級固件是替換settings app,不建議直接注釋或刪除對應(yīng)代碼,因為本地數(shù)據(jù)庫已存儲了key,無法打到屏蔽的效果,如果確實要去除,自行刪除本地數(shù)據(jù)庫key才行。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容