SMS mesajlarını cihazdan alıp görüntülemek istiyorum?
SMS mesajlarını cihazdan alıp görüntülemek istiyorum?
Yanıtlar:
Gelen kutusundaki SMS'leri okumak için İçerik Çözümleyici'yi ( "içerik: // sms / gelen kutusu" ) kullanı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
}
Lütfen READ_SMS ekleyin izni .
Umut ediyorum bu yardım eder :)
moveToFirst
Benim yaptığım gibi kaçırmayın .
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();
}
Uygulamayı varsayılan SMS uygulaması olarak ayarla
@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();
}
}
}
}
}
SMS alma fonksiyonu
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 sınıfı aşağıdadır:
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;
}
}
AndroidManifest.xml dosyasında izin tanımlamayı unutmayı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)));
Bu size 24 saat zaman verecektir.
mActivity
Tanımlanmadı. Bu nedir?
Bu önemsiz bir süreç. SMSPopup kaynak kodunda iyi bir örnek görebilirsiniz
Aşağıdaki yöntemleri inceleyin:
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)
bu okuma yöntemi:
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;
}
API 19'dan itibaren bunun için Telefon Sınıfı'nı kullanabilirsiniz; İçerik sağlayıcı Uri, cihazlardan ve üreticilerden değiştiği için sabit değerler her cihazda mesaj alamayacağından.
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();
}
}
Bu gönderi biraz eski, ama burada ilgili verileri almak için başka bir kolay çözüm SMS
Android'de içerik sağlayıcıyla :
Bu lib'i kullanın: https://github.com/EverythingMe/easy-content-providers
Tümünü al SMS
:
TelephonyProvider telephonyProvider = new TelephonyProvider(context);
List<Sms> smses = telephonyProvider.getSms(Filter.ALL).getList();
Her Sms tüm alanlara sahiptir, böylece ihtiyacınız olan herhangi bir bilgiyi alabilirsiniz:
adres, gövde, alınan Tarih, tür (INBOX, SENT, DRAFT, ..), threadId, ...
Tüm jel MMS
:
List<Mms> mmses = telephonyProvider.getMms(Filter.ALL).getList();
Tüm jel Thread
:
List<Thread> threads = telephonyProvider.getThreads().getList();
Tüm jel Conversation
:
List<Conversation> conversations = telephonyProvider.getConversations().getList();
List
Veya ile çalışırCursor
ve nasıl göründüğünü ve çalıştığını görmek için örnek bir uygulama vardır.
Aslında, tüm Android içerik sağlayıcıları için bir destek var: Kişiler, Çağrı günlükleri, Takvim, ... Tüm seçeneklere sahip tam doküman: https://github.com/EverythingMe/easy-content-providers/wiki/Android- sağlayıcılar
Umarım da yardımcı oldu :)
Adım 1: İlk olarak, manifest dosyasına aşağıdaki gibi izinler eklemeliyiz
<uses-permission android:name="android.permission.RECEIVE_SMS" android:protectionLevel="signature" />
<uses-permission android:name="android.permission.READ_SMS" />
Adım 2: Daha sonra SMS almak için servis sms alıcı sınıfı ekleyin
<receiver android:name="com.aquadeals.seller.services.SmsReceiver">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
</receiver>
3. Adım: Çalışma zamanı izni ekleyin
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;
}
4. Adım: Bu sınıfları uygulamanıza ekleyin ve Interface sınıfını test edin
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; }}
Zaten çok sayıda cevap var ama hepsinin bu sorunun önemli bir bölümünü eksik olduğunu düşünüyorum. Dahili bir veritabanından veya tablosundan veri okumadan önce verilerin nasıl saklandığını anlamalıyız ve daha sonra yukarıdaki sorunun çözümünü bulabiliriz:
Android'de cihazdan SMS mesajlarını programlı olarak nasıl okuyabilirim?
Yani, Android SMS tablosunda şöyle görünmek
Veritabanından istediğimizi seçebiliriz, bizim durumumuzda sadece
kimlik, adres ve gövde
SMS okunması durumunda:
1. izin isteyin
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);
}
veya
<uses-permission android:name="android.permission.READ_SMS" />
2.Şimdi kodunuz böyle gider
// 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);
Umarım bu yardımcı olur. Teşekkürler.
Google Play hizmetlerinde SMS tabanlı doğrulama işlemini kolaylaştırmak için kullanabileceğiniz iki API vardır
Kullanıcının doğrulama kodlarını manuel olarak yazmasını gerektirmeden ve fazladan uygulama izni gerektirmeden tam otomatik bir kullanıcı deneyimi sağlar ve mümkün olduğunda kullanılmalıdır. Bununla birlikte, ileti gövdesine özel bir karma kodu yerleştirmenizi gerektirir, bu nedenle sunucu tarafında da kontrol sahibi olmanız gerekir .
Android Uygulamasında SMS Doğrulama İsteğinde Bulunma
Sunucuda SMS Doğrulama Gerçekleştirme
Özel karma kodu gerektirmez, ancak kullanıcının doğrulama kodunu içeren mesaja erişim isteğini onaylamasını gerektirir. Kullanıcıya yanlış iletinin ortaya SMS User Consent
çıkma olasılığını en aza indirgemek için kullanıcının Kişiler listesindeki gönderenlerden gelen iletileri filtreleyecektir.
The SMS User Consent API
Google Play Hizmetlerinin bir parçasıdır. Kullanmak için 17.0.0
şu kitaplıkların en az sürümüne ihtiyacınız olacak :
implementation "com.google.android.gms:play-services-auth:17.0.0"
implementation "com.google.android.gms:play-services-auth-api-phone:17.1.0"
1. Adım: SMS mesajlarını dinlemeye başlayın
SMS Kullanıcı Onayı, beş dakikaya kadar bir kerelik kod içeren gelen SMS mesajlarını dinleyecektir. Başlamadan önce gönderilen iletilere bakmaz. Bir kerelik kodu gönderecek telefon numarasını biliyorsanız senderPhoneNumber
, veya null
herhangi bir numarayla eşleşmeyecek şekilde belirtebilirsiniz .
smsRetriever.startSmsUserConsent(senderPhoneNumber /* or null */)
2. Adım: Bir mesajı okumak için onay isteyin
Uygulamanız bir kerelik kod içeren bir ileti aldığında, bir yayın tarafından bildirilir. Bu noktada, mesajı okuma izniniz yoktur - bunun yerine Intent
kullanıcıdan onay almanızı isteyebileceğiniz bir mesaj verilir . İçerideki BroadcastReceiver
, kullandığınız istemi göstermek Intent
de extras
. Bu amacı başlattığınızda, kullanıcıdan tek bir mesajı okuma izni ister. Uygulamanızla paylaşacakları metnin tamamı gösterilir.
val consentIntent = extras.getParcelable<Intent>(SmsRetriever.EXTRA_CONSENT_INTENT)
startActivityForResult(consentIntent, SMS_CONSENT_REQUEST)
Adım 3: Bir defalık kodu ayrıştırın ve SMS Doğrulamasını tamamlayın
Kullanıcı tıkladığında “Allow”
- mesajı gerçekten okuma zamanı! İçinizde onActivityResult
SMS Mesajının tam metnini verilerden alabilirsiniz:
val message = data.getStringExtra(SmsRetriever.EXTRA_SMS_MESSAGE)
Daha sonra SMS mesajını ayrıştırır ve bir kerelik kodu arka ucunuza geçirirsiniz!
4-10 digit alphanumeric code containing at least one number
Bunun ne anlama geldiğini açıklayabilir misiniz? Tüm mesajın uzunluğunun sadece sms kodunun 4-10 karakteri olması gerektiği anlamına mı geliyor?
String WHERE_CONDITION = unreadOnly ? SMS_READ_COLUMN + " = 0" : null;
tarafından değiştirildi:
String WHERE_CONDITION = unreadOnly ? SMS_READ_COLUMN + " = 0 " : SMS_READ_COLUMN + " = 1 ";
SMS okumak için Kotlin Kodu:
1- Bu izni AndroidManifest.xml dosyasına ekleyin:
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
2-BroadCastreceiver Sınıfı Yaratın:
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-Android 6 ve üzeri sürümlerde SMS İzni Alı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- Bu istek kodunu Aktivite veya parçaya ekleyin:
companion object {
const val PERMISSIONS_REQUEST_READ_SMS = 100
}
5- Geçersiz kılma İzni kontrol et Sonuç eğlencesi iste:
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 ")
}
}
}
}
En kolay fonksiyon
Sms okumak için bir Konuşma nesnesi döndüren bir işlev yazdım:
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)
}
Kullanımı:
getSmsConversation(this){ conversations ->
conversations.forEach { conversation ->
println("Number: ${conversation.number}")
println("Message One: ${conversation.message[0].body}")
println("Message Two: ${conversation.message[1].body}")
}
}
Veya yalnızca belirli bir numarada sohbet edin:
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}")
}
}