如何在Android 4.4上實現短信攔截

衆所周知Android在4.4上增加了不少安全措施,除了把SELinux設置爲enforce外,在短信方向也加強了限制。

4.4之後,新增了一個default sms的機制,詳細的描述,可以參考我的另一篇文章談談4.4中的新增功能對安全類軟件的影響。簡而言之,就是如果要在4.4之後實現短信攔截功能,就必須成爲default sms,把所有短信相關的功能都包攬了,然後再做短信攔截。但這種做法,適配性和兼容性的工作是非常巨大的,短信、wapush(多種)、彩信、單雙卡等等,相當於要求短信攔截類的軟件要集成一個功能非常完善的通訊錄類應用的功能。

那麼,是否有一種方法,可以在不成爲default sms的同時也可以對短信進行“寫操作”(這可是讓4.4一下子回到解放前啊。。。。)? 答案是有的。

XDA大牛有人發現了一種比較討巧的方法,原文可以參考這裏

原理很簡單,主要是利用4.2+後的添加的App Ops權限管理功能,在MESSAGE的TAB中找到自己的App,並進入相應的權限管理界面,如下圖所示,FinalDemo是我自己測試的一個DEMO:

      


留意到Write SMS/MMS的開頭,默認是OFF的,但我們可以把它打開。

     打開之後,我們就可以通過監控短信數據庫變化的方法實現短信攔截了,我也寫了個簡單的測試代碼,測試成功,把代碼和相關的配置也放了來吧

  • 打開App Ops的代碼
	Intent intent = new Intent(Intent.ACTION_MAIN);
	ComponentName cn = new ComponentName("com.android.settings", "com.android.settings.Settings");
	intent.setComponent(cn);
	intent.putExtra(":android:show_fragment", "com.android.settings.applications.AppOpsSummary");
	startActivity(intent);




  • AndroidManifest.xml的配置
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.finaldemo"
    android:versionCode="1"
    android:versionName="1.0" >
    <uses-sdk
        android:minSdkVersion="19" />
    <uses-permission android:name="android.permission.READ_SMS" />
    <uses-permission android:name="android.permission.WRITE_SMS" />
    <uses-permission android:name="android.permission.SEND_SMS" />
    <uses-permission android:name="android.permission.RECEIVE_SMS" />
    <uses-permission android:name="android.permission.RECEIVE_WAP_PUSH" />
    <uses-permission android:name="android.permission.RECEIVE_MMS" />
    <!-- <uses-permission android:name="android.permission.SEND_SMS"/> -->
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        
        <activity
            android:name="com.example.finaldemo.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <receiver
            android:name=".SmsReceiver"
            android:permission="android.permission.BROADCAST_SMS" >
            
            <intent-filter>
                <action android:name="android.provider.Telephony.SMS_RECEIVED" />
            </intent-filter>
            
        </receiver>
        
        <service android:name="com.example.finaldemo.SmsService" />
   
    </application>
</manifest>

  • 短信攔截的代碼
mObserver = new ContentObserver(new Handler()) {

		@Override
		public void onChange(boolean selfChange) {
			super.onChange(selfChange);
			ContentResolver resolver = getContentResolver();
			Cursor cursor = resolver.query(Uri.parse("content://sms/inbox"), new String[] { "_id", "address", "body" }, null, null, "_id desc");
			long id = -1;

			if (cursor.getCount() > 0 && cursor.moveToFirst()) {
				id = cursor.getLong(0);
				String address = cursor.getString(1);
				String body = cursor.getString(2);

				Toast.makeText(SmsService.this, String.format("address: %s\n body: %s", address, body), Toast.LENGTH_SHORT).show();
			}
			cursor.close();

			if (id != -1) {
				int count = resolver.delete(Sms.CONTENT_URI, "_id=" + id, null);
				Toast.makeText(SmsService.this, count == 1 ? "刪除成功" : "刪除失敗", Toast.LENGTH_SHORT).show();
			}
		}

		};

		getContentResolver().registerContentObserver(Uri.parse("content://sms/"), true, mObserver);





個人結論
  •  在4.4上我們可以在不成爲default sms的前提下實現短信攔截,但由於App Ops從4.3出現到4.4一直牌隱藏的狀態,猜想google還在不斷調整中,4.4之後的子版本是否會保留,是完全不能保證的;
  •  Write SMS/MMS的權限開關的存在跟defaultsms本身是一個矛盾,之所以出現Write SMS/MMS的權限開關,完全是因爲App Ops出現在前,而defaultsms出現在後所致;
  • 在4.4前,短信攔截都是通過動態註冊高優先級BroadcastReceiver的方式進行攔截的,主要是用於跟競品進行短信搶佔。而現在ContenetObserver是並行通知的情況下,如果過濾邏輯不夠快,依然有可能會被競品搶先把短信先刪除掉,導致拿到的最後一次短信是舊的短信。建議結合BroadcastReceiver和ContenetObserver進行攔截,BroadcastReceiver做內容校正和後備數據,以防拿到的最後一條短信是舊的時候,依然可以進行正常的攔截流程;



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章