Tôi muốn lấy tin nhắn SMS từ thiết bị và hiển thị chúng?
Tôi muốn lấy tin nhắn SMS từ thiết bị và hiển thị chúng?
Câu trả lời:
Sử dụng Trình giải quyết nội dung ( "nội dung: // sms / hộp thư đến" ) để đọc SMS trong hộp thư đến.
// public static final String INBOX = "content://sms/inbox";
// public static final String SENT = "content://sms/sent";
// public static final String DRAFT = "content://sms/draft";
Cursor cursor = getContentResolver().query(Uri.parse("content://sms/inbox"), null, null, null, null);
if (cursor.moveToFirst()) { // must check the result to prevent exception
do {
String msgData = "";
for(int idx=0;idx<cursor.getColumnCount();idx++)
{
msgData += " " + cursor.getColumnName(idx) + ":" + cursor.getString(idx);
}
// use msgData
} while (cursor.moveToNext());
} else {
// empty box, no SMS
}
Vui lòng thêm READ_SMS quyền .
Tôi hy vọng nó sẽ giúp :)
moveToFirst
như tôi đã làm.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
final String myPackageName = getPackageName();
if (!Telephony.Sms.getDefaultSmsPackage(this).equals(myPackageName)) {
Intent intent = new Intent(Telephony.Sms.Intents.ACTION_CHANGE_DEFAULT);
intent.putExtra(Telephony.Sms.Intents.EXTRA_PACKAGE_NAME, myPackageName);
startActivityForResult(intent, 1);
}else {
List<Sms> lst = getAllSms();
}
}else {
List<Sms> lst = getAllSms();
}
Đặt ứng dụng làm ứng dụng SMS mặc định
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 1) {
if (resultCode == RESULT_OK) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
final String myPackageName = getPackageName();
if (Telephony.Sms.getDefaultSmsPackage(mActivity).equals(myPackageName)) {
List<Sms> lst = getAllSms();
}
}
}
}
}
Chức năng nhận SMS
public List<Sms> getAllSms() {
List<Sms> lstSms = new ArrayList<Sms>();
Sms objSms = new Sms();
Uri message = Uri.parse("content://sms/");
ContentResolver cr = mActivity.getContentResolver();
Cursor c = cr.query(message, null, null, null, null);
mActivity.startManagingCursor(c);
int totalSMS = c.getCount();
if (c.moveToFirst()) {
for (int i = 0; i < totalSMS; i++) {
objSms = new Sms();
objSms.setId(c.getString(c.getColumnIndexOrThrow("_id")));
objSms.setAddress(c.getString(c
.getColumnIndexOrThrow("address")));
objSms.setMsg(c.getString(c.getColumnIndexOrThrow("body")));
objSms.setReadState(c.getString(c.getColumnIndex("read")));
objSms.setTime(c.getString(c.getColumnIndexOrThrow("date")));
if (c.getString(c.getColumnIndexOrThrow("type")).contains("1")) {
objSms.setFolderName("inbox");
} else {
objSms.setFolderName("sent");
}
lstSms.add(objSms);
c.moveToNext();
}
}
// else {
// throw new RuntimeException("You have no SMS");
// }
c.close();
return lstSms;
}
Lớp Sms bên dưới:
public class Sms{
private String _id;
private String _address;
private String _msg;
private String _readState; //"0" for have not read sms and "1" for have read sms
private String _time;
private String _folderName;
public String getId(){
return _id;
}
public String getAddress(){
return _address;
}
public String getMsg(){
return _msg;
}
public String getReadState(){
return _readState;
}
public String getTime(){
return _time;
}
public String getFolderName(){
return _folderName;
}
public void setId(String id){
_id = id;
}
public void setAddress(String address){
_address = address;
}
public void setMsg(String msg){
_msg = msg;
}
public void setReadState(String readState){
_readState = readState;
}
public void setTime(String time){
_time = time;
}
public void setFolderName(String folderName){
_folderName = folderName;
}
}
Đừng quên xác định quyền trong AndroidManifest.xml của bạn
<uses-permission android:name="android.permission.READ_SMS" />
String receiveDayTime = Functions.dateFromMilisec(Long.valueOf(c.getColumnIndexOrThrow("date")), "hh:mm a MMM dd, yyyy");
new SimpleDateFormat("hh:mm", Locale.US).format(new Date(Long.parseLong(_time)));
Điều này sẽ cung cấp cho bạn thời gian 24 giờ.
mActivity
không được xác định. Cái này là cái gì?
Đó là một quá trình tầm thường. Bạn có thể thấy một ví dụ hay trong mã nguồn SMSPopup
Kiểm tra các phương pháp sau:
SmsMmsMessage getSmsDetails(Context context, long ignoreThreadId, boolean unreadOnly)
long findMessageId(Context context, long threadId, long _timestamp, int messageType
void setMessageRead(Context context, long messageId, int messageType)
void deleteMessage(Context context, long messageId, long threadId, int messageType)
đây là phương pháp để đọc:
SmsMmsMessage getSmsDetails(Context context,
long ignoreThreadId, boolean unreadOnly)
{
String SMS_READ_COLUMN = "read";
String WHERE_CONDITION = unreadOnly ? SMS_READ_COLUMN + " = 0" : null;
String SORT_ORDER = "date DESC";
int count = 0;
// Log.v(WHERE_CONDITION);
if (ignoreThreadId > 0) {
// Log.v("Ignoring sms threadId = " + ignoreThreadId);
WHERE_CONDITION += " AND thread_id != " + ignoreThreadId;
}
Cursor cursor = context.getContentResolver().query(
SMS_INBOX_CONTENT_URI,
new String[] { "_id", "thread_id", "address", "person", "date", "body" },
WHERE_CONDITION,
null,
SORT_ORDER);
if (cursor != null) {
try {
count = cursor.getCount();
if (count > 0) {
cursor.moveToFirst();
// String[] columns = cursor.getColumnNames();
// for (int i=0; i<columns.length; i++) {
// Log.v("columns " + i + ": " + columns[i] + ": " + cursor.getString(i));
// }
long messageId = cursor.getLong(0);
long threadId = cursor.getLong(1);
String address = cursor.getString(2);
long contactId = cursor.getLong(3);
String contactId_string = String.valueOf(contactId);
long timestamp = cursor.getLong(4);
String body = cursor.getString(5);
if (!unreadOnly) {
count = 0;
}
SmsMmsMessage smsMessage = new SmsMmsMessage(context, address,
contactId_string, body, timestamp,
threadId, count, messageId, SmsMmsMessage.MESSAGE_TYPE_SMS);
return smsMessage;
}
} finally {
cursor.close();
}
}
return null;
}
Từ API 19 trở đi, bạn có thể sử dụng Lớp điện thoại cho điều đó; Vì các giá trị được bảo vệ sẽ không truy xuất thư trong mọi thiết bị vì nhà cung cấp nội dung Uri thay đổi từ thiết bị và nhà sản xuất.
public void getAllSms(Context context) {
ContentResolver cr = context.getContentResolver();
Cursor c = cr.query(Telephony.Sms.CONTENT_URI, null, null, null, null);
int totalSMS = 0;
if (c != null) {
totalSMS = c.getCount();
if (c.moveToFirst()) {
for (int j = 0; j < totalSMS; j++) {
String smsDate = c.getString(c.getColumnIndexOrThrow(Telephony.Sms.DATE));
String number = c.getString(c.getColumnIndexOrThrow(Telephony.Sms.ADDRESS));
String body = c.getString(c.getColumnIndexOrThrow(Telephony.Sms.BODY));
Date dateFormat= new Date(Long.valueOf(smsDate));
String type;
switch (Integer.parseInt(c.getString(c.getColumnIndexOrThrow(Telephony.Sms.TYPE)))) {
case Telephony.Sms.MESSAGE_TYPE_INBOX:
type = "inbox";
break;
case Telephony.Sms.MESSAGE_TYPE_SENT:
type = "sent";
break;
case Telephony.Sms.MESSAGE_TYPE_OUTBOX:
type = "outbox";
break;
default:
break;
}
c.moveToNext();
}
}
c.close();
} else {
Toast.makeText(this, "No message to show!", Toast.LENGTH_SHORT).show();
}
}
Bài đăng này hơi cũ, nhưng đây là một giải pháp dễ dàng khác để lấy dữ liệu liên quan đến SMS
nhà cung cấp nội dung trong Android:
Sử dụng lib này: https://github.com/EverythingMe/easy-content-providers
Nhận tất cả SMS
:
TelephonyProvider telephonyProvider = new TelephonyProvider(context);
List<Sms> smses = telephonyProvider.getSms(Filter.ALL).getList();
Mỗi Sms có tất cả các trường, vì vậy bạn có thể nhận được bất kỳ thông tin nào bạn cần:
địa chỉ, cơ thể, receiveDate, loại (INBOX, SENT, DRAFT, ..), threadId, ...
Gel tất cả MMS
:
List<Mms> mmses = telephonyProvider.getMms(Filter.ALL).getList();
Gel tất cả Thread
:
List<Thread> threads = telephonyProvider.getThreads().getList();
Gel tất cả Conversation
:
List<Conversation> conversations = telephonyProvider.getConversations().getList();
Nó hoạt động với List
hoặc Cursor
và có một ứng dụng mẫu để xem nó trông như thế nào và hoạt động.
Trên thực tế, có một hỗ trợ cho tất cả các nhà cung cấp nội dung Android như: Danh bạ, Nhật ký cuộc gọi, Lịch, ... Tài liệu đầy đủ với tất cả các tùy chọn: https://github.com/EverythingMe/easy-content-providers/wiki/Android- nhà cung cấp
Hy vọng nó cũng có ích :)
Bước 1: đầu tiên chúng ta phải thêm quyền trong tệp kê khai như
<uses-permission android:name="android.permission.RECEIVE_SMS" android:protectionLevel="signature" />
<uses-permission android:name="android.permission.READ_SMS" />
Bước 2: sau đó thêm lớp nhận dịch vụ sms để nhận sms
<receiver android:name="com.aquadeals.seller.services.SmsReceiver">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
</receiver>
Bước 3: Thêm quyền thời gian chạy
private boolean checkAndRequestPermissions()
{
int sms = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_SMS);
if (sms != PackageManager.PERMISSION_GRANTED)
{
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_SMS}, REQUEST_ID_MULTIPLE_PERMISSIONS);
return false;
}
return true;
}
Bước 4: Thêm lớp này trong ứng dụng của bạn và kiểm tra lớp Giao diện
public interface SmsListener {
public void messageReceived(String messageText);
}
SmsReceiver.java
public class SmsReceiver extends BroadcastReceiver {
private static SmsListener mListener;
public Pattern p = Pattern.compile("(|^)\\d{6}");
@Override
public void onReceive(Context context, Intent intent) {
Bundle data = intent.getExtras();
Object[] pdus = (Object[]) data.get("pdus");
for(int i=0;i<pdus.length;i++)
{
SmsMessage smsMessage = SmsMessage.createFromPdu((byte[]) pdus[i]);
String sender = smsMessage.getDisplayOriginatingAddress();
String phoneNumber = smsMessage.getDisplayOriginatingAddress();
String senderNum = phoneNumber ;
String messageBody = smsMessage.getMessageBody();
try
{
if(messageBody!=null){
Matcher m = p.matcher(messageBody);
if(m.find()) {
mListener.messageReceived(m.group(0)); }
else {}} }
catch(Exception e){} } }
public static void bindListener(SmsListener listener) {
mListener = listener; }}
Có rất nhiều câu trả lời đã có sẵn nhưng tôi nghĩ tất cả chúng đều thiếu một phần quan trọng của câu hỏi này. Trước khi đọc dữ liệu từ cơ sở dữ liệu nội bộ hoặc bảng của nó, chúng ta phải hiểu cách lưu trữ dữ liệu trong đó và sau đó chúng ta có thể tìm ra giải pháp cho câu hỏi trên đó là:
Làm cách nào tôi có thể đọc tin nhắn SMS từ thiết bị lập trình trong Android?
Vì vậy, trong bảng SMS của android giống như thế này
Biết, chúng tôi có thể chọn bất cứ điều gì chúng tôi muốn từ cơ sở dữ liệu. Trong trường hợp của chúng tôi, chúng tôi chỉ yêu cầu
id, địa chỉ và cơ thể
Trong trường hợp đọc SMS:
1.Ask cho phép
int REQUEST_PHONE_CALL = 1;
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_SMS) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.READ_SMS}, REQUEST_PHONE_CALL);
}
hoặc là
<uses-permission android:name="android.permission.READ_SMS" />
2.Bây giờ mã của bạn đi như thế này
// Create Inbox box URI
Uri inboxURI = Uri.parse("content://sms/inbox");
// List required columns
String[] reqCols = new String[]{"_id", "address", "body"};
// Get Content Resolver object, which will deal with Content Provider
ContentResolver cr = getContentResolver();
// Fetch Inbox SMS Message from Built-in Content Provider
Cursor c = cr.query(inboxURI, reqCols, null, null, null);
// Attached Cursor with adapter and display in listview
adapter = new SimpleCursorAdapter(this, R.layout.a1_row, c,
new String[]{"body", "address"}, new int[]{
R.id.A1_txt_Msg, R.id.A1_txt_Number});
lst.setAdapter(adapter);
Tôi hy vọng điều này sẽ hữu ích. Cảm ơn.
Dịch vụ Google Play có hai API bạn có thể sử dụng để hợp lý hóa quy trình xác minh dựa trên SMS
Cung cấp trải nghiệm người dùng hoàn toàn tự động, không yêu cầu người dùng nhập mã xác minh theo cách thủ công và không yêu cầu bất kỳ quyền ứng dụng bổ sung nào và nên được sử dụng khi có thể. Tuy nhiên, nó yêu cầu bạn đặt mã băm tùy chỉnh trong phần thân thông báo, do đó bạn cũng phải có quyền kiểm soát phía máy chủ .
Yêu cầu xác minh SMS trong ứng dụng Android
Thực hiện xác minh SMS trên máy chủ
Không yêu cầu mã băm tùy chỉnh, tuy nhiên yêu cầu người dùng phê duyệt yêu cầu của ứng dụng của bạn để truy cập thư chứa mã xác minh. Để giảm thiểu cơ hội phát thông báo sai cho người dùng, SMS User Consent
sẽ lọc ra các tin nhắn từ người gửi trong danh sách Liên hệ của người dùng.
The SMS User Consent API
là một phần của Dịch vụ Google Play. Để sử dụng, bạn sẽ cần ít nhất phiên bản 17.0.0
của các thư viện này:
implementation "com.google.android.gms:play-services-auth:17.0.0"
implementation "com.google.android.gms:play-services-auth-api-phone:17.1.0"
Bước 1: Bắt đầu nghe tin nhắn SMS
Sự đồng ý của người dùng SMS sẽ lắng nghe các tin nhắn SMS đến có chứa mã một lần trong tối đa năm phút. Nó sẽ không nhìn vào bất kỳ tin nhắn nào được gửi trước khi nó bắt đầu. Nếu bạn biết số điện thoại sẽ gửi mã một lần, bạn có thể chỉ định senderPhoneNumber
hoặc nếu bạn không null
khớp với bất kỳ số nào.
smsRetriever.startSmsUserConsent(senderPhoneNumber /* or null */)
Bước 2: Yêu cầu đồng ý đọc tin nhắn
Khi ứng dụng của bạn nhận được tin nhắn chứa mã một lần, nó sẽ được thông báo bằng một chương trình phát sóng. Tại thời điểm này, bạn không có sự đồng ý để đọc tin nhắn - thay vào đó bạn được cung cấp Intent
rằng bạn có thể bắt đầu nhắc nhở người dùng đồng ý. Trong của bạn BroadcastReceiver
, bạn hiển thị lời nhắc bằng cách sử dụng Intent
trong extras
. Khi bạn bắt đầu ý định đó, nó sẽ nhắc người dùng cho phép đọc một tin nhắn. Họ sẽ được hiển thị toàn bộ văn bản mà họ sẽ chia sẻ với ứng dụng của bạn.
val consentIntent = extras.getParcelable<Intent>(SmsRetriever.EXTRA_CONSENT_INTENT)
startActivityForResult(consentIntent, SMS_CONSENT_REQUEST)
Bước 3: Phân tích mã một lần và hoàn tất Xác minh SMS
Khi người dùng nhấp “Allow”
- đây là lúc để thực sự đọc tin nhắn! Bên trong onActivityResult
bạn có thể nhận được toàn bộ tin nhắn SMS từ dữ liệu:
val message = data.getStringExtra(SmsRetriever.EXTRA_SMS_MESSAGE)
Sau đó, bạn phân tích tin nhắn SMS và chuyển mã một lần đến phần phụ trợ của bạn!
4-10 digit alphanumeric code containing at least one number
Bạn có thể giải thích điều đó có nghĩa là gì? Có nghĩa là độ dài của toàn bộ tin nhắn phải là 4-10 ký tự của mã sms?
String WHERE_CONDITION = unreadOnly ? SMS_READ_COLUMN + " = 0" : null;
Thay đổi bởi:
String WHERE_CONDITION = unreadOnly ? SMS_READ_COLUMN + " = 0 " : SMS_READ_COLUMN + " = 1 ";
Mã Kotlin để đọc SMS:
1- Thêm quyền này vào AndroidManifest.xml:
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
2-Tạo một lớp BroadCastreceiver:
package utils.broadcastreceivers
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.telephony.SmsMessage
import android.util.Log
class MySMSBroadCastReceiver : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
var body = ""
val bundle = intent?.extras
val pdusArr = bundle!!.get("pdus") as Array<Any>
var messages: Array<SmsMessage?> = arrayOfNulls(pdusArr.size)
// if SMSis Long and contain more than 1 Message we'll read all of them
for (i in pdusArr.indices) {
messages[i] = SmsMessage.createFromPdu(pdusArr[i] as ByteArray)
}
var MobileNumber: String? = messages[0]?.originatingAddress
Log.i(TAG, "MobileNumber =$MobileNumber")
val bodyText = StringBuilder()
for (i in messages.indices) {
bodyText.append(messages[i]?.messageBody)
}
body = bodyText.toString()
if (body.isNotEmpty()){
// Do something, save SMS in DB or variable , static object or ....
Log.i("Inside Receiver :" , "body =$body")
}
}
}
3-Nhận quyền SMS nếu Android 6 trở lên:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M &&
ActivityCompat.checkSelfPermission(context!!,
Manifest.permission.RECEIVE_SMS
) != PackageManager.PERMISSION_GRANTED
) { // Needs permission
requestPermissions(arrayOf(Manifest.permission.RECEIVE_SMS),
PERMISSIONS_REQUEST_READ_SMS
)
} else { // Permission has already been granted
}
4- Thêm mã yêu cầu này vào Hoạt động hoặc đoạn:
companion object {
const val PERMISSIONS_REQUEST_READ_SMS = 100
}
5- Ghi đè Kiểm tra permisstion Yêu cầu kết quả thú vị:
override fun onRequestPermissionsResult(
requestCode: Int, permissions: Array<out String>,
grantResults: IntArray
) {
when (requestCode) {
PERMISSIONS_REQUEST_READ_SMS -> {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Log.i("BroadCastReceiver", "PERMISSIONS_REQUEST_READ_SMS Granted")
} else {
// toast("Permission must be granted ")
}
}
}
}
Chức năng dễ nhất
Để đọc sms tôi đã viết một hàm trả về một đối tượng Hội thoại:
class Conversation(val number: String, val message: List<Message>)
class Message(val number: String, val body: String, val date: Date)
fun getSmsConversation(context: Context, number: String? = null, completion: (conversations: List<Conversation>?) -> Unit) {
val cursor = context.contentResolver.query(Telephony.Sms.CONTENT_URI, null, null, null, null)
val numbers = ArrayList<String>()
val messages = ArrayList<Message>()
var results = ArrayList<Conversation>()
while (cursor != null && cursor.moveToNext()) {
val smsDate = cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Sms.DATE))
val number = cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Sms.ADDRESS))
val body = cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Sms.BODY))
numbers.add(number)
messages.add(Message(number, body, Date(smsDate.toLong())))
}
cursor?.close()
numbers.forEach { number ->
if (results.find { it.number == number } == null) {
val msg = messages.filter { it.number == number }
results.add(Conversation(number = number, message = msg))
}
}
if (number != null) {
results = results.filter { it.number == number } as ArrayList<Conversation>
}
completion(results)
}
Sử dụng:
getSmsConversation(this){ conversations ->
conversations.forEach { conversation ->
println("Number: ${conversation.number}")
println("Message One: ${conversation.message[0].body}")
println("Message Two: ${conversation.message[1].body}")
}
}
Hoặc chỉ nhận được cuộc trò chuyện của số cụ thể:
getSmsConversation(this, "+33666494128"){ conversations ->
conversations.forEach { conversation ->
println("Number: ${conversation.number}")
println("Message One: ${conversation.message[0].body}")
println("Message Two: ${conversation.message[1].body}")
}
}