首页 > 其他分享 >Android短信监听实现,及Android4.4之后短信机制变更

Android短信监听实现,及Android4.4之后短信机制变更

时间:2023-02-16 17:33:25浏览次数:63  
标签:短信 String Android4.4 SMS public Android 监听

Android短信监听实现,及Android4.4之后短信机制变更

 

前阵子公司有一个项目,简单的监听短信应用,功能只有如下两个:

1.监听短信并获取短信内容上传服务器; 2.从服务器获取短信内容,发送出去    按照传统的思路,监听短信我们有两种方式;第一种是使用广播方式监听短信广播到来,第二种则是通过观察者,监听数据库数据变化。     其中,指的注意的是Android4.4之后版本,新引入了默认短信应用的概念,系统可以设置由某个应用来处理短信; 本文我们将带人们分析以下几个问题:    1.监听数据库变化方式监听短信    2.通过广播监听短信内容    3.Android 4.4以上版本短信权限问题    4.Android4.4版本以上设置默认短信应用    

1.监听数据库变化方式监听短信内容

既然是监听数据库变化 那我们就应该清楚短信的数据库表结构: sms主要结构:
  _id:          短信序号,如100
  thread_id:对话的序号,如100,与同一个手机号互发的短信,其序号是相同的
  address:  发件人地址,即手机号,如+86138138000
  person:   发件人,如果发件人在通讯录中则为具体姓名,陌生人为null
  date:       日期,long型,如1346988516,可以对日期显示格式进行设置
  protocol: 协议0SMS_RPOTO短信,1MMS_PROTO彩信
  read:      是否阅读0未读,1已读
  status:    短信状态-1接收,0complete,64pending,128failed
  type:       短信类型1是接收到的,2是已发出
  body:      短信具体内容
  service_center:短信服务中心号码编号,如+8613800755500    既然需要操作数据库,便少不了使用ContentResolver,所以我们应该还需要了解,短信的content uri : 全部短信:content://sms/ 收件箱:content://sms/inbox 发件箱:content://sms/sent 草稿箱:content://sms/draft   复制代码
private Uri SMS_INBOX = Uri.parse("content://sms/inbox");  
    public void getSmsFromPhone() {  
        ContentResolver cr = getContentResolver();  
        String[] projection = new String[] { "body","address" };//"_id", "address", "person",, "date", "type  
        String where = " date >  "  
                + (System.currentTimeMillis() - 10 * 60 * 1000);  
        Cursor cur = cr.query(SMS_INBOX, projection, where, null, "date desc");  
        if (null == cur)  
            return;  
        if (cur.moveToFirst()) {  
            String number = cur.getString(cur.getColumnIndex("address"));//手机号  
            String body = cur.getString(cur.getColumnIndex("body"));  
            //TODO 这里是具体处理逻辑 
            
        }  
    }
复制代码

 

在这里我们只是写了一个方法查询数据库,但是还有一个问题就是我们应该在什么时候去查数据库,总不能起个线程去轮训,这样太耗费资源了,这里我们可以是用观察者模式;

 

复制代码
private SmsObserver smsObserver;  
  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.app_login);  
        smsObserver = new SmsObserver(this, smsHandler);  
        getContentResolver().registerContentObserver(SMS_INBOX, true,  
                smsObserver);  
  
    }  
    public Handler smsHandler = new Handler() {  
        //这里可以进行回调的操作  
        //TODO  
  
    };  
    class SmsObserver extends ContentObserver {  
  
        public SmsObserver(Context context, Handler handler) {  
            super(handler);  
        }  
  
        @Override  
        public void onChange(boolean selfChange) {  
            super.onChange(selfChange);  
            //每当有新短信到来时,使用我们获取短消息的方法  
            getSmsFromPhone();  
        }  
    }
复制代码

 

在这里我们注册了一个观察者,监听收件箱的变化,一旦收件箱变化,我们就查询数据库,去除最新的一条数据 相应的权限这里就不贴出来了 至此我们就实现了通过监听数据库的方式来监听短信内容    

 2.通过广播监听短信内容

复制代码
public class SmsReceiver extends BroadcastReceiver {
    public static final String SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED";
    private static final String TAG = "yjj";
    public SmsReceiver() {
        Log.i("yjj", "new SmsReceiver");
    }
    @Override
    public void onReceive(final Context context, Intent intent) {
        Log.i(TAG, "jie shou dao");
        Cursor cursor = null;
        try {
            if (SMS_RECEIVED.equals(intent.getAction())) {
                Log.d(TAG, "sms received!");
                Bundle bundle = intent.getExtras();
                if (bundle != null) {
                    Object[] pdus = (Object[]) bundle.get("pdus");
                    final SmsMessage[] messages = new SmsMessage[pdus.length];
                    for (int i = 0; i < pdus.length; i++) {
                        messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
                    }
                    if (messages.length > 0) {
                        String content = messages[0].getMessageBody();
                        String sender = messages[0].getOriginatingAddress();
                        long msgDate = messages[0].getTimestampMillis();
                        String smsToast = "New SMS received from : "
                                + sender + "\n'"
                                + content + "'";
                        Toast.makeText(context, smsToast, Toast.LENGTH_LONG)
                                .show();
                        Log.d(TAG, "message from: " + sender + ", message body: " + content
                                + ", message date: " + msgDate);
                        //自己的逻辑
                    }
                }
                cursor = context.getContentResolver().query(Uri.parse("content://sms"), new String[] { "_id", "address", "read", "body", "date" }, "read = ? ", new String[] { "0" }, "date desc");
                if (null == cursor){
                    return;
                }
                Log.i(TAG,"m cursor count is "+cursor.getCount());
                Log.i(TAG,"m first is "+cursor.moveToFirst());
            }
        } catch (Exception e) {
            e.printStackTrace();
            Log.e(TAG, "Exception : " + e);
        } finally {
            if (cursor != null) {
                cursor.close();
                cursor = null;
            }
        }
    }
}
复制代码

 

这个很简单就是定义一个广播接收者,并且在清单文件中注册(注册有两种方式,这里就不展开了)

复制代码
<receiver android:name=".message.SmsReceiver" android:permission="android.permission.BROADCAST_SMS">
            <intent-filter android:priority="2147483647">
                <action android:name="android.provider.Telephony.SMS_DELIVER" />
                <action android:name="android.provider.Telephony.SMS_RECEIVED" />
            </intent-filter>
</receiver>
复制代码

 

3.Android 4.4以上版本短信权限问题

Android4.4版本之前,短信有着一个问题,任何应用只要想,就可以操作短信,着包括监听短信、修改短信、删除短信、拦截短信等,因而市面上有着成片的短信应用,着也使得Android系统短信的管理变得越发的混乱。 针对这个问题Google在Android4.4版本之后,引进了一个新的概念----默认短信应用。即用户可以在系统中选择由哪个应用默认对短信进行处理。 针对Android4.4版本的,Google提供了 SMS_DELIVER_ACTION(sms)和 WAP_PUSH_DELIVER_ACTION(MMS)这两个intent给默认的短信使用,也就是说只有默认短信才可以收到这两个广播,也只有收到这两个广播的短信应用才可以对短信数据库机型操作,其他的短信应用可以使用SMS_RECEIVED_ACTION对短信进行监听,但仅仅只能读取(理论上可以监听,但是在一台6.0系统的三星机器上并不能监听到,具体什么原因没查出来,当然这是在我所写的应用没有成为手机默认短信应用的情况下,当设置为默认短信应用后监听也是正常的) 另外,值得一提的是,在Android4.4版本之前SMS_RECEIVED_ACTION是一个有序广播,这意味着在Android4.4版本之前,应用在接受广播之后可以对广播进行拦截;但是在Android4.4之后,这个拦截动作不会生效,这就意味着Android4.4之后,非默认短信应用对短信除了读操作外,没有更多的权限了

 

 

4.Android4.4版本以上设置默认短信应用

我们已经分析了Android4.4版本之后短信的改变----默认短信应用,但是并不是每个应用都可以被设置为默认短信应用,接下来我们来实现一下怎么让我们的短信应用可以被设置为默认短息应用。 复制代码
<!-- BroadcastReceiver that listens for incoming MMS messages -->
        <receiver android:name=".message.MmsReceiver"
            android:permission="android.permission.BROADCAST_WAP_PUSH">
            <intent-filter>
                <action android:name="android.provider.Telephony.WAP_PUSH_DELIVER" />
                <data android:mimeType="application/vnd.wap.mms-message" />
            </intent-filter>
        </receiver>
        <!-- Activity that allows the user to send new SMS/MMS messages -->
        <activity android:name=".message.ComposeSmsActivity" >
            <intent-filter>
                <action android:name="android.intent.action.SEND" />
                <action android:name="android.intent.action.SENDTO" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />
                <data android:scheme="sms" />
                <data android:scheme="smsto" />
                <data android:scheme="mms" />
                <data android:scheme="mmsto" />
            </intent-filter>
        </activity>
        <!-- Service that delivers messages from the phone "quick response" -->
        <service android:name=".message.HeadlessSmsSendService"
            android:permission="android.permission.SEND_RESPOND_VIA_MESSAGE"
            android:exported="true" >
            <intent-filter>
                <action android:name="android.intent.action.RESPOND_VIA_MESSAGE" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:scheme="sms" />
                <data android:scheme="smsto" />
                <data android:scheme="mms" />
                <data android:scheme="mmsto" />
            </intent-filter>
        </service>
复制代码

 

首先我们子在清单文件中写入如下信息,可以看到我们定义了一个MmsReceiver、一个ComposeSmsActivity、一个HeadlessSmsSendService 很显然我们需要这三个对应的java文件,即一个receiver类、一个service类、一个Activity类;这三个了都可以不需要任何内容,具体代码如下 MmsReceiver.java
public class MmsReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
    }
}

 

ComposeSmsActivity.java

复制代码
public class ComposeSmsActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
    }
}
复制代码

 

HeadlessSmsSendService.java

复制代码
public class HeadlessSmsSendService extends Service {
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
}
复制代码

 

通过以上步骤,我们所写的应用就可以被设置为默认短信应用了

最后别忘了添加相应的权限:

复制代码
<uses-permission android:name="android.permission.CALL_PHONE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.READ_CONTACTS" />
    <uses-permission android:name="android.permission.WRITE_CONTACTS" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.READ_CALL_LOG" />
    <uses-permission android:name="android.permission.WRITE_CALL_LOG" />
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.READ_LOGS" />
    <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
    <uses-permission android:name="android.permission.READ_SMS" />
    <uses-permission android:name="android.permission.RECEIVE_SMS" />
    <uses-permission android:name="android.permission.SEND_SMS" />
    <uses-permission android:name="android.permission.WRITE_SMS" />
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
    <uses-permission android:name="android.permission.SYSTEM_OVERLAY_WINDOW" />
复制代码

 

这里贴出的是我整个项目的权限,世纪应该只需要SMS相关的权限,这里就不做区分了

下面贴出参考的相关博客,供大家全面了解Android短信机制: http://blog.csdn.net/maybe_windleave/article/details/17740345 http://blog.csdn.net/liuhe688/article/details/7020612 http://blog.csdn.net/subaohao/article/details/39368961 http://blog.csdn.net/mad1989/article/details/22426415/

 

 





标签:短信,String,Android4.4,SMS,public,Android,监听
From: https://www.cnblogs.com/yelanggu/p/17127562.html

相关文章

  • 【android】音视频开发一:绘制图片
    本文目标在Android平台绘制一张图片,使用至少3种不同的API,ImageView,SurfaceView,自定义View绘制准备:申请手机权限<!--添加权限--><uses-permissionandroid:n......
  • Android Studio创建模拟器
    创建方法:1.选择DeviceManager   2.选择Createdevice   3.选择一个你喜欢的  4.下载下来  5.AVD配置(一般默认就好)  6.完成啦,大功告......
  • android studio的activity中R.layout.activity中的R报错显红原因
    原因是:activity和对于的xml并没有相关联解决:法一:手动在AndroidManifest.xml中添加:<activity  android:name="........"  android:exported="fa......
  • 【android 】android 比较两个时间大小
    /***对比两个时间**@paramstartTime*@paramendTime*@return*/publicstaticbooleangetTimeCompareSize(Stringstar......
  • 【android】Android使用LAME将pcm文件转mp3文件
    Android使用LAME将pcm格式转mp3格式lame介绍:LAME是一款开源的MP3编码器,被认为是中高比特率和VBR的最佳MP3编码器,质量和速度方面的改进仍在继续,可能使LAME成为仍在积极开发......
  • 【android 】Android AudioRecord录制PCM以及转换为wav和mp3
    AndroidAudioRecord录制PCM以及转换为wav和mp31.录制pcmpcm介绍pcm是指音频裸数据是脉冲编码调制数据。描述一段PCM数据通常以下几个概念:量化格式(SampleFormat)又叫位深度......
  • 直播平台软件开发,Android 计时器,定时功能
    直播平台软件开发,Android计时器,定时功能 计时器工具类importandroid.annotation.SuppressLint;importandroid.os.Handler;importandroid.os.Message; importandro......
  • android 开发问题
    viewpager滑动时中间的一闪而过开发时遇到了这个问题,百思不得其解,后来查看源码/***Setthecurrentlyselectedpage.**@paramitemItemindex......
  • 【android】关于Android中将PCM转AMR的问题探讨
    因为项目中用到了阿里的语音识别技术,但是返回的是PCM原始数据,这里就需要将PCM转为AMR的音频格式,这里将其中遇到的问题记录下来,有需要的小伙伴们可以参考一下。这里的实现......
  • 【android 】Android PCM文件转WAV文件
    之前对android音频方面根本不了解,找了很多博客都没找到合适自己的,顺便看了很多代码,发现pcm基本上所有的音频格式都能转,我项目里面用到的就是wav的,所以这里贴一下pcm转wav......