Android4.4 往短信收件箱中插入自定義短信(偽造短信)


這段時間稍微有點空閑,把前一段學習Android做過的一些小項目整理整理。雖然沒有什么工程量很大的項目,但是對於一個新手,解決這些問題還是花了一段時間。感覺還是非常有記錄的意義呢~~~么么噠*—*

今天要說明的這個項目,是要在Android手機里偽造一條短信,也就是在短信箱中插入一條自定義的短信,看上去就像自己的手機里收到了新的信息,但其實這並不是一條通過通信運營商的網絡發過來的信息,這是一條假的信息。

在Android4.4之前的版本,往短信箱插入信息很方便,所以這個對用戶來說很有威脅的漏洞,在Android4.4得到了修復。Android4.4中只有手機默認的消息App才能處理和短信相關的操作,而手機默認的消息App一般就是手機里自帶的官方App,當然用戶可以在設置里面,手動地將自己信任的消息App設置為默認App,總的來說,短信的操作控制權掌握到用戶自己的手中。

那如何自己實現一個處理消息的App呢?可以參考這篇文章。讓你的短信應用迎接Android 4.4(KitKat)。這篇文章是根據Google給出的官方文檔翻譯下來的。里面對消息App的必須的實現細節已經做了詳細的說明。

下面是我自己用到的時候具體的代碼:

MainActivity.java

  1 package tina.messagebox;
  2 
  3 import android.content.ContentResolver;
  4 import android.content.ContentUris;
  5 import android.content.ContentValues;
  6 import android.content.Intent;
  7 import android.database.Cursor;
  8 import android.net.Uri;
  9 import android.provider.Telephony;
 10 import android.support.v7.app.ActionBarActivity;
 11 import android.os.Bundle;
 12 import android.text.method.MovementMethod;
 13 import android.text.method.ScrollingMovementMethod;
 14 import android.view.Menu;
 15 import android.view.MenuItem;
 16 import android.view.View;
 17 import android.widget.Button;
 18 import android.widget.EditText;
 19 import android.widget.TextView;
 20 import android.widget.Toast;
 21 
 22 import java.text.SimpleDateFormat;
 23 import java.util.Date;
 24 
 25 
 26 public class MainActivity extends ActionBarActivity {
 27     private String defaultSmsPkg;
 28     private String mySmsPkg;
 29     private TextView mMessageView=null;
 30     private EditText mPhoneNumber=null;
 31     private EditText mMsg=null;
 32 
 33     @Override
 34     protected void onCreate(Bundle savedInstanceState) {
 35         super.onCreate(savedInstanceState);
 36         setContentView(R.layout.activity_main);
 37 
 38         mPhoneNumber=(EditText)findViewById(R.id.editText);
 39         mMsg=(EditText)findViewById(R.id.editText2);
 40         mMessageView=(TextView)findViewById(R.id.textView3);
 41         mMessageView.setMovementMethod(ScrollingMovementMethod.getInstance()); //設置滾動  42         defaultSmsPkg= Telephony.Sms.getDefaultSmsPackage(this);
 43         mySmsPkg= this.getPackageName();
 44 
 45         if(!defaultSmsPkg.equals(mySmsPkg)){
 46 //            如果這個App不是默認的Sms App,則修改成默認的SMS APP
 47 //            因為從Android 4.4開始,只有默認的SMS APP才能對SMS數據庫進行處理
 48             Intent intent=new Intent(Telephony.Sms.Intents.ACTION_CHANGE_DEFAULT);
 49             intent.putExtra(Telephony.Sms.Intents.EXTRA_PACKAGE_NAME,mySmsPkg);
 50             startActivity(intent);
 51         }
 52 
 53         Button button=(Button)findViewById(R.id.button);
 54         button.setOnClickListener(new View.OnClickListener() {
 55             @Override
 56             public void onClick(View v) {
 57                 if(mySmsPkg.equals(Telephony.Sms.getDefaultSmsPackage(MainActivity.this))){
 58                     if(mPhoneNumber.getText().toString().isEmpty()){
 59                         Toast.makeText(MainActivity.this,"Phone number cannot be empty!",Toast.LENGTH_LONG).show();
 60                         return;
 61                     }
 62                     if(mMsg.getText().toString().isEmpty()){
 63                         Toast.makeText(MainActivity.this,"Message cannot be empty!",Toast.LENGTH_LONG).show();
 64                         return;
 65                     }
 66                     System.out.println("My App is default SMS App.");
 67                     //        對短信數據庫進行處理
 68                     ContentResolver resolver=getContentResolver();
 69 
 70                     ContentValues values=new ContentValues();
 71                     values.put(Telephony.Sms.ADDRESS,mPhoneNumber.getText().toString());
 72                     values.put(Telephony.Sms.DATE, System.currentTimeMillis());
 73                     long dateSent=System.currentTimeMillis()-5000;
 74                     values.put(Telephony.Sms.DATE_SENT,dateSent);
 75                     values.put(Telephony.Sms.READ,false);
 76                     values.put(Telephony.Sms.SEEN,false);
 77                     values.put(Telephony.Sms.STATUS, Telephony.Sms.STATUS_COMPLETE);
 78                     values.put(Telephony.Sms.BODY, mMsg.getText().toString());
 79                     values.put(Telephony.Sms.TYPE, Telephony.Sms.MESSAGE_TYPE_INBOX);
 80 
 81                     Uri uri=resolver.insert(Telephony.Sms.CONTENT_URI,values);
 82                     if(uri!=null){
 83                         long uriId= ContentUris.parseId(uri);
 84                         System.out.println("uriId "+uriId);
 85                     }
 86 
 87                     Toast.makeText(MainActivity.this, "Insert a short Message.",
 88                             Toast.LENGTH_LONG).show();
 89 
 90 //            對短信數據庫處理結束后,恢復原來的默認SMS APP
 91                     Intent intent=new Intent(Telephony.Sms.Intents.ACTION_CHANGE_DEFAULT);
 92                     intent.putExtra(Telephony.Sms.Intents.EXTRA_PACKAGE_NAME,defaultSmsPkg);
 93                     startActivity(intent);
 94                     System.out.println("Recover default SMS App");
 95 
 96 //                    打印出收件箱里的最新5條短信
 97                     Cursor cursor=getContentResolver().query(Telephony.Sms.CONTENT_URI,null,null,null,null);
 98                     String msg="";
 99                     while ((cursor.moveToNext()) &&
100                             (cursor.getPosition()<5)){
101                         int dateColumn=cursor.getColumnIndex("date");
102                         int phoneColumn=cursor.getColumnIndex("address");
103                         int smsColumn=cursor.getColumnIndex("body");
104 
105                         System.out.println("count "+cursor.getCount()+" position "+cursor.getPosition());
106 //                        把從短信中獲取的時間戳換成一定格式的時間
107                         SimpleDateFormat sfd=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
108                         Date date=new Date(Long.parseLong(cursor.getString(dateColumn)));
109                         String time=sfd.format(date);
110                         msg=msg+time+" "+cursor.getString(phoneColumn)+":"+cursor.getString(smsColumn)+"\n";
111                         mMessageView.setText(msg);
112                     }
113 
114                 }
115                 else{
116                     Toast.makeText(MainActivity.this,"Sorry,the App is not default Sms App.",
117                             Toast.LENGTH_LONG).show();
118                 }
119             }
120         });
121     }
122 
123     @Override
124     public boolean onCreateOptionsMenu(Menu menu) {
125         // Inflate the menu; this adds items to the action bar if it is present.
126         getMenuInflater().inflate(R.menu.menu_main, menu);
127         return true;
128     }
129 
130     @Override
131     public boolean onOptionsItemSelected(MenuItem item) {
132         // Handle action bar item clicks here. The action bar will
133         // automatically handle clicks on the Home/Up button, so long
134         // as you specify a parent activity in AndroidManifest.xml.
135         int id = item.getItemId();
136 
137         //noinspection SimplifiableIfStatement
138         if (id == R.id.action_settings) {
139             return true;
140         }
141 
142         return super.onOptionsItemSelected(item);
143     }
144 }

以上是具體的動作實現,要完成一個默認的消息App,還需要具備接收SMS和MMS的能力以及發送SMS的能力,所以還需要MmsReceiver/SmsReceiver/SmsSendService,具體到今天要實現的功能而言,這幾個能力都不用具體實現,所以Receiver和Service並不用對具體的action進行相應。

MmsReceiver.java

 1 package tina.messagebox;
 2 
 3 import android.content.BroadcastReceiver;
 4 import android.content.Context;
 5 import android.content.Intent;
 6 
 7 /**
 8  * Created by Tina on 2015/8/11.
 9  */
10 public class MmsReceiver extends BroadcastReceiver {
11     @Override
12     public void onReceive(Context context, Intent intent) {
13 
14     }
15 }

SmsReceiver.java

 1 package tina.messagebox;
 2 
 3 import android.content.BroadcastReceiver;
 4 import android.content.Context;
 5 import android.content.Intent;
 6 
 7 /**
 8  * Created by Tina on 2015/8/11.
 9  */
10 public class SmsReceiver extends BroadcastReceiver {
11     @Override
12     public void onReceive(Context context, Intent intent) {
13 
14     }
15 }

SmsSendService.java

 1 package tina.messagebox;
 2 
 3 import android.app.Service;
 4 import android.content.Intent;
 5 import android.os.IBinder;
 6 
 7 public class SmsSendService extends Service {
 8     public SmsSendService() {
 9     }
10 
11     @Override
12     public IBinder onBind(Intent intent) {
13         // TODO: Return the communication channel to the service.
14         return null;
15     }
16 }

最后,要在AndroidManifest.xml中對Receiver和Service進行注冊,並聲明消息相關的權限。

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
 3     package="tina.messagebox" >
 4 
 5     <!-- Adding -->
 6     <uses-permission android:name="android.permission.WRITE_SMS" />
 7     <uses-permission android:name="android.permission.READ_SMS" />
 8 
 9     <!-- End Adding -->
10     <application
11         android:allowBackup="true"
12         android:icon="@mipmap/ic_launcher"
13         android:label="@string/app_name"
14         android:theme="@style/AppTheme" >
15         <activity
16             android:name=".MainActivity"
17             android:label="@string/app_name" >
18             <intent-filter>
19                 <action android:name="android.intent.action.MAIN" />
20 
21                 <category android:name="android.intent.category.LAUNCHER" />
22 
23                 <!-- Adding -->
24                 <action android:name="android.intent.action.SEND" />
25                 <action android:name="android.intent.action.SENDTO" />
26 
27                 <category android:name="android.intent.category.DEFAULT" />
28                 <category android:name="android.intent.category.BROWSABLE" />
29 
30                 <data android:scheme="sms" />
31                 <data android:scheme="smsto" />
32                 <data android:scheme="mms" />
33                 <data android:scheme="mmsto" />
34                 <!-- End Adding -->
35 
36             </intent-filter>
37         </activity>
38 
39         <!-- Adding -->
40         <!-- BroadcastReceiver that listens for incoming SMS messages -->
41         <receiver
42             android:name=".SmsReceiver"
43             android:permission="android.permission.BROADCAST_SMS" >
44             <intent-filter>
45                 <action android:name="android.provider.Telephony.SMS_DELIVER" />
46             </intent-filter>
47         </receiver>
48 
49         <!-- BroadcastReceiver that listens for incoming MMS messages -->
50         <receiver
51             android:name=".MmsReceiver"
52             android:permission="android.permission.BROADCAST_WAP_PUSH" >
53             <intent-filter>
54                 <action android:name="android.provider.Telephony.WAP_PUSH_DELIVER" />
55 
56                 <data android:mimeType="application/vnd.wap.mms-message" />
57             </intent-filter>
58         </receiver>
59 
60         <!-- Service that delivers messages from the phone "quick response" -->
61         <service
62             android:name=".SmsSendService"
63             android:exported="true"
64             android:permission="android.permission.SEND_RESPOND_VIA_MESSAGE" >
65             <intent-filter>
66                 <action android:name="android.intent.action.RESPOND_VIA_MESSAGE" />
67 
68                 <category android:name="android.intent.category.DEFAULT" />
69 
70                 <data android:scheme="sms" />
71                 <data android:scheme="smsto" />
72                 <data android:scheme="mms" />
73                 <data android:scheme="mmsto" />
74             </intent-filter>
75         </service>
76         <!-- End Adding -->
77     </application>
78 
79 </manifest>
View Code

這兩個Receiver和Service缺了任何一個,App都無法成為一個默認的消息App。

下面,是今天實現的App的運行效果。第一次打開App,會檢測該App是否是默認消息App,如果不是,則彈出對話框讓用戶決定是否將其設置為默認App,如果用戶同意,則可以輸入手機號碼和短信內容,按一下Insert,手機短信箱里就會多了一條短信,插入成功后會再彈出一個對話框,詢問用戶是否恢復手機自帶的短信App為默認,用戶選擇Yes,那么回到Message中,就可以看到一條未讀短信啦。當然,萬一一不小心,在后面這個對話框里選擇了NO,那么為了能夠正常地處理短信,還是到手機的“設置”里面,把原來的App設為默認吧。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM