[我正在Xamarin中开发一个应为默认SMS的SMS应用,我注册了Sms Receiver类,但是当设备收到消息时,会出现此错误。
Java.Lang.RuntimeException: 'Unable to instantiate receivercom.companyName.MySmsApp.DroidSmsReceiver: java.lang.ClassNotFoundException:Didn't find class "com.companyName.MySmsApp.DroidSmsReceiver" on path:DexPathList[[zip file "/data/app/com.companyName.MySmsApp-NaDrepA_GVue_nq4DxzmqA==/base.apk"],nativeLibraryDirectories=[/data/app/com.companyName.MySmsApp-NaDrepA_GVue_nq4DxzmqA==/lib/x86, /data/app/com.companyName.MySmsApp-NaDrepA_GVue_nq4DxzmqA==/base.apk!/lib/x86, /system/lib]]'
我的Android清单:
<receiver android:name=".DroidSmsReceiver"
android:exported="true"
android:permission="android.permission.BROADCAST_SMS">
<intent-filter android:priority="999" >
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
<action android:name="android.provider.Telephony.SMS_DELIVER" />
<action android:name="android.provider.Telephony.SMS_DELIVER_ACTION" />
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
<receiver android:name=".MMSBroadcastReceiver"
android:exported="true"
android:permission="android.permission.BROADCAST_WAP_PUSH">
<intent-filter android:priority="999" >
<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
android:name=".QuickResponseService"
android:enabled="true"
android:exported="true"
android:permission="android.permission.SEND_RESPOND_VIA_MESSAGE">
<intent-filter>
<category android:name="android.intent.category.DEFAULT" />
<action android:name="android.intent.action.RESPOND_VIA_MESSAGE" />
<data android:scheme="sms" />
<data android:scheme="smsto" />
<data android:scheme="mms" />
<data android:scheme="mmsto" />
</intent-filter>
</service>
我也尝试过
<receiver android:name=".DroidSmsReceiver"
android:permission="android.permission.BROADCAST_SMS">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
<action android:name="android.provider.Telephony.SMS_DELIVER" />
</intent-filter></receiver>
我的接收器,位于:MySmsApp.Droid
[BroadcastReceiver(Enabled = true, Exported = true)]
[IntentFilter(new[] { "android.provider.Telephony.SMS_RECEIVED" })]
//[IntentFilter(new[] { "android.provider.Telephony.SMS_DELIVER" })]
public class DroidSmsReceiver : BroadcastReceiver
{
//private const string IntentAction = "android.provider.Telephony.SMS_RECEIVED";
protected string address, message = "";
public override void OnReceive(Context context, Intent intent)
{
//message received
}
}
我还在MainActivity.cs中注册了接收者
RegisterReceiver(new DroidSmsReceiver(), new IntentFilter("android.provider.Telephony.SMS_DELIVER"));
预先感谢你们。
您是否想像以Xamarin形式遵循GIF一样实现转播??
如果是这样,我使用依赖项服务来实现。
首先,我在PCL中创建一个接口
public interface ISmsReader
{
void GetSmsInbox();
}
您可以在PCL MainPage.xaml.cs
中使用它。
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
MessagingCenter.Subscribe<List<string>>(this, "MyMessage", (expense) =>
{
List<string> mylist= expense as List<string>;
string allText= "";
foreach (string item in mylist)
{
allText += item+" ";
}
editorSms.Text = allText;
});
}
private void Button_Clicked(object sender, EventArgs e)
{
Xamarin.Forms.DependencyService.Get<ISmsReader>().GetSmsInbox();
}
}
这里是我的MainPage.xaml
。
<StackLayout>
<Button Text="open broadcase" Clicked="Button_Clicked"/>
<Label x:Name="editorSms"/>
</StackLayout>
然后,在xxxx.Droid文件夹中实现此接口。注意:您的new IntentFilter("android.provider.Telephony.SMS_DELIVER")
中的MainActivity.cs
IntentFilter错误,应该为android.provider.Telephony.SMS_RECEIVED
[assembly: Xamarin.Forms.Dependency(typeof(MySmsReader))]
namespace ScanDemo.Droid
{
public class MySmsReader : ISmsReader
{
public void GetSmsInbox()
{
IntentFilter filter = new IntentFilter();
filter.AddAction("android.provider.Telephony.SMS_RECEIVED");
SmsBroadcastRceiver receiver = new SmsBroadcastRceiver();
Application.Context.RegisterReceiver(receiver, filter);
}
}
}
然后,这是我关于SmsBroadcastRceiver
的代码。
[BroadcastReceiver(Enabled = true, Exported = true)]
[IntentFilter(new[] { "android.provider.Telephony.SMS_RECEIVED" })]
public class SmsBroadcastRceiver : BroadcastReceiver
{
public SmsBroadcastRceiver()
{
}
public override void OnReceive(Context context, Intent intent)
{
var msgs = Telephony.Sms.Intents.GetMessagesFromIntent(intent);
List<string> msgList = new List<string>();
foreach (var msg in msgs)
{
msgList.Add(msg.DisplayMessageBody);
}
MessagingCenter.Send<List<string>>(msgList, "MyMessage");
}
}
}
如果您在SmsBroadcastRceiver
类上方设置了属性,则无需在Android清单中将其清除。
这是我的演示(我没有获得运行时权限,如果测试我的演示,则应手动添加权限)。
https://github.com/851265601/BroadcastReceSMS
====更新====
如果您要将邮件设置为已读,首先,我们应将我的应用程序设置为默认的短信应用程序。
我们必须执行以下步骤(如果缺少其中之一,它将无法正常工作。)>
在广播接收器中,包括用于SMS_DELIVER_ACTION的意图过滤器(“ android.provider.Telephony.SMS_DELIVER”)。广播接收器还必须要求BROADCAST_SMS权限。这使您的应用程序可以直接接收传入的SMS消息。
在广播接收器中,包括MIME类型为application / vnd.wap.mms-message的WAP_PUSH_DELIVER_ACTION(“ android.provider.Telephony.WAP_PUSH_DELIVER”)的意图过滤器。广播接收器还必须要求BROADCAST_WAP_PUSH权限。这使您的应用程序可以直接接收传入的MMS消息。
在传递新消息的活动中,包括具有模式,sms :、 smsto :、 mms:和mmsto:的ACTION_SENDTO(“ android.intent.action.SENDTO”)意图过滤器。这使您的应用可以接收来自其他要传递消息的应用的意图。
在服务中,包含具有模式,sms:,smsto:,mms:和mmsto:的ACTION_RESPONSE_VIA_MESSAGE(“ android.intent.action.RESPOND_VIA_MESSAGE”)的意图过滤器。此服务还必须需要SEND_RESPOND_VIA_MESSAGE权限。
没有全部四个,您的应用将不会在默认的SMS选择对话框中列出。
这里是我的AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="com.companyname.scandemo" android:installLocation="auto"> <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="28" /> <application android:label="ScanDemo.Android"> <!-- 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>
达到
MmsReceiver
,HeadlessSmsSendService
,ComposeSmsActivity
,SmsBroadcastRceiver
这里是关于MmsReceiver.cs
的代码。
public class MmsReceiver : BroadcastReceiver { public override void OnReceive(Context context, Intent intent) { Toast.MakeText(context, "Received intent!", ToastLength.Short).Show(); } }
这里是关于
HeadlessSmsSendService.cs
的代码。
public class HeadlessSmsSendService : Service { public override IBinder OnBind(Intent intent) { return null; } }
这里是关于
ComposeSmsActivity.cs
的代码。
public class ComposeSmsActivity : Activity { protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); // Create your application here } }
这里是关于
SmsBroadcastRceiver.cs
的代码。
[BroadcastReceiver(Enabled = true, Exported = true,Permission = "android.permission.BROADCAST_SMS")] [IntentFilter(new[] { "android.provider.Telephony.SMS_RECEIVED", "android.provider.Telephony.SMS_DELIVER" })] public class SmsBroadcastRceiver : BroadcastReceiver { public SmsBroadcastRceiver() { } 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); 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()); } } }
我在
MainActivity.cs
中添加以下代码,以将我的应用设置为默认的短信应用。
//Add this to make your app default Intent intent = new Intent(); intent.SetAction(Telephony.Sms.Intents.ActionChangeDefault); intent.PutExtra(Telephony.Sms.Intents.ExtraPackageName, this.PackageName); StartActivity(intent);
这是我的新演示。