[英]Creating Default SMS App in Xamarin.Forms
我正在 Xamarin 中開發一個短信應用程序,它應該是默認短信,我注冊了短信接收器 class,但是當設備收到一條消息時會出現此錯誤。
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 forms 中實現類似 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")
IntentFilter 在你的MainActivity.cs
中有錯誤,應該是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
class 上方的屬性,則無需在 Android Manifest 中將其清除。
這是我的演示(我沒有實現運行時權限,如果你測試我的演示,你應該手動添加權限)。
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 權限。 這允許您的應用直接接收傳入的彩信。
在傳遞新消息的 Activity 中,包含 ACTION_SENDTO(“android.intent.action.SENDTO”)的意圖過濾器,其中包含模式、sms:、smsto:、mms: 和 mmsto:。 這允許您的應用程序從想要傳遞消息的其他應用程序接收意圖。
在服務中,包含 ACTION_RESPONSE_VIA_MESSAGE ("android.intent.action.RESPOND_VIA_MESSAGE") 的意圖過濾器,其中包含模式、sms:、smsto:、mms: 和 mmsto:。 此服務還必須需要 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);
這是我的新演示。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.