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

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

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

那麼,是否有一種方法,能夠在不成爲default sms的同時也能夠對短信進行「寫操做」(這但是讓4.4一會兒回到解放前啊。。。。)? 答案是有的。java

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

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

      

 

留意到Write SMS/MMS的開頭,默認是OFF的,但咱們能夠把它打開。安全

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

 

 

  • 打開App Ops的代碼
<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);

 



 
 
  • AndroidManifest.xml的配置
 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     <application
16         android:allowBackup="true"
17         android:icon="@drawable/ic_launcher"
18         android:label="@string/app_name"
19         android:theme="@style/AppTheme" >
20         
21         <activity
22             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         <receiver
30             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/17112227ide

相關文章
相關標籤/搜索