標籤:des android style c class blog
眾所周知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的,但我們可以把它開啟。
開啟之後,我們就可以通過監控簡訊資料庫變化的方法實現簡訊攔截了,我也寫了個簡單的測試代碼,測試成功,把代碼和相關的配置也放了來吧
<span style="white-space:pre"> </span>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);
1 <?xml version="1.0" encoding="utf-8"?> 2 <manifest xmlns:android="http://schemas.android.com/apk/res/android" 3 package="com.example.finaldemo" 4 android:versionCode="1" 5 android:versionName="1.0" > 6 <uses-sdk 7 android:minSdkVersion="19" /> 8 <uses-permission android:name="android.permission.READ_SMS" /> 9 <uses-permission android:name="android.permission.WRITE_SMS" />10 <uses-permission android:name="android.permission.SEND_SMS" />11 <uses-permission android:name="android.permission.RECEIVE_SMS" />12 <uses-permission android:name="android.permission.RECEIVE_WAP_PUSH" />13 <uses-permission android:name="android.permission.RECEIVE_MMS" />14 <!-- <uses-permission android:name="android.permission.SEND_SMS"/> -->15 <application16 android:allowBackup="true"17 android:icon="@drawable/ic_launcher"18 android:label="@string/app_name"19 android:theme="@style/AppTheme" >20 21 <activity22 android:name="com.example.finaldemo.MainActivity"23 android:label="@string/app_name" >24 <intent-filter>25 <action android:name="android.intent.action.MAIN" />26 <category android:name="android.intent.category.LAUNCHER" />27 </intent-filter>28 </activity>29 <receiver30 android:name=".SmsReceiver"31 android:permission="android.permission.BROADCAST_SMS" >32 33 <intent-filter>34 <action android:name="android.provider.Telephony.SMS_RECEIVED" />35 </intent-filter>36 37 </receiver>38 39 <service android:name="com.example.finaldemo.SmsService" />40 41 </application>42 </manifest>
1 mObserver = new ContentObserver(new Handler()) { 2 3 @Override 4 public void onChange(boolean selfChange) { 5 super.onChange(selfChange); 6 ContentResolver resolver = getContentResolver(); 7 Cursor cursor = resolver.query(Uri.parse("content://sms/inbox"), new String[] { "_id", "address", "body" }, null, null, "_id desc"); 8 long id = -1; 9 10 if (cursor.getCount() > 0 && cursor.moveToFirst()) {11 id = cursor.getLong(0);12 String address = cursor.getString(1);13 String body = cursor.getString(2);14 15 Toast.makeText(SmsService.this, String.format("address: %s\n body: %s", address, body), Toast.LENGTH_SHORT).show();16 }17 cursor.close();18 19 if (id != -1) {20 int count = resolver.delete(Sms.CONTENT_URI, "_id=" + id, null);21 Toast.makeText(SmsService.this, count == 1 ? "刪除成功" : "刪除失敗", Toast.LENGTH_SHORT).show();22 }23 }24 25 };26 27 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做內容校正和後備資料,以防拿到的最後一條簡訊是舊的時候,依然可以進行正常的攔截流程;
轉載至:http://blog.csdn.net/l173864930/article/details/17112227