Ich möchte die SMS-Nachrichten vom Gerät abrufen und anzeigen?
Wie kann ich SMS-Nachrichten vom Gerät programmgesteuert in Android lesen?
Suryavel TR
Verwenden Sie den Inhaltsauflöser (“inhalt://sms/posteingang”), 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 hinzufügen READ_SMS Erlaubnis.
Ich hoffe, es hilft 🙂
-
Danke! Sie haben “getColumnName” falsch geschrieben, ansonsten funktioniert es wie ein Zauber. Oh, und wenn jemand dies verwendet, vergessen Sie nicht, die Berechtigung android.permission.READ_SMS hinzuzufügen.
– qwerty
28. März 2012 um 18:40 Uhr
-
Verwendet dies auch die undokumentierte API, die @CommonsWare in seinem Kommentar zur akzeptierten Antwort angegeben hat?
– Krishnabhadra
20. August 2012 um 5:07 Uhr
-
Aufmerksamkeit! Nicht verpassen
moveToFirst
wie ich es tat.– Alexandr Priymak
23. April 2013 um 14:38 Uhr
-
@ Krishnabhadra Ja. Es verwendet den undokumentierten Inhaltsanbieter „content://sms/inbox“.
– pm_labs
2. Mai 2013 um 11:07 Uhr
-
Frage: Gewährt diese Verwendung dem Entwickler Zugriff, um jede einzelne Nachricht im SMS-Posteingang zu lesen?
– Aditya MP
13. Dezember 2015 um 5:49 Uhr
Atif Mahmud
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();
}
App als Standard-SMS-App festlegen
@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 Empfangen 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" />
-
Das ist ein nettes Stück Code. Nur eine Sache, die Zeit wird in Millisekunden erhalten. Ich denke, es wird besser sein, es in einem für Menschen lesbaren Format zu erstellen
String receiveDayTime = Functions.dateFromMilisec(Long.valueOf(c.getColumnIndexOrThrow("date")), "hh:mm a MMM dd, yyyy");
– Bibaswann Bandyopadhyay
13. September 2015 um 19:42 Uhr
-
Was ist der Zweck, alles mit Getter und Setter zu machen, ich verstehe wirklich nicht, warum nicht einfach ein Assoc-Array oder eine Klasse verwendet wird, auf deren Elemente direkt zugegriffen wird
– michnovka
25. Oktober 2015 um 18:54 Uhr
-
@TomasNavara: Überprüfen Sie diesen Code, um die Verwendung von Getter und Setter zu verstehen. pastebin.com/Nh8YXtyJ
– Fehler passieren
24. August 2016 um 11:18 Uhr
-
@BibaswannBandyopadhyay Wenn Sie nichts außer Android-Bibliotheken und Java-Bibliotheken verwenden möchten.
new SimpleDateFormat("hh:mm", Locale.US).format(new Date(Long.parseLong(_time)));
Dadurch erhalten Sie 24 Stunden Zeit.– Chris-Jr
11. Februar 2017 um 14:13 Uhr
-
mActivity
ist nicht definiert. Was ist das?– ddrei
15. November 2017 um 6:39 Uhr
Ömer
Es ist ein trivialer Vorgang. Sie können ein gutes Beispiel im Quellcode sehen SMSPopup
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;
}
-
Dies ist nicht Teil des Android SDK. Dieser Code geht fälschlicherweise davon aus, dass alle Geräte diesen undokumentierten und nicht unterstützten Inhaltsanbieter unterstützen. Google hat ausdrücklich darauf hingewiesen, dass es keine gute Idee ist, sich darauf zu verlassen: android-developers.blogspot.com/2010/05/…
– CommonsWare
15. Dezember 2010 um 16:08 Uhr
-
@Janusz: Es gibt kein dokumentiertes und unterstütztes Mittel, das über alle SMS-Clients auf allen Geräten funktioniert.
– CommonsWare
27. Dezember 2010 um 15:07 Uhr
-
@CommonsWare, das ist traurig zu hören. Muss dann wohl mit dieser API leben.
– Janusz
28. Dezember 2010 um 10:09 Uhr
-
@Omer Irgendeine Idee, wie Sie die Anzahl der SMS-Nachrichten pro Kontakt zählen würden?
– Benutzer868935
21. Mai 2012 um 10:36 Uhr
-
Der Code ist umgezogen. Die Suche nach SmsPopupUtils.java hat mir einen neuen Link dazu im Google-Code gebracht. Falls sie es erneut verschieben oder ganz einstellen, hier ist ein Backup-Link – pastebin.com/iPt7MLyM
– KalEl
3. Juni 2012 um 12:06 Uhr
Manoj Perumarath
Ab API 19 können Sie dafür die Telefonieklasse verwenden; Da Hardcored-Werte Nachrichten nicht auf allen Geräten abrufen, da der Inhaltsanbieter Uri von Geräten und Herstellern wechselt.
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 ein bisschen alt, aber hier ist eine weitere einfache Lösung, um Daten zu erhalten SMS
Inhaltsanbieter in Android:
Verwenden Sie diese Bibliothek: https://github.com/EverythingMe/easy-content-providers
-
Nimm alle
SMS
:TelephonyProvider telephonyProvider = new TelephonyProvider(context); List<Sms> smses = telephonyProvider.getSms(Filter.ALL).getList();
Jeder SMS hat alle Felder, sodass Sie alle Informationen erhalten, die Sie benötigen:
Adresse, Text, Empfangsdatum, Typ (INBOX, GESENDET, ENTWURF, ..), threadId, … -
Alles gelieren
MMS
:List<Mms> mmses = telephonyProvider.getMms(Filter.ALL).getList();
-
Alles gelieren
Thread
:List<Thread> threads = telephonyProvider.getThreads().getList();
-
Alles gelieren
Conversation
:List<Conversation> conversations = telephonyProvider.getConversations().getList();
Es funktioniert mit List
oder Cursor
und es gibt eine Beispiel-App, um zu sehen, wie sie aussieht und funktioniert.
Tatsächlich gibt es eine Unterstützung für alle Android-Inhaltsanbieter wie: Kontakte, Anruflisten, Kalender, …
Vollständiges Dokument mit allen Optionen: https://github.com/EverythingMe/easy-content-providers/wiki/Android-providers
Hoffe es hat auch geholfen 🙂
-
Quellcode und Beispiele auf dem Github sind sehr nützlich. Dies ist eine gute Hülle/Fassade für die meisten gängigen Anbieter. Danke.
– m3nda
17. August 2017 um 22:18 Uhr
Es sind bereits mehrere Antworten verfügbar, 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 werden, und nur dann können wir die Lösung für die obige Frage finden, die lautet:
Wie kann ich SMS-Nachrichten vom Gerät programmgesteuert in Android lesen?
In Android sieht die SMS-Tabelle so aus
Jetzt können Sie aus der Datenbank auswählen, was Sie wollen. In unserem Fall brauchen wir nur
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, das wird hilfreich sein. Danke.
-
Quellcode und Beispiele auf dem Github sind sehr nützlich. Dies ist eine gute Hülle/Fassade für die meisten gängigen Anbieter. Danke.
– m3nda
17. August 2017 um 22:18 Uhr
Nima
Schritt 1: Zuerst müssen wir Berechtigungen in der Manifestdatei 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 Ihrer App hinzu und testen Sie sie
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));
}
}
}
catch(Exception e){}
}
}
public static void bindListener(SmsListener listener) {
mListener = listener;
}
}
-
Was macht das Muster?
– Mark Buikema
19. Oktober 2016 um 9:14 Uhr
-
Nun … ist das (“com.aquadeals.seller.services.SmsReceiver”) der allgemeine Dienstname?
– m3nda
17. August 2017 um 22:21 Uhr
-
Ja, das ist kein Dienstname, das ist der SmsReceiver-Klassenpfad in meiner App
– Venkatesh
18. August 2017 um 3:09 Uhr
-
Warum eine Genehmigung für LOCATION benötigen?
– Zam versenkt
5. April 2018 um 11:18 Uhr
-
Ich versuche, eine App zu erstellen, die dem Benutzer den SMS-Inhalt anzeigt, selbst wenn die App beendet wurde
– Anjani Mittal
17. Juli 2018 um 6:41 Uhr
@David Freitas Vertrauenswürdiger Link +1
– Shahzad Imam
27. November 2012 um 14:24 Uhr
@DavidFreitas dieser Link funktioniert nicht, kannst du bitte den neuesten Link teilen?
– Khobaib
13. November 2013 um 9:45 Uhr
@Khobaib, wie immer sind die Dinge im Internet flüchtig. Ich habe eine Kopie auf archive.org stackoverflow.com/a/19966227/40961 gefunden, Gott sei Dank für sie (ich habe kürzlich gespendet, um sie am Laufen zu halten). Aber wir sollten überlegen, den Inhalt der Seite von zu konvertieren web.archive.org/web/20121022021217/http://mobdev.olin.edu/… zur Abschriftensyntax in einer Antwort auf diese Frage. Wahrscheinlich eine Stunde Arbeit.
– David d C e Freitas
13. November 2013 um 22:59 Uhr