短信權(quán)限
<uses-permission android:name="android.permission.SEND_SMS"/>
<uses-permission android:name="android.permission.READ_SMS"/>
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
自動填寫短信驗證碼
[圖片上傳中...(image-f5bada-1527212844994-2)]
以下代碼測試環(huán)境為:
Android模擬器:5.0(因為模擬器發(fā)送短信方便快捷)
Android Studio:2.2.2
代碼主要借鑒于這里
注冊短信廣播分為動態(tài)注冊(即Java代碼中register)和靜態(tài)注冊(即配置文件Manifest.xml中配置receiver)兼雄,效果一樣哩掺。
動態(tài)注冊廣播
private void registSmsReciver() {
IntentFilter filter = new IntentFilter();
filter.addAction("android.provider.Telephony.SMS_RECEIVED");
// 設(shè)置優(yōu)先級 不然監(jiān)聽不到短信
filter.setPriority(1000);
Snackbar.make(editText,"注冊短信廣播", Snackbar.LENGTH_LONG).show();
Log.d("TAG", "registSmsReciver ");
registerReceiver(smsReciver, filter);
}
靜態(tài)注冊廣播
<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);
// 短信的內(nèi)容
String message = sms.getMessageBody();
Log.d("TAG", "message=" + message);
// 短信的發(fā)送方
String from = sms.getOriginatingAddress();
Log.d("TAG", "from=" + from);
analysisVerify(message);
}
}
/**
* 解析短信并且回寫财剖,主要是提取出數(shù)字驗證碼并顯示在輸入框上
*
* @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"); // 獲取手機內(nèi)部短信
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 = "發(fā)送";
} 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();
}
運行時權(quán)限
google在6.0以后加入了運行時權(quán)限米酬,就是說有些危險權(quán)限是在觸發(fā)這些相關(guān)操作時會彈出對話框讓用戶來選擇是否允許喻喳,比如打電話或者發(fā)短信這類涉及到資費的權(quán)限等蠕蚜。
危險權(quán)限包括以下幾大分類:
1吉嫩,日歷:讀取其掂,寫入
2,攝像頭
3扁耐,聯(lián)系人:讀取暇检,寫入,獲取帳戶
4婉称,位置
5块仆,錄音
6,手機狀態(tài):撥打電話王暗,讀取通話記錄等
7悔据,傳感器
8,短信
9俗壹,存儲卡讀寫
涉及到以上這些權(quán)限時科汗,開發(fā)者就只能去改代碼了,如果不改的話绷雏,相關(guān)功能則在6.0以后就無法使用了头滔。。涎显。
至于怎么改坤检,以下代碼來源于第一行代碼第二版,郭神在12.27號的直播中又提供了三種更好的方法期吓,大家可以參考直播視頻回放
首先判斷用戶是否已經(jīng)對該權(quán)限授權(quán)過缀蹄,沒有則彈框提示,有的話直接進行操作
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 {
// 原來的敏感操作代碼:發(fā)短信或者收短信
}
然后就是對彈框操作的回調(diào)
@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) {
// 原來的敏感操作代碼:發(fā)短信或者收短信
} else {
Snackbar.make(editText, "你拒絕了該權(quán)限", Snackbar.LENGTH_LONG).show();
}
break;
}
}
獲取本機號碼
通用方法一膘婶,此方法的前提是相應(yīng)運營商的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可以獲取
不靠譜方法三:偷偷發(fā)短信給10086或者10010然后攔截短信截取其中的本機號碼
總之一句話,為了安全起見悬襟,開發(fā)者是無法正常的獲取用戶的本機號碼的衅码。