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>

这两个Receiver和Service缺了任何一个,App都无法成为一个默认的消息App。

下面,是今天实现的App的运行效果。第一次打开App,会检测该App是否是默认消息App,如果不是,则弹出对话框让用户决定是否将其设置为默认App,如果用户同意,则可以输入手机号码和短信内容,按一下Insert,手机短信箱里就会多了一条短信,插入成功后会再弹出一个对话框,询问用户是否恢复手机自带的短信App为默认,用户选择Yes,那么回到Message中,就可以看到一条未读短信啦。当然,万一一不小心,在后面这个对话框里选择了是,那么为了能够正常地处理短信,还是到手机的“设置”里面,把原来的App设为默认吧。

时间: 2024-10-01 05:28:02

Android4.4 往短信收件箱中插入自定义短信(伪造短信)的相关文章

android 访问SMS短信收件箱

访问 SMS收件箱是另一个常见的需求.首先,需要将读取 SMS 的权限 <uses-permission android:name="android.permission.READ_SMS"/> 添加到描述文件中.添加此权限后就可以读取SMS收件箱中的 短消息了. 要读取 SMS 消息,必须对SMS收件箱执行查询,下面是我们的 代码清单. 布局文件 <?xml version="1.0" encoding="utf-8"?>

如何解决Outlook收件箱显示1000多封邮件,但是查看时都是已读的?

如何解决Outlook收件箱显示1000多封邮件,但是查看时都是已读的? ?Lander Zhang 专注外企按需IT运维服务,IT Helpdesk 实战培训践行者博客:https://blog.51cto.com/lander IT Helpdesk 工程师实战培训课程:https://edu.51cto.com/lecturer/733218.html轻松进外企:IT Helpdesk工程师实战自学之路:https://blog.51cto.com/lander/2413018更新时间:2

JavaMail读取收件箱退信邮件/分析邮件附件获取Message_Id

需求描述:公司最近有个项目邮件通知功能,但是客户上传的邮件地址并不一定存在,以及其他的各种问题.所有希望发送通知后有个回执,及时发现地址存在问题的邮箱. 需求分析:经过分析JavaMail可以读取收件箱邮件,我们可以通过对应通知的退信来回写通知状态.那么问题来了,发送通知和退信如何建立映射?经过调研,最终确定采用以下方案解决. 映射方案: 在发送邮件通知时在Header中指定自定义的Message_Id,作为唯一标示,本系统中采用UUID. 定时任务扫描服务器邮箱的收件箱,本系统我们搜索收件箱中

通什翡翠商城大站协议邮件群发系统日发20-30万封不打码不换ip不需发件箱100%进收件箱

用一种新的技术思维去群发邮件 一种不用换IP,不需要任何发件箱的邮件群发方式 一种不需要验证码,不需要**代码变量的邮件群发方式 即使需要验证码也能全自动识别验证码的超级智能软件 教你最核心的邮件群发思维和软件群发技术图片链接不是 问题50%~90%进入收件箱让你不再为进垃圾箱而发愁 每天群发100万封邮件不再是难题 懒人技术升级版大站协议邮件群发 提供的不仅仅是软件更重要的是群发技术 邮件群发神器简介:什么是通什翡翠商城大站协议邮件群发系统? 通什翡翠商城大站协议邮件群发系统,是通过签署邮件群

懒人邮件群发日发50-100万封不打码不换IP不需发件箱大站协议系统营销软件100%进收件箱

用一种新的技术思维去群发邮件 一种不用换IP,不需要任何发件箱的邮件群发方式 一种不需要验证码,不需要**代码变量的邮件群发方式 即使需要验证码也能全自动识别验证码的超级智能软件 教你最核心的邮件群发思维和软件群发技术图片链接不是 问题50%~90%进入收件箱让你不再为进垃圾箱而发愁 每天群发100万封邮件不再是难题 懒人技术升级版大站协议邮件群发 提供的不仅仅是软件更重要的是群发技术 邮件群发神器简介:什么是懒人群发技术大站协议升级版? 懒人群发大站协议升级版,是通过签署邮件群发服务器协议的大

如何提高群发邮件进收件箱概率全面分析

保证邮件能进入收件箱并有高反馈的核心在于“在正确的时间给正确的人发正确的邮件”. 只有当我所发送的信息,对收件人来说是感兴趣的.需要的.相关的.有价值的,他才可能把发件人设置为白名单,把邮件从垃圾箱移入收件箱,星标邮件.打开邮件.点击链接.否则做再多的认证设置,再好的ISP关系也不可能持久地让邮件到达联系人的收件箱. 垃圾邮件判断步骤: 第一步是判断连接,如果你的IP域名在黑名单在这一步可能就直接被拒掉了: 第二步是判断账户,如果收件地址不存在.邮箱已满在这一步会被弹回: 第三步是邮件过滤,不同

一盘很大的棋:Android Wear要做用户唯一的收件箱

在今年的Google I/O 2014上,Google用一组数据告诉了我们:"安卓月活跃用户达 10 亿,用户每天点亮.解锁手机 1000 亿次". 这么算下来,一个合格的安卓用户每天都要解锁100此次呀.亲,你及格了么?三分钟一次信息提醒,五分钟两次消息推送,一个强迫症怎么可能经受的住这种折磨呢?总有收到新消息的错觉,总有遗漏信息的幻觉,无数次的点亮.解锁手机就成了必修课. Google已经看到了智能手机时代的上述问题,不会让这样的问题再延续到智能手表上,想要借助新的工具和战场,真正

网页邮箱收件箱被清空

春节前邮件系统收件箱有很多邮件,节后登录网页邮箱发现收件箱被清空无一封邮件. 客户配置了outlook,查看outlook配置 将在服务器上保留邮件的副本去除后即可.已删除邮件未找回.如有方法找回请大神告知.

IBM Domino用户收件箱定期维护

笔者公司邮件服务器使用Domino,因为种种原因,客户端一直使用Outlook,而且用户的邮件都是保留在服务器上,这样一来,时间久了用户的邮箱就会不断的增长,严重影响服务器的性能及用户体验,对于上述问题做了一个分析,使用Outlook或其它的POP工具一般只收取最近两周的邮件,但用户有POP请求的时候,连接到服务器上,会先执行POP的List命令,大家可以理解为服务器先把用户邮箱里的所有邮件按时间先后全部列表出来,然后再收取最近两周的邮件,这样用户的收件箱里邮件数量太多就会占用服务器的线程,使用