How to Implement text message interception on Android 4.4
As we all know, Android 4.4 has added a lot of security measures. In addition to setting SELinux as enforce, it has also increased restrictions on text messages.
After 4.4, a default sms mechanism was added. For details, refer to my other article "about the impact of new functions in 4.4 on security software". In short, if you want to implement the text message interception function after 4.4, you must become the default sms. All the text message-related functions are included, and then the text message interception is performed. However, the adaptability and compatibility of such practices are enormous, such as text messages, wapush (various), MMS, single-and-Dual-card, etc, it is equivalent to the requirement that the text message interception software should integrate a well-functional Address Book application function.
So, is there a way to "write" text messages without being the default sms? (this makes 4.4 go back to liberation all at once ....)? The answer is yes.
Someone found a clever method for XDA Daniel. For the original article, refer to here.
The principle is very simple. It mainly uses the App Ops permission management function added after 4.2 + to find your App on the message tab and enter the corresponding permission management interface, as shown in, finalDemo is a demo I tested myself:
Note that the start of Write SMS/MMS is OFF by default, but we can open it.
After the function is enabled, we can monitor the changes in the text message database to implement text message interception. I also wrote a simple test code, and the test was successful, release the Code and related configurations.
Code for opening 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 configuration
<?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>
SMS interception code
MObserver = new ContentObserver (new Handler () {@ Overridepublic 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? "Deletion successful": "deletion failed", Toast. LENGTH_SHORT ). show () ;}}; getContentResolver (). registerContentObserver (Uri. parse ("content: // sms/"), true, mObserver );
Personal conclusionOn 4.4, we can implement text message interception without being the default sms. However, as App Ops appears from 4.3 to 4.4, google is still adjusting, whether the sub-versions after 4.4 will be retained is completely insecure. The permission switch of Write SMS/MMS is in conflict with defaultsms, the reason why the Write SMS/MMS permission switch occurs is because App Ops is in the front, and defaultsms is in the back;
Before January 1, 4.4, SMS interception was implemented by dynamically registering a high-priority BroadcastReceiver, mainly for text message preemption with competing products. Currently, when ContenetObserver is a parallel notification, if the filtering logic is not fast enough, it is still possible for competing products to delete the text message first, the last message is the old one. We recommend that you use BroadcastReceiver and ContenetObserver to intercept the message. BroadcastReceiver performs content correction and backup data to prevent normal interception when the last text message is old;