@DavidFreitas ten link nie działa, czy możesz udostępnić najnowszy link?
Khobaib
3
@Khobaib, jak zwykle rzeczy w Internecie są ulotne. Znalazłem kopię na archive.org stackoverflow.com/a/19966227/40961 , dzięki Bogu za nich (ostatnio przekazałem darowiznę, aby utrzymać ich działanie). Ale powinniśmy rozważyć konwersję zawartości strony z web.archive.org/web/20121022021217/http://mobdev.olin.edu/... do składni markdown w odpowiedzi na to pytanie. Prawdopodobnie godzina pracy.
David d C e Freitas
Odpowiedzi:
157
Użyj Content Resolver ( „content: // sms / inbox” ), aby odczytać SMS-y znajdujące się w skrzynce odbiorczej.
// 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 exceptiondo{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}
Dziękuję Ci! Błędnie napisałeś „getColumnName”, poza tym działa to jak urok. Aha, a jeśli ktoś będzie tego używał, nie zapomnij dodać uprawnienia android.permission.READ_SMS.
qwerty
1
Dzięki. Zmodyfikowałem to :)
Suryavel TR
5
Czy wykorzystuje to również nieudokumentowane API, które @CommonsWare określiło w swoim komentarzu do zaakceptowanej odpowiedzi?
Krishnabhadra,
1
Uwaga! Nie przegap moveToFirsttak jak ja.
Alexandr Priymak
4
@Krishnabhadra Tak. Wykorzystuje nieudokumentowanego dostawcę treści „content: // sms / inbox”.
To niezły kawałek kodu. Tylko jedno, czas jest uzyskiwany w milisekundach. Myślę, że lepiej będzie, aby był to format czytelny dla człowieka, taki jakString receiveDayTime = Functions.dateFromMilisec(Long.valueOf(c.getColumnIndexOrThrow("date")), "hh:mm a MMM dd, yyyy");
Bibaswann Bandyopadhyay
1
jaki jest cel tworzenia wszystkiego za pomocą gettera i settera, naprawdę nie rozumiem, dlaczego po prostu nie użyć tablicy lub klasy assoc, do której elementów można uzyskać bezpośredni dostęp
michnovka,
1
@TomasNavara: Sprawdź ten kod, aby zrozumieć korzystanie z metody pobierającej i ustawiającej. pastebin.com/Nh8YXtyJ
Błędy występowały
@BibaswannBandyopadhyay Jeśli nie chcesz używać niczego oprócz bibliotek Androida i bibliotek Java. new SimpleDateFormat("hh:mm", Locale.US).format(new Date(Long.parseLong(_time)));To da ci 24 godziny.
Chris - Jr
mActivitynie jest zdefiniowany. Co to jest?
dthree
61
To jest trywialny proces. Dobry przykład możesz zobaczyć w kodzie źródłowym SMSPopup
To nie jest część zestawu SDK systemu Android. Ten kod błędnie zakłada, że wszystkie urządzenia obsługują tego nieudokumentowanego i nieobsługiwanego dostawcę treści. Google wyraźnie wskazał, że poleganie na tym nie jest dobrym pomysłem: android-developers.blogspot.com/2010/05/…
CommonsWare
1
@Janusz: Nie ma udokumentowanych i obsługiwanych środków, które działałyby we wszystkich klientach SMS na wszystkich urządzeniach.
CommonsWare
9
@CommonsWare to smutno słyszeć. Może wtedy trzeba będzie żyć z tym interfejsem API.
Janusz
@Omer Masz pomysł, jak policzyć liczbę wiadomości SMS na kontakt?
SpicyWeenie
4
Kod został przeniesiony. Przeszukując SmsPopupUtils.java otrzymałem nowy link do niego w kodzie Google. Na wypadek, gdyby przenieśli go ponownie lub całkowicie przerwie, oto link do kopii zapasowej - pastebin.com/iPt7MLyM
KalEl
25
Począwszy od API 19, możesz do tego wykorzystywać klasę telefonii; Ponieważ wartości zapisane na stałe nie będą pobierać wiadomości z każdego urządzenia, ponieważ dostawca treści Uri zmienia się od urządzeń i producentów.
publicvoid 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=newDate(Long.valueOf(smsDate));String type;switch(Integer.parseInt(c.getString(c.getColumnIndexOrThrow(Telephony.Sms.TYPE)))){caseTelephony.Sms.MESSAGE_TYPE_INBOX:
type ="inbox";break;caseTelephony.Sms.MESSAGE_TYPE_SENT:
type ="sent";break;caseTelephony.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();}}
Wydaje się, że jest to jedyna odpowiedź, która nie korzysta z nieudokumentowanego interfejsu API i nie odnosi się do bibliotek stron trzecich.
Ishamael
Próbowałem użyć tego kodu, aby otrzymywać wiadomości SMS z Hangouts (jest to moja domyślna aplikacja do SMS-ów). Zamiast tego pobierał ostatnią wiadomość wychodzącą wysłaną przez Messenger ... Czy wiesz, co to powoduje?
Miki P
@MikiP używając moich uprawnień do zgadywania powiem, że aplikacja Messenger poprosiła cię o zastąpienie zarządzania SMS-em komunikatorem Messenger. Zdarza się to w przypadku innej aplikacji do przesyłania wiadomości. Nie mam innego wytłumaczenia.
m3nda
2
Nie zapomnij wywołać c.close ();
Cícero Moura,
1
@SardarAgabejli Jeśli użyjemy zapisanych wartości, takich jak „contenturi: sms”, nie będzie to takie samo dla każdego urządzenia, ale jeśli użyjemy klasy Telephony, otrzymamy bezpośredni dostęp do tego conetnt uri lub ścieżki sms db tego urządzenia, to klasa pomocnicza wskazująca na db sms
Manoj Perumarath
23
Ten post jest trochę stary, ale oto inne łatwe rozwiązanie do pobierania danych związanych z SMSdostawcą treści w systemie Android:
Każdy SMS ma wszystkie pola, dzięki czemu możesz uzyskać wszelkie potrzebne informacje: adres, treść, otrzymano Data, typ (SKRZYNKA, WYSŁANE, PROJEKT, ...), wątek, ...
Cóż ... czy to („com.aquadeals.seller.services.SmsReceiver”) nazwa usługi wspólnej?
m3nda
Tak, to nie nazwa usługi, czyli ścieżka klasy SmsReceiver w mojej aplikacji
Venkatesh
Dlaczego potrzebujesz zezwolenia na LOKALIZACJĘ?
Zam Zatopiony
1
próbuję stworzyć aplikację, która wyskakuje zawartość sms do użytkownika, nawet jeśli aplikacja została zabita
Anjani Mittal
11
Istnieje wiele odpowiedzi, które są już dostępne, ale myślę, że we wszystkich brakuje ważnej części tego pytania. Przed odczytem danych z wewnętrznej bazy danych lub jej tabeli musimy zrozumieć, w jaki sposób dane są w niej przechowywane, a następnie możemy znaleźć rozwiązanie powyższego pytania, które brzmi:
Jak mogę programowo odczytać wiadomości SMS z urządzenia na Androidzie?
Tak więc w Androidzie Tabela SMS wygląda tak
Wiemy, że możemy wybrać z bazy danych wszystko, co chcemy, w naszym przypadku mamy tylko wymagane
identyfikator, adres i treść
W przypadku czytania SMS:
1. Zapytaj o uprawnienia
int REQUEST_PHONE_CALL =1;if(ContextCompat.checkSelfPermission(MainActivity.this,Manifest.permission.READ_SMS)!=PackageManager.PERMISSION_GRANTED){ActivityCompat.requestPermissions(MainActivity.this,newString[]{Manifest.permission.READ_SMS}, REQUEST_PHONE_CALL);}
Zapewnia w pełni zautomatyzowane środowisko użytkownika, bez konieczności ręcznego wpisywania kodów weryfikacyjnych i bez dodatkowych uprawnień aplikacji i należy z niego korzystać, gdy to możliwe. Wymaga to jednak umieszczenia niestandardowego kodu skrótu w treści wiadomości, więc musisz mieć kontrolę również po stronie serwera .
Wymagania dotyczące wiadomości - 11-cyfrowy kod skrótu, który jednoznacznie identyfikuje Twoją aplikację
Nie wymaga niestandardowego kodu skrótu, wymaga jednak od użytkownika zatwierdzenia prośby aplikacji o dostęp do wiadomości zawierającej kod weryfikacyjny. Aby zminimalizować ryzyko wyświetlenia niewłaściwej wiadomości użytkownikowi, SMS User Consentodfiltruje wiadomości od nadawców z listy kontaktów użytkownika.
Wymagania dotyczące wiadomości - 4–10 cyfrowy kod alfanumeryczny zawierający co najmniej jedną cyfrę
Wymagania nadawcy - nadawcy nie można znaleźć na liście kontaktów użytkownika
Interakcja użytkownika - jedno dotknięcie, aby zatwierdzić
The SMS User Consent APIjest częścią usług Google Play. Aby z niego skorzystać, potrzebujesz co najmniej wersji 17.0.0tych bibliotek:
Zgoda użytkownika SMS będzie nasłuchiwać przychodzących wiadomości SMS zawierających jednorazowy kod przez maksymalnie pięć minut. Nie będzie patrzeć na żadne wiadomości wysłane przed jego uruchomieniem. Jeśli znasz numer telefonu, który wyśle jednorazowy kod, możesz podać senderPhoneNumberlub, jeśli nie null, dopasować dowolny numer.
smsRetriever.startSmsUserConsent(senderPhoneNumber /* or null */)
Krok 2: Poproś o zgodę na przeczytanie wiadomości
Gdy aplikacja otrzyma wiadomość zawierającą kod jednorazowy, zostanie o tym powiadomiona przez transmisję. W tym momencie nie masz zgody na przeczytanie wiadomości - zamiast tego otrzymujesz informację Intent, że możesz zacząć pytać użytkownika o zgodę. Wewnątrz BroadcastReceiverwyświetlasz monit za pomocą Intentw extras. Po uruchomieniu tego zamiaru użytkownik poprosi o zgodę na przeczytanie pojedynczej wiadomości. Wyświetlą się cały tekst, który udostępnią Twojej aplikacji.
val consentIntent = extras.getParcelable<Intent>(SmsRetriever.EXTRA_CONSENT_INTENT)
startActivityForResult(consentIntent, SMS_CONSENT_REQUEST)
Krok 3: Analizuj kod jednorazowy i zakończ weryfikację SMS
Gdy użytkownik kliknie “Allow”- nadszedł czas, aby przeczytać wiadomość! Wewnątrz onActivityResultmożesz uzyskać pełny tekst wiadomości SMS z danych:
val message = data.getStringExtra(SmsRetriever.EXTRA_SMS_MESSAGE)
Następnie parsujesz wiadomość SMS i przekazujesz jednorazowy kod do backendu!
4-10 digit alphanumeric code containing at least one numberCzy możesz wyjaśnić, co to znaczy? Czy to oznacza, że długość całej wiadomości powinna wynosić 4–10 znaków samego kodu sms?
Zeeshan Shabbir
Dziękuję również
Levon Petrosyan
Działa to tylko w przypadku weryfikacji OTP, prawda? Co powiesz na czytanie wszystkich innych wiadomości w telefonie, wszystkich SMS-ów itp.? Czy jest jakiś nowy interfejs API, daj mi znać. Miłego kodowania! :)
Manoj Perumarath,
Zawsze występował błąd przekroczenia limitu czasu. Proszę o pomoc
package utils.broadcastreceivers
import android.content.BroadcastReceiverimport android.content.Contextimport android.content.Intentimport android.telephony.SmsMessageimport android.util.LogclassMySMSBroadCastReceiver:BroadcastReceiver(){override fun onReceive(context:Context?, intent:Intent?){var body =""
val bundle = intent?.extras
val pdusArr = bundle!!.get("pdus")asArray<Any>var messages:Array<SmsMessage?>= arrayOfNulls(pdusArr.size)// if SMSis Long and contain more than 1 Message we'll read all of themfor(i in pdusArr.indices){
messages[i]=SmsMessage.createFromPdu(pdusArr[i]asByteArray)}varMobileNumber: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-Uzyskaj uprawnienie SMS, jeśli Android 6 i nowszy:
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- Dodaj ten kod żądania do działania lub fragmentu:
companion object{const val PERMISSIONS_REQUEST_READ_SMS =100}
5- Przesłoń Sprawdź uprawnienia Prośba o wynik zabawy:
override fun onRequestPermissionsResult(
requestCode:Int, permissions:Array<outString>,
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 ")}}}}
Aby odczytać sms, napisałem funkcję, która zwraca obiekt konwersacji:
classConversation(val number:String, val message:List<Message>)classMessage(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 }asArrayList<Conversation>}
completion(results)}
Odpowiedzi:
Użyj Content Resolver ( „content: // sms / inbox” ), aby odczytać SMS-y znajdujące się w skrzynce odbiorczej.
Dodaj uprawnienie READ_SMS .
Mam nadzieję, że to pomoże :)
źródło
moveToFirst
tak jak ja.Ustaw aplikację jako domyślną aplikację do SMS-ów
Funkcja otrzymywania wiadomości SMS
Klasa SMS jest poniżej:
Nie zapomnij zdefiniować uprawnień w pliku AndroidManifest.xml
źródło
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)));
To da ci 24 godziny.mActivity
nie jest zdefiniowany. Co to jest?To jest trywialny proces. Dobry przykład możesz zobaczyć w kodzie źródłowym SMSPopup
Sprawdź następujące metody:
to jest metoda czytania:
źródło
Począwszy od API 19, możesz do tego wykorzystywać klasę telefonii; Ponieważ wartości zapisane na stałe nie będą pobierać wiadomości z każdego urządzenia, ponieważ dostawca treści Uri zmienia się od urządzeń i producentów.
źródło
Ten post jest trochę stary, ale oto inne łatwe rozwiązanie do pobierania danych związanych z
SMS
dostawcą treści w systemie Android:Użyj tej biblioteki: https://github.com/EverythingMe/easy-content-providers
Zbierz wszystkie
SMS
:Każdy SMS ma wszystkie pola, dzięki czemu możesz uzyskać wszelkie potrzebne informacje:
adres, treść, otrzymano Data, typ (SKRZYNKA, WYSŁANE, PROJEKT, ...), wątek, ...
Żel wszystko
MMS
:Żel wszystko
Thread
:Żel wszystko
Conversation
:Działa z
List
lubCursor
i jest przykładowa aplikacja, aby zobaczyć, jak to wygląda i działa.W rzeczywistości istnieje wsparcie dla wszystkich dostawców treści dla Androida, takich jak: Kontakty, dzienniki połączeń, kalendarz, ... Pełny dokument ze wszystkimi opcjami: https://github.com/EverythingMe/easy-content-providers/wiki/Android- dostawcy
Mam nadzieję, że to również pomogło :)
źródło
Krok 1: najpierw musimy dodać uprawnienia w pliku manifestu, takim jak
Krok 2: następnie dodaj klasę usługowego odbiornika SMS do odbierania wiadomości SMS
Krok 3: Dodaj uprawnienie w czasie wykonywania
Krok 4: Dodaj te klasy do swojej aplikacji i przetestuj klasę interfejsu
SmsReceiver.java
źródło
Istnieje wiele odpowiedzi, które są już dostępne, ale myślę, że we wszystkich brakuje ważnej części tego pytania. Przed odczytem danych z wewnętrznej bazy danych lub jej tabeli musimy zrozumieć, w jaki sposób dane są w niej przechowywane, a następnie możemy znaleźć rozwiązanie powyższego pytania, które brzmi:
Jak mogę programowo odczytać wiadomości SMS z urządzenia na Androidzie?
Tak więc w Androidzie Tabela SMS wygląda tak
Wiemy, że możemy wybrać z bazy danych wszystko, co chcemy, w naszym przypadku mamy tylko wymagane
W przypadku czytania SMS:
1. Zapytaj o uprawnienia
lub
2. Teraz twój kod wygląda tak
Mam nadzieję, że ten będzie pomocny. Dzięki.
źródło
Usługi Google Play mają dwa interfejsy API, za pomocą których można usprawnić proces weryfikacji za pomocą wiadomości SMS
SMS Retriever API
Zapewnia w pełni zautomatyzowane środowisko użytkownika, bez konieczności ręcznego wpisywania kodów weryfikacyjnych i bez dodatkowych uprawnień aplikacji i należy z niego korzystać, gdy to możliwe. Wymaga to jednak umieszczenia niestandardowego kodu skrótu w treści wiadomości, więc musisz mieć kontrolę również po stronie serwera .
Poproś o weryfikację SMS w aplikacji na Androida
Wykonaj weryfikację SMS na serwerze
Interfejs API zgody użytkownika SMS
Nie wymaga niestandardowego kodu skrótu, wymaga jednak od użytkownika zatwierdzenia prośby aplikacji o dostęp do wiadomości zawierającej kod weryfikacyjny. Aby zminimalizować ryzyko wyświetlenia niewłaściwej wiadomości użytkownikowi,
SMS User Consent
odfiltruje wiadomości od nadawców z listy kontaktów użytkownika.The SMS User Consent API
jest częścią usług Google Play. Aby z niego skorzystać, potrzebujesz co najmniej wersji17.0.0
tych bibliotek:Krok 1: Rozpocznij nasłuchiwanie wiadomości SMS
Zgoda użytkownika SMS będzie nasłuchiwać przychodzących wiadomości SMS zawierających jednorazowy kod przez maksymalnie pięć minut. Nie będzie patrzeć na żadne wiadomości wysłane przed jego uruchomieniem. Jeśli znasz numer telefonu, który wyśle jednorazowy kod, możesz podać
senderPhoneNumber
lub, jeśli nienull
, dopasować dowolny numer.Krok 2: Poproś o zgodę na przeczytanie wiadomości
Gdy aplikacja otrzyma wiadomość zawierającą kod jednorazowy, zostanie o tym powiadomiona przez transmisję. W tym momencie nie masz zgody na przeczytanie wiadomości - zamiast tego otrzymujesz informację
Intent
, że możesz zacząć pytać użytkownika o zgodę. WewnątrzBroadcastReceiver
wyświetlasz monit za pomocąIntent
wextras
. Po uruchomieniu tego zamiaru użytkownik poprosi o zgodę na przeczytanie pojedynczej wiadomości. Wyświetlą się cały tekst, który udostępnią Twojej aplikacji.Krok 3: Analizuj kod jednorazowy i zakończ weryfikację SMS
Gdy użytkownik kliknie
“Allow”
- nadszedł czas, aby przeczytać wiadomość! WewnątrzonActivityResult
możesz uzyskać pełny tekst wiadomości SMS z danych:Następnie parsujesz wiadomość SMS i przekazujesz jednorazowy kod do backendu!
źródło
4-10 digit alphanumeric code containing at least one number
Czy możesz wyjaśnić, co to znaczy? Czy to oznacza, że długość całej wiadomości powinna wynosić 4–10 znaków samego kodu sms?zmienione przez:
źródło
Kod Kotlin do czytania SMS:
1- Dodaj to uprawnienie do AndroidManifest.xml:
2-Utwórz klasę BroadCastreceiver:
3-Uzyskaj uprawnienie SMS, jeśli Android 6 i nowszy:
4- Dodaj ten kod żądania do działania lub fragmentu:
5- Przesłoń Sprawdź uprawnienia Prośba o wynik zabawy:
źródło
Najłatwiejsza funkcja
Aby odczytać sms, napisałem funkcję, która zwraca obiekt konwersacji:
Za pomocą:
Lub uzyskaj tylko rozmowę o określonym numerze:
źródło