Android8.1 原始碼修改之通過黑名單遮蔽系統簡訊功能和來電功能

cczheng發表於2019-05-09

前言

之前寫過一篇Android6.0 的遮蔽系統簡訊功能和來電功能,具體看這裡

同樣的最近有個新需求,需要將8.1 裝置的來電功能和簡訊功能都遮蔽掉,特殊產品就是特殊定製,那就開始吧。

遮蔽簡訊功能

還可沿用之前的6.0 處理方法, 在 SmsReceiverService.java 中 handleSmsReceived()中進行攔截分發

但是想了想這次準備搞點不一樣的,我發現通訊錄和之前6.0不太一樣,8.1有個新增遮蔽聯絡人的功能,能夠遮蔽指定電話和簡訊,也就是黑名單功能。所以此次就通過黑名單的方式進行攔截,通過下面幾位老哥的詳盡分析和列印日誌找到修改地方

原始碼位置 frameworks\opt\telephony\src\java\com\android\internal\telephony\BlockChecker.java

public static boolean isBlocked(Context context, String phoneNumber) {
    boolean isBlocked = false;
    long startTimeNano = System.nanoTime();
    //cczheng add [S]
    log("phoneNumber==="+phoneNumber);
    boolean isIntercept = Settings.Global.getInt(context.getContentResolver(), 
            Settings.Global.IS_INTERCEPT_TELE, 1) == 1;
    if (isIntercept) {
        log("Intercept tele don't delivery..... default is blocked");
        return true;
    }
    //cczheng add [E]
    try {
        if (BlockedNumberContract.SystemContract.shouldSystemBlockNumber(
                context, phoneNumber)) {
            Rlog.d(TAG, phoneNumber + " is blocked.");
            isBlocked = true;
        }
    } catch (Exception e) {
        Rlog.e(TAG, "Exception checking for blocked number: " + e);
    }

    int durationMillis = (int) ((System.nanoTime() - startTimeNano) / 1000000);
    if (durationMillis > 500 || VDBG) {
        Rlog.d(TAG, "Blocked number lookup took: " + durationMillis + " ms.");
    }
    return isBlocked;
}

程式碼很簡單,傳遞一個號碼,去BlockedNumberContract資料庫中查詢是否存在,存在即為黑名單,攔截,不存在則不攔截。

為了實現攔截的功能,我在前面加了判斷,Settings.Global.IS_INTERCEPT_TELE 讀取值,這是在Settings中自定義的,當然你也可以採用SharedPreference儲存,這樣就可以動態的控制達到遮蔽簡訊和電話的功能。

當然如果你需要有黑名單列表,可在此處增加xml或者資料庫查詢,再做對應的攔截返回true操作。

遮蔽來電功能

方法同上

相關的簡單分析

BlockChecker的isBlocked()方法,電話和簡訊都會走這裡,如果你需要單獨分開,那麼就需要去跟蹤各自從哪裡呼叫過來的。

通過全域性搜尋,找到如下目錄

vendor\mediatek\proprietary\packages\services\Telecomm\src\com\android\server\telecom\callfiltering

  • AsyncBlockCheckFilter.java
  • BlockCheckerAdapter.java
  • CallFilteringResult.java
  • CallFilterResultCallback.java
  • CallScreeningServiceFilter.java
  • DirectToVoicemailCallFilter.java
  • IncomingCallFilter.java

AsyncBlockCheckFilter中呼叫 BlockCheckerAdapter 的isBlocked(),而BlockCheckerAdapter最終呼叫到BlockChecker中,所以要單獨遮蔽電話,可在AsyncBlockCheckFilter中操作

 @Override
protected Boolean doInBackground(String... params) {
    try {
        Log.continueSession(mBackgroundTaskSubsession, "ABCF.dIB");
        Log.addEvent(mIncomingCall, LogUtils.Events.BLOCK_CHECK_INITIATED);
        return mBlockCheckerAdapter.isBlocked(mContext, params[0]);
    } finally {
        Log.endSession();
    }
}

接下來再來看簡訊的

vendor\mediatek\proprietary\frameworks\opt\telephony\src\java\com\mediatek\internal\telephony\cdma\MtkCdmaInboundSmsHandler.java

vendor\mediatek\proprietary\frameworks\opt\telephony\src\java\com\mediatek\internal\telephony\gsm\MtkGsmInboundSmsHandler.java

都是直接呼叫BlockChecker的isBlocked()方法

在Settings中增加Switch控制是否啟用攔截

Android8.1 原始碼修改之通過黑名單遮蔽系統簡訊功能和來電功能

效果圖

實際上就是新增一個SwitchPreference來控制 Settings.Global.IS_INTERCEPT_TELE 的值

在安全性和位置資訊中新增 攔截設定選項

原始碼位置 vendor/mediatek/proprietary/packages/apps/MtkSettings/src/com/android/settings/SecuritySettings.java

仿照security_settings_misc.xml增加一份 security_settings_blockcheck.xml

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
    android:title="@string/security_settings_title">

    <PreferenceCategory android:title="@string/security_blockcheck_title"
            android:persistent="false">

        <SwitchPreference
            android:key="is_intercept"
            android:title="@string/is_intercept"
            android:summary="@string/is_intercept_summary"/>

    </PreferenceCategory>

</PreferenceScreen>

在SecuritySettings中findPreference("is_intercept"),監聽onPreferenceChange()事件,將回撥結果 value 儲存到IS_INTERCEPT_TELE

@Override
public boolean onPreferenceChange(Preference preference, Object value) {
    boolean result = true;
    final String key = preference.getKey();
    final LockPatternUtils lockPatternUtils = mChooseLockSettingsHelper.utils();

     if (KEY_IS_INTERCEPT.equals(key)) {
        Settings.Global.putInt(getContentResolver(), Settings.Global.IS_INTERCEPT_TELE,
                ((Boolean) value) ? 1 : 0);
    }
    return result;
}

好了,至此功能完成,感興趣的可研讀下列參考文章

參考文章

Android7.0 Phone應用原始碼分析(二) phone來電流程分析

Telephony之GsmCallTracker

Android 8.0來電流程分析(一)

相關文章