Hello,
Welcome to our Microsoft Q&A platform!
I notice you use Android 9.0, if you want to read sms, you should change your application as SMS default application like following screenshot.
Firstly, we should set my application to the default sms app.
We must do following steps(If we lack of one of them, it will not worked).
- In a broadcast receiver, include an intent filter for SMS_DELIVER_ACTION ("android.provider.Telephony.SMS_DELIVER"). The broadcast receiver must also require the BROADCAST_SMS permission. This allows your app to directly receive incoming SMS messages.
- In a broadcast receiver, include an intent filter for WAP_PUSH_DELIVER_ACTION ("android.provider.Telephony.WAP_PUSH_DELIVER") with the MIME type "application/vnd.wap.mms-message". The broadcast receiver must also require the BROADCAST_WAP_PUSH permission. This allows your app to directly receive incoming MMS messages.
- In your activity that delivers new messages, include an intent filter for ACTION_SENDTO ("android.intent.action.SENDTO") with schemas, sms:, smsto:, mms:, and mmsto:. This allows your app to receive intents from other apps that want to deliver a message.
- In a service, include an intent filter for ACTION_RESPONSE_VIA_MESSAGE ("android.intent.action.RESPOND_VIA_MESSAGE") with schemas, sms:, smsto:, mms:, and mmsto:. This service must also require the SEND_RESPOND_VIA_MESSAGE permission.
Without all four, your app will not be listed in the default SMS selection dialog.
Here is edited Manifest file.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:versionCode="1"
android:versionName="1.0"
package="com.companyname.sms_receiver2">
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="28" />
<application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme">
<!-- BroadcastReceiver that listens for incoming MMS messages -->
<receiver android:name=".MmsReceiver"
android:permission="android.permission.BROADCAST_WAP_PUSH">
<intent-filter>
<action android:name="android.provider.Telephony.WAP_PUSH_DELIVER" />
<data android:mimeType="application/vnd.wap.mms-message" />
</intent-filter>
</receiver>
<!-- Activity that allows the user to send new SMS/MMS messages -->
<activity android:name=".ComposeSmsActivity" >
<intent-filter>
<action android:name="android.intent.action.SEND" />
<action android:name="android.intent.action.SENDTO" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="sms" />
<data android:scheme="smsto" />
<data android:scheme="mms" />
<data android:scheme="mmsto" />
</intent-filter>
</activity>
<!-- Service that delivers messages from the phone "quick response" -->
<service android:name=".HeadlessSmsSendService"
android:permission="android.permission.SEND_RESPOND_VIA_MESSAGE"
android:exported="true" >
<intent-filter>
<action android:name="android.intent.action.RESPOND_VIA_MESSAGE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="sms" />
<data android:scheme="smsto" />
<data android:scheme="mms" />
<data android:scheme="mmsto" />
</intent-filter>
</service>
</application>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.BROADCAST_SMS" />
</manifest>
Then add following three class
public class MmsReceiver : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
Toast.MakeText(context, "Received intent!", ToastLength.Short).Show();
}
}
public class HeadlessSmsSendService : Service
{
public override IBinder OnBind(Intent intent)
{
return null;
}
}
public class ComposeSmsActivity : Activity
{
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Create your application here
}
}
In the end, change the default app with following code.
//Add this to make your app default
Intent intent = new Intent();
intent.SetAction(Telephony.Sms.Intents.ActionChangeDefault);
intent.PutExtra(Telephony.Sms.Intents.ExtraPackageName, "com.companyname.sms_receiver2");
Here is your Receiver1.cs
.
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.Telephony;
using Android.Provider;
using Android.Database;
using Android.Util;
namespace Sms_Receiver2
{
[BroadcastReceiver(Enabled = true, Exported = true, Permission = "android.permission.BROADCAST_SMS")]
[IntentFilter(new[] { "android.provider.Telephony.SMS_RECEIVED", "android.provider.Telephony.SMS_DELIVER" })]
public class Receiver1 : BroadcastReceiver
{
public string message = "";
public string address = "";
public static readonly string INTENT_ACTION = "android.provider.Telephony.SMS_RECEIVED";
public Receiver1()
{
}
public string Text { get; set; }
public override void OnReceive(Context context, Intent intent)
{
var msgs = Telephony.Sms.Intents.GetMessagesFromIntent(intent);
List<string> msgList = new List<string>();
string address = "";
string body = "";
foreach (var msg in msgs)
{
msgList.Add(msg.DisplayMessageBody);
address = msg.DisplayOriginatingAddress;
body = msg.DisplayMessageBody;
}
markMessageRead(Android.App.Application.Context, address, body);
Text = body;
Toast.MakeText(context, "Number :" + address + "Message : " + body, ToastLength.Short).Show();
// MessagingCenter.Send<List<string>>(msgList, "MyMessage");
}
public void markMessageRead(Context context, String number, String body)
{
Android.Net.Uri uri = Android.Net.Uri.Parse("content://sms/inbox");
ICursor cursor = context.ContentResolver.Query(uri, null, null, null, null);
try
{
while (cursor.MoveToNext())
{
if ((cursor.GetString(cursor.GetColumnIndex("address")).Equals(number)) && (cursor.GetInt(cursor.GetColumnIndex("read")) == 0))
{
if (cursor.GetString(cursor.GetColumnIndex("body")).StartsWith(body))
{
String SmsMessageId = cursor.GetString(cursor.GetColumnIndex("_id"));
ContentValues values = new ContentValues();
values.Put("read", true);
context.ContentResolver.Update(Android.Net.Uri.Parse("content://sms/inbox"), values, "_id=" + SmsMessageId, null);
return;
}
}
}
}
catch (Exception e)
{
Log.Error("Mark Read", "Error in Read: " + e.ToString());
}
}
}
}
Here is your MainActivity.cs
[Activity(Label = "@string/app_name", Theme = "@style/AppTheme", MainLauncher = true)]
public class MainActivity : AppCompatActivity
{
Receiver1 _receiver; // Receiver class
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.activity_main);
TextView translatedPhoneWord = FindViewById<TextView>(Resource.Id.TranslatedPhoneword);
Button translateButton = FindViewById<Button>(Resource.Id.TranslateButton);
if (ContextCompat.CheckSelfPermission(this, Manifest.Permission.ReadSms) != (int)Permission.Granted)
{
RequestPermissions(new string[] { Manifest.Permission.ReadSms, Manifest.Permission.SendSms, Manifest.Permission.ReceiveSms }, 0);
}
//Add this to make your app default
Intent intent = new Intent();
intent.SetAction(Telephony.Sms.Intents.ActionChangeDefault);
intent.PutExtra(Telephony.Sms.Intents.ExtraPackageName, "com.companyname.sms_receiver2");
StartActivity(intent);
translateButton.Click += (s, e) =>
{
translatedPhoneWord.Text = _receiver.Text;
// = _receiver.message;
// Toast.MakeText(ApplicationContext, _receiver.address + ", " + _receiver.message, ToastLength.Short).Show(); //showing a Toast again
};
// RegisterReceiver(_receiver,new IntentFilter();
}
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
{
Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}
protected override void OnResume()
{
base.OnResume();
_receiver = new Receiver1();
IntentFilter filter = new IntentFilter();
filter.AddAction("android.provider.Telephony.SMS_RECEIVED");
filter.AddAction("android.provider.Telephony.SMS_DELIVER");
RegisterReceiver(_receiver, filter);
}
protected override void OnPause()
{
base.OnPause();
UnregisterReceiver(_receiver);
}
}
}
Here is running screenshot( when you run your application, please gave the sms permission and change the default sms application).
============================
Update=================================
Somehow, I checked on this ,Uninstalled my App,Redeployed it on my phone (Android 9.0), It first asked my about the default permission which I cancelled,Then it >asked me for permissions for sending and reading sms.My App worked regardless that I made it default or not in my case I didn't,so thats a relief,but when I destroy >my App start it again it asks me about the default permission again which it should just one time after installation.How can I make it stop asking me everytime I start >my App?
You can use Preferences to achieve it when you first login. If you are loging at the first time, myValue is true, if push the window, Preferences.Set("IsFirstLogin", false);
will be setted to false, at the next time, this window that asks you about the default permission will not execute.
bool myValue = Preferences.Get("IsFirstLogin", true);
if (myValue)
{
//Add this to make your app default
Intent intent = new Intent();
intent.SetAction(Telephony.Sms.Intents.ActionChangeDefault);
intent.PutExtra(Telephony.Sms.Intents.ExtraPackageName, "com.companyname.sms_receiver2");
StartActivity(intent);
Preferences.Set("IsFirstLogin", false);
}
Best Regards,
Leon Lu
If the response is helpful, please click "Accept Answer" and upvote it.
Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.