Cannot apply source type to destination type (JNIEnv.GetArray <Java.Lang.Object> (pudis.Handle);)
I am trying to receive SMS in my application.
There is a BroadcastReceiver class in my project, and I get a runtime error:
System.InvalidCastException: Cannot pass from source type to destination type. at at (cluster class) .__ castclass_with_cache object (object, intptr, intptr) on Android.Runtime.JNIEnv.CopyArray (intptr, Java.Lang.Object []) <0x002a3> at at Android.Runtime.JNIEnv.GetArray (intptr ) <0x0021f>
in Messages.SMSBroadcastReceiver.OnReceive (Android.Content.Context, Android.Content.Intent) [0x0005f] in C: \ Users \ Jase \ Documents \ Projects \ Messages \ Messages \ SMSBroadcastReceiver.cs: 36 in Android.Content.BroadcastReceiver. n_OnReceive_Landroid_content_Context_Landroid_content_Intent_ (intptr, intptr, intptr, intptr) [0x00019] in / Users / builder / data / lanes / monodroid -mlion-monodroid-4.20-series / ba9bbbdd / source / monodroid / sndc / androiddr /src/generated/Android.Content.BroadcastReceiver.cshaps34 at at (dynamic shell method) object.145a0c82-0de6-4c2c-90a0-3654436a06c3 (intptr, intptr, intptr, intptr)
Here is the code I'm using:
using System;
using System.Text;
using Android.App;
using Android.OS;
using Android.Content;
using Android.Runtime;
using Android.Util;
using Android.Widget;
using Android.Telephony;
using Environment = System.Environment;
namespace Messages
{
[BroadcastReceiver(Enabled = true, Label = "SMS Receiver")]
[IntentFilter(new[] { "android.provider.Telephony.SMS_RECEIVED" })]
public class SMSBroadcastReceiver : BroadcastReceiver
{
private const string Tag = "SMSBroadcastReceiver";
private const string IntentAction = "android.provider.Telephony.SMS_RECEIVED";
public override void OnReceive(Context context, Intent intent)
{
Log.Info(Tag, "Intent: " + intent.Action);
if (intent.Action != IntentAction)
return;
var bundle = intent.Extras;
if (bundle == null)
return;
var pdus = bundle.Get("pdus");
// ********** This is the error line at runtime ****************
var castedPdus = JNIEnv.GetArray<Java.Lang.Object>(pdus.Handle);
var messages = new SmsMessage[castedPdus.Length];
var stringBuilder = new StringBuilder();
for (int i = 0; i < messages.Length; i++)
{
var bytes = new byte[JNIEnv.GetArrayLength(castedPdus[i].Handle)];
JNIEnv.CopyArray(castedPdus[i].Handle, bytes);
messages[i] = SmsMessage.CreateFromPdu(bytes);
stringBuilder.Append(String.Format("SMS from: {0}{1}Body: {2}{1}", messages[i].OriginatingAddress,
Environment.NewLine, messages[i].MessageBody));
}
Toast.MakeText(context, stringBuilder.ToString(), ToastLength.Long).Show();
}
}
}
I tried to find a solution for a while and have been looking for many hours, but none of the existing solutions to this error worked. I do not understand. Can someone please help shed some light on this?
:
Bundle not null: Bundle[mParcelledData.dataSize=256]
PDUS: [[B@5s294833
PDUS Handle: 2065454
Cannot cast from source type to destination type. at (wrapper castclass) object:__castclass_with_cache (object,intptr,intptr)
at Android.Runtime.JNIEnv.CopyArray[Object] (IntPtr src, Java.Lang.Object[] dest) [0x00078] in /Users/builder/data/lanes/monodroid-mlion-monodroid-4.20-series/ba9bbbdd/source/monodroid/src/Mono.Android/src/Runtime/JNIEnv.cs:946
at Android.Runtime.JNIEnv.GetArray[Object] (IntPtr array_ptr) [0x00053] in /Users/builder/data/lanes/monodroid-mlion-monodroid-4.20-series/ba9bbbdd/source/monodroid/src/Mono.Android/src/Runtime/JNIEnv.cs:1211
at Java.Lang.Object.ToArray[Object] () [0x00000] in /Users/builder/data/lanes/monodroid-mlion-monodroid-4.20-series/ba9bbbdd/source/monodroid/src/Mono.Android/src/Java.Lang/Object.cs:338
at Java.Lang.Object.op_Explicit (Java.Lang.Object value) [0x00008] in /Users/builder/data/lanes/monodroid-mlion-monodroid-4.20-series/ba9bbbdd/source/monodroid/src/Mono.Android/src/Java.Lang/Object.cs:499
at Messages.SMSBroadcastReceiver.OnReceive (Android.Content.Context context, Android.Content.Intent intent) [0x000ba] in c:\Users\Jase\Documents\Projects\Messages\Messages\SMSBroadcastReceiver.cs:52
, , . ( ) 60 Google, -. , , , , , , , .
:
// var castedPdus = JNIEnv.GetObjectArrayElement(pdus.Handle, 0);
// Object castedPdus = (Object)bundle.Get("pdus");
// var castedPdus = JNIEnv.GetArray<Java.Lang.Object>(pdus.Handle);
.
, , " ", " [] ". , . , " ", , , "". SMS Xamarin , . , - . , . .
, Java Android Studio, , , .
SmsReceiver.java:
package com.your.app;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.telephony.SmsMessage;
import android.util.Log;
import android.widget.Toast;
public class SmsReceiver extends BroadcastReceiver {
private static final String SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED";
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(SMS_RECEIVED)) {
Bundle bundle = intent.getExtras();
if (bundle != null) {
// get sms objects
Object[] pdus = (Object[]) bundle.get("pdus");
if (pdus.length == 0) {
return;
}
// large message might be broken into many
SmsMessage[] messages = new SmsMessage[pdus.length];
StringBuilder sb = new StringBuilder();
for (int i = 0; i < pdus.length; i++) {
messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
sb.append(messages[i].getMessageBody());
}
String sender = messages[0].getOriginatingAddress();
Log.d("SNDR", sender);
String message = sb.toString();
Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
// prevent any other broadcast receivers from receiving broadcast
abortBroadcast();
}
}
}
}
AndroidManifest.xml.
AndroidManifest.xml:
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<application
android:allowBackup="true"
android:icon="@drawable/icon"
android:label="@string/app_name"
android:theme="@style/AppTheme">
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name="com.your.app.SmsReceiver" android:enabled="true">
<intent-filter android:priority="2147483647">
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
</application>
, , Java, pdu Android 5.0.
Java.Lang.Object rawPdus = intent.Extras.Get("pdus");
int length = JNIEnv.GetArrayLength(rawPdus.Handle);
if (length < 1)
return;
var pdus = JNIEnv.GetArrayItem<byte[]>(rawPdus.Handle, 0);
var msg = SmsMessage.CreateFromPdu(pdus);
, . Bugzilla Issue 26674.
Here is another alternative:
[BroadcastReceiver(Enabled = true, Label = "SMS Receiver")]
[IntentFilter(new[] { "android.provider.Telephony.SMS_RECEIVED" })]
public class SMSBroadcastReceiver : BroadcastReceiver, ISMSReceiver
{
private const string Tag = "SMSBroadcastReceiver";
private const string IntentAction = "android.provider.Telephony.SMS_RECEIVED";
public override void OnReceive(Context context, Intent intent)
{
Log.Info(Tag, "Intent received: " + intent.Action);
if (intent.Action != IntentAction) return;
SmsMessage[] messages=Telephony.Sms.Intents.GetMessagesFromIntent (intent);
var sb = new StringBuilder();
for (var i = 0; i < messages.Length; i++)
{
sb.Append(string.Format("SMS From: {0}{1}Body: {2}{1}", messages[i].OriginatingAddress,
Environment.NewLine,messages[i].MessageBody));
}
}
}