Android关于短信广播及权限的研究
来源:互联网 发布:sql 合计多行数据 编辑:程序博客网 时间:2024/06/03 08:01
- 短信权限
- 自动填写短信验证码
- 动态注册广播
- 静态注册广播
- 短信广播
- 取消注册广播
- 获取手机短信收件箱列表
- 运行时权限
- 获取本机号码
短信权限
<uses-permission android:name="android.permission.SEND_SMS"/> <uses-permission android:name="android.permission.READ_SMS"/> <uses-permission android:name="android.permission.RECEIVE_SMS"/>
自动填写短信验证码
以下代码测试环境为:
Android模拟器:5.0(因为模拟器发送短信方便快捷)
Android Studio:2.2.2
代码主要借鉴于这里
注册短信广播分为动态注册(即Java代码中register)和静态注册(即配置文件Manifest.xml中配置receiver),效果一样。
动态注册广播
private void registSmsReciver() { IntentFilter filter = new IntentFilter(); filter.addAction("android.provider.Telephony.SMS_RECEIVED"); // 设置优先级 不然监听不到短信 filter.setPriority(1000); Snackbar.make(editText,"注册短信广播", Snackbar.LENGTH_LONG).show(); Log.d("TAG", "registSmsReciver "); registerReceiver(smsReciver, filter); }
静态注册广播
<receiver android:name=".SmsReciver"> <intent-filter android:priority="1000"> <action android:name="android.provider.Telephony.SMS_RECEIVED"/> </intent-filter> </receiver>
短信广播
public class SmsReciver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Object[] objs = (Object[]) intent.getExtras().get("pdus"); for (Object obj : objs) { byte[] pdu = (byte[]) obj; SmsMessage sms = SmsMessage.createFromPdu(pdu); // 短信的内容 String message = sms.getMessageBody(); Log.d("TAG", "message=" + message); // 短信的发送方 String from = sms.getOriginatingAddress(); Log.d("TAG", "from=" + from); analysisVerify(message); } } /** * 解析短信并且回写,主要是提取出数字验证码并显示在输入框上 * * @param message */ private void analysisVerify(String message) { char[] msgs = message.toCharArray(); StringBuffer sb = new StringBuffer(); for (int i = 0; i < msgs.length; i++) { if ('0' <= msgs[i] && msgs[i] <= '9') { sb.append(msgs[i]); } } editText.setText(sb.toString()); } }
取消注册广播
@Override protected void onDestroy() { super.onDestroy(); // 取消短信广播注册 if (smsReciver != null) { unregisterReceiver(smsReciver); smsReciver = null; } }
获取手机短信收件箱列表
以下代码从这里搬运
public String getSmsInPhone() { final String SMS_URI_ALL = "content://sms/"; final String SMS_URI_INBOX = "content://sms/inbox"; final String SMS_URI_SEND = "content://sms/sent"; final String SMS_URI_DRAFT = "content://sms/draft"; final String SMS_URI_OUTBOX = "content://sms/outbox"; final String SMS_URI_FAILED = "content://sms/failed"; final String SMS_URI_QUEUED = "content://sms/queued"; StringBuilder smsBuilder = new StringBuilder(); try { Uri uri = Uri.parse(SMS_URI_INBOX); String[] projection = new String[] { "_id", "address", "person", "body", "date", "type" }; Cursor cur = getContentResolver().query(uri, projection, null, null, "date desc"); // 获取手机内部短信 if (cur.moveToFirst()) { int index_Address = cur.getColumnIndex("address"); int index_Person = cur.getColumnIndex("person"); int index_Body = cur.getColumnIndex("body"); int index_Date = cur.getColumnIndex("date"); int index_Type = cur.getColumnIndex("type"); do { String strAddress = cur.getString(index_Address); int intPerson = cur.getInt(index_Person); String strbody = cur.getString(index_Body); long longDate = cur.getLong(index_Date); int intType = cur.getInt(index_Type); SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); Date d = new Date(longDate); String strDate = dateFormat.format(d); String strType = ""; if (intType == 1) { strType = "接收"; } else if (intType == 2) { strType = "发送"; } else { strType = "null"; } smsBuilder.append("[ "); smsBuilder.append(strAddress + ", "); smsBuilder.append(intPerson + ", "); smsBuilder.append(strbody + ", "); smsBuilder.append(strDate + ", "); smsBuilder.append(strType); smsBuilder.append(" ]\n\n"); } while (cur.moveToNext()); if (!cur.isClosed()) { cur.close(); cur = null; } } else { smsBuilder.append("no result!"); } // end if smsBuilder.append("getSmsInPhone has executed!"); } catch (SQLiteException ex) { LogUtil.d("TAG", ex.getMessage()); } return smsBuilder.toString(); }
运行时权限
google在6.0以后加入了运行时权限,就是说有些危险权限是在触发这些相关操作时会弹出对话框让用户来选择是否允许,比如打电话或者发短信这类涉及到资费的权限等。
危险权限包括以下几大分类:
1,日历:读取,写入 2,摄像头 3,联系人:读取,写入,获取帐户 4,位置 5,录音 6,手机状态:拨打电话,读取通话记录等 7,传感器 8,短信 9,存储卡读写
涉及到以上这些权限时,开发者就只能去改代码了,如果不改的话,相关功能则在6.0以后就无法使用了。。。
至于怎么改,以下代码来源于第一行代码第二版,郭神在12.27号的直播中又提供了三种更好的方法,大家可以参考直播视频回放
首先判断用户是否已经对该权限授权过,没有则弹框提示,有的话直接进行操作
if (ContextCompat.checkSelfPermission(SmsCodeActivity.this, android.Manifest.permission.RECEIVE_SMS) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(SmsCodeActivity.this, new String[]{Manifest.permission.RECEIVE_SMS}, 1); } else { // 原来的敏感操作代码:发短信或者收短信 }
然后就是对弹框操作的回调
@Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); switch (requestCode) { case 1: if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // 原来的敏感操作代码:发短信或者收短信 } else { Snackbar.make(editText, "你拒绝了该权限", Snackbar.LENGTH_LONG).show(); } break; } }
获取本机号码
通用方法一,此方法的前提是相应运营商的sim卡上必须存着号码才行,否则只能取空:
TelephonyManager tm =(TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE); String number = tm.getLine1Number(); String simSerialNumber = tm.getSimSerialNumber(); String imei = tm.getDeviceId(); Log.i("TAG","n"+number+"s"+simSerialNumber+"i"+imei);
不靠谱方法二:可通过facebook api或者whatsapp api等类似的api可以获取
不靠谱方法三:偷偷发短信给10086或者10010然后拦截短信截取其中的本机号码
总之一句话,为了安全起见,开发者是无法正常的获取用户的本机号码的。
0 0
- Android关于短信广播及权限的研究
- android--广播及短信拦截
- android关于监听短信的广播获取内容
- Android--广播的研究
- Android发送短信、打电话、发送邮件的程序集合&&广播权限
- Android中短信的广播接收问题
- Android广播接收短信的简单实现
- android虚拟机接收短信的广播
- Android中短信的接受广播和短信的解析
- android短信与广播
- Android手机获取通讯录联系人信息及短信广播实现
- 关于Android发送短信字数问题的分析及解决方法
- 短信的广播
- 接收短信的广播
- 短信的广播接收者
- 关于小米手机使用广播无法接受短信的问题
- android之发送短信的方法研究
- android之发送短信的方法研究
- python处理情感预测(一)
- anroid Handler机制详解
- 完美实现STM32单总线挂多个DS18B20
- ssm框架学习---mybatis单独使用各个文件编写
- ibatis 批量处理
- Android关于短信广播及权限的研究
- 摸爬滚打DirectX11_day05——三维世界中的四大变换
- 最长递增子序列
- APP 基本框架设计
- 谈谈敏捷开发
- 安装nginx 需要检查的依赖库
- 运算放大器的分析
- CM12.0 CMUpdater解读
- POJ 2723Get Luffy Out 2-SAT&&二分搜索