@DavidFreitas эта ссылка не работает, не могли бы вы поделиться последней ссылкой?
Хобайб
3
@Khobaib, как обычно, вещи в Интернете мимолетны. Я нашел копию на archive.org stackoverflow.com/a/19966227/40961 , слава Богу за них (я недавно пожертвовал, чтобы они работали). Но мы должны рассмотреть возможность преобразования содержимого страницы из web.archive.org/web/20121022021217/http://mobdev.olin.edu/… в синтаксис уценки в ответе на этот вопрос. Наверное, часовая работа.
Дэвид д С е Фрейтас
Ответы:
157
Используйте Content Resolver ( «content: // sms / inbox» ) для чтения SMS, которые находятся в папке «Входящие».
// 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}
Спасибо! Вы неправильно написали "getColumnName", иначе он работает как шарм. Да, и если кто-то будет использовать это, не забудьте добавить разрешение android.permission.READ_SMS.
qwerty
1
Спасибо. Я изменил это :)
Suryavel TR
5
Использует ли это также недокументированный API, указанный @CommonsWare в его комментарии к принятому ответу?
Кришнабхадра
1
Внимание! Не скучай, moveToFirstкак я.
Александр Приймак
4
@ Krishnabhadra Да. Он использует недокументированный контент-провайдер "content: // sms / inbox".
Это хороший кусок кода. Только одно, время получается в миллисекундах. Я думаю, что будет лучше сделать его читабельным для людей, например,String receiveDayTime = Functions.dateFromMilisec(Long.valueOf(c.getColumnIndexOrThrow("date")), "hh:mm a MMM dd, yyyy");
Bibaswann Bandyopadhyay
1
Какова цель сделать все с помощью getter и setter, я действительно не понимаю, почему бы просто не использовать ассоциативный массив или класс, к элементам которого обращаются напрямую
michnovka
1
@TomasNavara: проверьте этот код для понимания использования геттера и сеттера. pastebin.com/Nh8YXtyJ
Ошибки случаются
@BibaswannBandyopadhyay Если вы не хотите использовать ничего, кроме библиотек Android и Java-библиотек. new SimpleDateFormat("hh:mm", Locale.US).format(new Date(Long.parseLong(_time)));Это даст вам 24 часа времени.
Крис - младший
mActivityне определен. Что это?
dthree
61
Это тривиальный процесс. Хороший пример вы можете увидеть в исходном коде SMSPopup.
Это не является частью Android SDK. Этот код делает неверное предположение, что все устройства поддерживают этого недокументированного и неподдерживаемого поставщика контента. Google явно указал, что полагаться на это не очень хорошая идея: android-developers.blogspot.com/2010/05/…
CommonsWare
1
@Janusz: нет документированных и поддерживаемых средств, которые бы работали на всех клиентах SMS на всех устройствах.
CommonsWare
9
@CommonsWare, что грустно слышать. Возможно, придется жить с этим API тогда.
Януш
@Omer Есть идеи, как посчитать количество SMS-сообщений на контакт?
SpicyWeenie
4
Код переехал. Поиск SmsPopupUtils.java получил мне новую ссылку на него в коде Google. В случае, если они переместят его снова или полностью
прекратят
25
Начиная с API 19 для этого вы можете использовать класс телефонии; Так как жестко заданные значения не будут получать сообщения на всех устройствах, потому что поставщик контента Uri меняется от устройств и производителей.
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();}}
Кажется, что это единственный ответ, который не использует недокументированный API и не относится к сторонним библиотекам.
Ишамаэль
Я пытался использовать этот код для получения SMS-сообщений от видеовстреч (это мое приложение SMS по умолчанию). Вместо этого он получил последнее исходящее сообщение, которое я отправил через Messenger ... Знаете ли вы, что является причиной этого?
Мики П
@MikiP, используя мои догадки, скажу, что Messenger App попросил вас заменить управление SMS на Messenger. Это происходит с другим приложением для обмена сообщениями. У меня нет другого объяснения.
m3nda
2
Не забудьте вызвать c.close ();
Сисеро Моура
1
@SardarAgabejli Если мы используем жесткие значения, такие как «contenturi: sms», это не будет одинаковым для всех устройств, но если мы используем класс телефонии, мы получим прямой доступ к этому conrint uri или пути sms db этого устройства, это класс помощника, чтобы указать на БД смс
Манодж Perumarath
23
Этот пост немного устарел, но вот еще одно простое решение для получения данных, связанных с SMSпоставщиком контента в Android:
В каждом SMS-сообщении есть все поля, поэтому вы можете получить любую нужную вам информацию: адрес, тело, receiveDate, тип (INBOX, SENT, DRAFT, ..), threadId, ...
Хорошо ... это ("com.aquadeals.seller.services.SmsReceiver") общее имя службы?
m3nda
Да, это не имя службы, это путь к классу SmsReceiver в моем приложении
Venkatesh
Зачем нужно разрешение на РАСПОЛОЖЕНИЕ?
Zam Sunk
1
я пытаюсь сделать приложение, которое выскакивает смс-контент пользователю, даже если приложение было убито
Anjani Mittal
11
Есть много уже доступных ответов, но я думаю, что все они упускают важную часть этого вопроса. Прежде чем читать данные из внутренней базы данных или ее таблицы, мы должны понять, как в ней хранятся данные, а затем найти решение вышеуказанного вопроса:
Как программно читать СМС-сообщения с устройства в Android?
Итак, в андроид смс таблица выглядит так
Знайте, мы можем выбрать все, что мы хотим из базы данных. В нашем случае нам нужно только
идентификатор, адрес и тело
В случае чтения СМС:
1. Спросите разрешения
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);}
Предоставляет полностью автоматизированный пользовательский интерфейс, не требуя от пользователя ручного ввода кодов проверки и не требуя каких-либо дополнительных разрешений приложения, и должен использоваться по возможности. Однако он требует, чтобы вы поместили пользовательский хеш-код в тело сообщения, поэтому вы должны также контролировать серверную часть .
Требования к сообщениям - 11-значный хэш-код, который однозначно идентифицирует ваше приложение
Не требует настраиваемого хеш-кода, однако требует, чтобы пользователь одобрил запрос вашего приложения на доступ к сообщению, содержащему проверочный код. Чтобы свести к минимуму вероятность появления неправильного сообщения для пользователя, SMS User Consentбудет отфильтровываться сообщения от отправителей в списке контактов пользователя.
Требования к сообщению - 4-10-значный буквенно-цифровой код, содержащий не менее одного номера
Требования к отправителю - отправитель не может быть в списке контактов пользователя
Взаимодействие с пользователем - одно нажатие для подтверждения
The SMS User Consent APIявляется частью Сервисов Google Play. Для его использования вам понадобится как минимум версия 17.0.0этих библиотек:
SMS User Consent будет прослушивать входящие SMS-сообщения, содержащие одноразовый код, до пяти минут. Он не будет проверять сообщения, отправленные до его запуска. Если вам известен номер телефона, на который будет отправляться одноразовый код, вы можете указать senderPhoneNumber, или, если вы не nullсоответствуете ни одному номеру.
smsRetriever.startSmsUserConsent(senderPhoneNumber /* or null */)
Шаг 2: Запрос согласия на чтение сообщения
Как только ваше приложение получит сообщение, содержащее одноразовый код, оно будет уведомлено о трансляции. На данный момент у вас нет согласия на чтение сообщения - вместо этого вы получаетеIntent что вы можете начать запрашивать согласие пользователя. Внутри вашего BroadcastReceiver, вы показываете подсказку, используя Intentв extras. Когда вы запускаете это намерение, он запрашивает у пользователя разрешение на чтение одного сообщения. Им будет показан весь текст, которым они поделятся с вашим приложением.
val consentIntent = extras.getParcelable<Intent>(SmsRetriever.EXTRA_CONSENT_INTENT)
startActivityForResult(consentIntent, SMS_CONSENT_REQUEST)
Шаг 3: Разбор одноразового кода и полное подтверждение SMS
Когда пользователь нажимает “Allow”- самое время прочитать сообщение! Внутри onActivityResultвы можете получить полный текст SMS-сообщения из данных:
val message = data.getStringExtra(SmsRetriever.EXTRA_SMS_MESSAGE)
Затем вы анализируете SMS-сообщение и передаете одноразовый код своему бэкэнду!
4-10 digit alphanumeric code containing at least one numberМожете ли вы объяснить, что это значит? Означает ли это, что длина всего сообщения должна составлять 4-10 символов только из SMS-кода?
Зеешан Шаббир
Спасибо и вам
Левон Петросян
Это работает только для проверки OTP, верно? Как насчет чтения всех других сообщений внутри телефона, всех SMS и т. Д.? Есть ли новый API для этого, пожалуйста, дайте мне знать. Удачного кодирования! :)
Manoj Perumarath
У нас всегда есть ошибка тайм-аута. Пожалуйста, помогите мне
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-Получить SMS-разрешение, если Android 6 и выше:
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- Добавьте этот код запроса в Activity или фрагмент:
companion object{const val PERMISSIONS_REQUEST_READ_SMS =100}
5- Переопределение проверки разрешений. Результат запроса:
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 ")}}}}
Чтобы прочитать смс, я написал функцию, которая возвращает объект беседы:
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)}
Ответы:
Используйте Content Resolver ( «content: // sms / inbox» ) для чтения SMS, которые находятся в папке «Входящие».
Пожалуйста, добавьте разрешение READ_SMS .
Я надеюсь, что это помогает :)
источник
moveToFirst
как я.Установить приложение в качестве приложения SMS по умолчанию
Функция для получения SMS
Класс смс ниже:
Не забудьте определить разрешение в вашем AndroidManifest.xml
источник
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)));
Это даст вам 24 часа времени.mActivity
не определен. Что это?Это тривиальный процесс. Хороший пример вы можете увидеть в исходном коде SMSPopup.
Изучите следующие методы:
это метод для чтения:
источник
Начиная с API 19 для этого вы можете использовать класс телефонии; Так как жестко заданные значения не будут получать сообщения на всех устройствах, потому что поставщик контента Uri меняется от устройств и производителей.
источник
Этот пост немного устарел, но вот еще одно простое решение для получения данных, связанных с
SMS
поставщиком контента в Android:Используйте эту библиотеку: https://github.com/EverythingMe/easy-content-providers
Получить все
SMS
:В каждом SMS-сообщении есть все поля, поэтому вы можете получить любую нужную вам информацию:
адрес, тело, receiveDate, тип (INBOX, SENT, DRAFT, ..), threadId, ...
Гель все
MMS
:Гель все
Thread
:Гель все
Conversation
:Он работает с
List
или,Cursor
и есть пример приложения, чтобы увидеть, как это выглядит и работает.На самом деле, есть поддержка всех поставщиков контента Android, таких как: Контакты, Журналы вызовов, Календарь, ... Полный документ со всеми опциями: https://github.com/EverythingMe/easy-content-providers/wiki/Android- провайдеры
Надеюсь, это также помогло :)
источник
Шаг 1: сначала мы должны добавить разрешения в файл манифеста, как
Шаг 2: затем добавьте сервисный класс получателя смс для получения смс
Шаг 3: Добавить разрешение во время выполнения
Шаг 4. Добавьте эти классы в ваше приложение и протестируйте интерфейсный класс.
SmsReceiver.java
источник
Есть много уже доступных ответов, но я думаю, что все они упускают важную часть этого вопроса. Прежде чем читать данные из внутренней базы данных или ее таблицы, мы должны понять, как в ней хранятся данные, а затем найти решение вышеуказанного вопроса:
Как программно читать СМС-сообщения с устройства в Android?
Итак, в андроид смс таблица выглядит так
Знайте, мы можем выбрать все, что мы хотим из базы данных. В нашем случае нам нужно только
В случае чтения СМС:
1. Спросите разрешения
или
2. Теперь ваш код выглядит так
Я надеюсь, что это будет полезно. Спасибо.
источник
Сервисы Google Play имеют два API, которые вы можете использовать для упрощения процесса проверки на основе SMS
SMS Retriever API
Предоставляет полностью автоматизированный пользовательский интерфейс, не требуя от пользователя ручного ввода кодов проверки и не требуя каких-либо дополнительных разрешений приложения, и должен использоваться по возможности. Однако он требует, чтобы вы поместили пользовательский хеш-код в тело сообщения, поэтому вы должны также контролировать серверную часть .
Запросить SMS-подтверждение в приложении для Android
Выполните проверку SMS на сервере
API согласия пользователя SMS
Не требует настраиваемого хеш-кода, однако требует, чтобы пользователь одобрил запрос вашего приложения на доступ к сообщению, содержащему проверочный код. Чтобы свести к минимуму вероятность появления неправильного сообщения для пользователя,
SMS User Consent
будет отфильтровываться сообщения от отправителей в списке контактов пользователя.The SMS User Consent API
является частью Сервисов Google Play. Для его использования вам понадобится как минимум версия17.0.0
этих библиотек:Шаг 1: Начните слушать SMS-сообщения
SMS User Consent будет прослушивать входящие SMS-сообщения, содержащие одноразовый код, до пяти минут. Он не будет проверять сообщения, отправленные до его запуска. Если вам известен номер телефона, на который будет отправляться одноразовый код, вы можете указать
senderPhoneNumber
, или, если вы неnull
соответствуете ни одному номеру.Шаг 2: Запрос согласия на чтение сообщения
Как только ваше приложение получит сообщение, содержащее одноразовый код, оно будет уведомлено о трансляции. На данный момент у вас нет согласия на чтение сообщения - вместо этого вы получаете
Intent
что вы можете начать запрашивать согласие пользователя. Внутри вашегоBroadcastReceiver
, вы показываете подсказку, используяIntent
вextras
. Когда вы запускаете это намерение, он запрашивает у пользователя разрешение на чтение одного сообщения. Им будет показан весь текст, которым они поделятся с вашим приложением.Шаг 3: Разбор одноразового кода и полное подтверждение SMS
Когда пользователь нажимает
“Allow”
- самое время прочитать сообщение! ВнутриonActivityResult
вы можете получить полный текст SMS-сообщения из данных:Затем вы анализируете SMS-сообщение и передаете одноразовый код своему бэкэнду!
источник
4-10 digit alphanumeric code containing at least one number
Можете ли вы объяснить, что это значит? Означает ли это, что длина всего сообщения должна составлять 4-10 символов только из SMS-кода?изменено:
источник
Код Котлина для чтения смс:
1- Добавьте это разрешение в AndroidManifest.xml:
2-Создать класс BroadCastreceiver:
3-Получить SMS-разрешение, если Android 6 и выше:
4- Добавьте этот код запроса в Activity или фрагмент:
5- Переопределение проверки разрешений. Результат запроса:
источник
Самая простая функция
Чтобы прочитать смс, я написал функцию, которая возвращает объект беседы:
С помощью:
Или получить только разговор на конкретный номер:
источник