Ich möchte die SMS-Nachrichten vom Gerät abrufen und anzeigen.
Ich möchte die SMS-Nachrichten vom Gerät abrufen und anzeigen.
Antworten:
Verwenden Sie Content Resolver ( "content: // sms / inbox" ), um SMS zu lesen, die sich im Posteingang befinden.
// 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
}
Bitte fügen Sie die READ_SMS- Berechtigung hinzu.
Ich hoffe, es hilft :)
moveToFirst
wie ich.
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();
}
Legen Sie die App als Standard-SMS-App fest
@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();
}
}
}
}
}
Funktion zum Abrufen von 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;
}
SMS-Klasse ist unten:
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;
}
}
Vergessen Sie nicht, die Berechtigung in Ihrer AndroidManifest.xml zu definieren
<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)));
Dies gibt Ihnen 24 Stunden Zeit.
mActivity
ist nicht definiert. Was ist das?
Es ist ein trivialer Prozess. Sie können ein gutes Beispiel im Quellcode SMSPopup sehen
Untersuchen Sie die folgenden Methoden:
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)
Dies ist die Methode zum Lesen:
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;
}
Ab API 19 können Sie dafür die Telefonieklasse verwenden; Da hartgesottene Werte nicht auf allen Geräten Nachrichten abrufen, ändert sich der Inhaltsanbieter Uri von Geräten und Herstellern.
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();
}
}
Dieser Beitrag ist etwas alt, aber hier ist eine weitere einfache Lösung, um Daten zum SMS
Inhaltsanbieter in Android abzurufen:
Verwenden Sie diese Bibliothek: https://github.com/EverythingMe/easy-content-providers
Holen Sie sich alles SMS
:
TelephonyProvider telephonyProvider = new TelephonyProvider(context);
List<Sms> smses = telephonyProvider.getSms(Filter.ALL).getList();
Jede SMS hat alle Felder, so dass Sie alle Informationen erhalten können, die Sie benötigen:
Adresse, Text, Empfangsdatum, Typ (INBOX, SENT, DRAFT, ..), threadId, ...
Gel alle MMS
:
List<Mms> mmses = telephonyProvider.getMms(Filter.ALL).getList();
Gel alle Thread
:
List<Thread> threads = telephonyProvider.getThreads().getList();
Gel alle Conversation
:
List<Conversation> conversations = telephonyProvider.getConversations().getList();
Es funktioniert mit List
oderCursor
und es gibt eine Beispiel-App, um zu sehen, wie es aussieht und funktioniert.
In der Tat gibt es eine Unterstützung für alle Android-Inhaltsanbieter wie: Kontakte, Anrufprotokolle, Kalender, ... Vollständiges Dokument mit allen Optionen: https://github.com/EverythingMe/easy-content-providers/wiki/Android- Anbieter
Hoffe es hat auch geholfen :)
Schritt 1: Zuerst müssen wir Berechtigungen in Manifest-Dateien wie hinzufügen
<uses-permission android:name="android.permission.RECEIVE_SMS" android:protectionLevel="signature" />
<uses-permission android:name="android.permission.READ_SMS" />
Schritt 2: Fügen Sie dann die Service-SMS-Empfängerklasse zum Empfangen von SMS hinzu
<receiver android:name="com.aquadeals.seller.services.SmsReceiver">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
</receiver>
Schritt 3: Laufzeitberechtigung hinzufügen
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;
}
Schritt 4: Fügen Sie diese Klassen in Ihre App ein und testen Sie die Interface-Klasse
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; }}
Es gibt bereits viele Antworten, aber ich denke, allen fehlt ein wichtiger Teil dieser Frage. Bevor wir Daten aus einer internen Datenbank oder ihrer Tabelle lesen, müssen wir verstehen, wie Daten darin gespeichert sind, und dann können wir die Lösung der obigen Frage finden:
Wie kann ich in Android programmgesteuert SMS-Nachrichten vom Gerät lesen?
Also, in Android SMS Tabelle sieht so aus
Wissen Sie, wir können aus der Datenbank auswählen, was wir wollen. In unserem Fall haben wir nur benötigt
ID, Adresse und Körper
Beim Lesen von SMS:
1. Fragen Sie nach Berechtigungen
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);
}
oder
<uses-permission android:name="android.permission.READ_SMS" />
2. Jetzt geht Ihr Code so
// 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);
Ich hoffe, dass dieser hilfreich sein wird. Vielen Dank.
Die Google Play-Dienste verfügen über zwei APIs, mit denen Sie den SMS-basierten Überprüfungsprozess optimieren können
Bietet eine vollautomatische Benutzererfahrung, ohne dass der Benutzer manuell Bestätigungscodes eingeben muss und ohne zusätzliche App-Berechtigungen, und sollte nach Möglichkeit verwendet werden. Es ist jedoch erforderlich, dass Sie einen benutzerdefinierten Hash-Code in den Nachrichtentext einfügen, sodass Sie auch die Kontrolle über die Serverseite haben müssen .
Fordern Sie eine SMS-Bestätigung in einer Android-App an
Führen Sie eine SMS-Überprüfung auf einem Server durch
Erfordert keinen benutzerdefinierten Hash-Code. Der Benutzer muss jedoch die Anforderung Ihrer App genehmigen, auf die Nachricht mit dem Bestätigungscode zuzugreifen. Um die Wahrscheinlichkeit zu minimieren, dass dem Benutzer die falsche Nachricht angezeigt SMS User Consent
wird, werden Nachrichten von Absendern in der Kontaktliste des Benutzers herausgefiltert.
The SMS User Consent API
ist Teil von Google Play Services. Um es zu verwenden, benötigen Sie mindestens eine Version 17.0.0
dieser Bibliotheken:
implementation "com.google.android.gms:play-services-auth:17.0.0"
implementation "com.google.android.gms:play-services-auth-api-phone:17.1.0"
Schritt 1: Hören Sie auf SMS-Nachrichten
Die Zustimmung des SMS-Benutzers wartet bis zu fünf Minuten lang auf eingehende SMS-Nachrichten, die einen Einmalcode enthalten. Es werden keine Nachrichten angezeigt, die vor dem Start gesendet wurden. Wenn Sie die Telefonnummer kennen, die den Einmalcode sendet, können Sie die angeben senderPhoneNumber
, oder wenn Sie null
mit keiner Nummer übereinstimmen.
smsRetriever.startSmsUserConsent(senderPhoneNumber /* or null */)
Schritt 2: Fordern Sie die Zustimmung zum Lesen einer Nachricht an
Sobald Ihre App eine Nachricht mit einem Einmalcode erhält, wird diese per Broadcast benachrichtigt. Zu diesem Zeitpunkt haben Sie keine Einwilligung zum Lesen der Nachricht. Stattdessen erhalten Sie eine Einwilligung, mit der Sie Intent
den Benutzer zur Einwilligung auffordern können. In Ihrem BroadcastReceiver
zeigen Sie die Eingabeaufforderung mit der Intent
in der extras
. Wenn Sie diese Absicht starten, werden Sie aufgefordert, eine einzelne Nachricht zu lesen. Ihnen wird der gesamte Text angezeigt, den sie mit Ihrer App teilen.
val consentIntent = extras.getParcelable<Intent>(SmsRetriever.EXTRA_CONSENT_INTENT)
startActivityForResult(consentIntent, SMS_CONSENT_REQUEST)
Schritt 3: Analysieren Sie den Einmalcode und schließen Sie die SMS-Überprüfung ab
Wenn der Benutzer klickt, ist “Allow”
es Zeit, die Nachricht tatsächlich zu lesen! Innerhalb von onActivityResult
können Sie den vollständigen Text der SMS-Nachricht aus den Daten erhalten:
val message = data.getStringExtra(SmsRetriever.EXTRA_SMS_MESSAGE)
Sie analysieren dann die SMS-Nachricht und geben den Einmalcode an Ihr Backend weiter!
4-10 digit alphanumeric code containing at least one number
Können Sie erklären, was das bedeutet? Bedeutet dies, dass die Länge der gesamten Nachricht 4-10 Zeichen nur des SMS-Codes betragen sollte?
String WHERE_CONDITION = unreadOnly ? SMS_READ_COLUMN + " = 0" : null;
verändert von:
String WHERE_CONDITION = unreadOnly ? SMS_READ_COLUMN + " = 0 " : SMS_READ_COLUMN + " = 1 ";
Kotlin Code zum Lesen von SMS:
1- Fügen Sie diese Berechtigung zu AndroidManifest.xml hinzu:
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
2-Erstellen Sie eine BroadCastreceiver-Klasse:
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-SMS-Berechtigung ab Android 6 abrufen:
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- Fügen Sie diesen Anforderungscode zu Aktivität oder Fragment hinzu:
companion object {
const val PERMISSIONS_REQUEST_READ_SMS = 100
}
5- Override Check permisstion Ergebnis anfordern Spaß:
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 ")
}
}
}
}
Die einfachste Funktion
Um die SMS zu lesen, habe ich eine Funktion geschrieben, die ein Conversation-Objekt zurückgibt:
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)
}
Verwenden von:
getSmsConversation(this){ conversations ->
conversations.forEach { conversation ->
println("Number: ${conversation.number}")
println("Message One: ${conversation.message[0].body}")
println("Message Two: ${conversation.message[1].body}")
}
}
Oder erhalten Sie nur ein Gespräch mit einer bestimmten Nummer:
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}")
}
}