简体   繁体   English

从广播接收器android调用活动方法?

[英]Call activity method from broadcast receiver android?

In my application I am sending a port SMS to the mobile.在我的应用程序中,我正在向手机发送端口 SMS。 And when the message is recieved I need to perform some task in my activity and update the UI.当收到消息时,我需要在我的活动中执行一些任务并更新 UI。

Manifest Declaration of receiver接收方的清单声明

 <receiver android:name="com.vfi.BinarySMSReceiver" >
        <intent-filter android:priority="10" >
            <action android:name="android.intent.action.DATA_SMS_RECEIVED" />

            <data
                android:host="*"
                android:port="9512"
                android:scheme="sms" />
        </intent-filter>
    </receiver>

Receiver class接收器类

public class BinarySMSReceiver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
    Bundle bundle = intent.getExtras();
    SmsMessage[] msgs = null;

    if (null != bundle) {
        String info = "SMS from ";
        String sender = "";
        String msg = "";

        Object[] pdus = (Object[]) bundle.get("pdus");

        msgs = new SmsMessage[pdus.length];
        byte[] data = null;

        for (int i = 0; i < msgs.length; i++) {
            msgs[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
            sender += msgs[i].getOriginatingAddress();
            info += msgs[i].getOriginatingAddress() + "\n";

            data = msgs[i].getUserData();

            for (int index = 0; index < data.length; ++index) {
                info += Character.toString((char) data[index]);
                msg += Character.toString((char) data[index]);
            }
        }
        Log.e("SakjsdMS", "akjsdhkas" + msg);
        Log.e("sender", "asdasdasdasdasdasd" + info);

        ((VerifyActivity)context).msgReceived(msg);
    }
}
}

Method in activity活动中的方法

public  void msgReceived(String msgContent)
{
    if(msgContent.equalsIgnoreCase(etMobile.getText().toString().trim())){
        showToast("Number Verified");
    }else{
        showToast("Sorry wrong number. Input your number again.");
    }

}

The exception I get我得到的例外

java.lang.RuntimeException: Unable to start receiver com.vfi.BinarySMSReceiver: java.lang.ClassCastException: android.app.ReceiverRestrictedContext cannot be cast to com.vfi.VerifyActivity
        at android.app.ActivityThread.handleReceiver(ActivityThread.java:2467)
        at android.app.ActivityThread.access$1700(ActivityThread.java:145)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1319)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:136)
        at android.app.ActivityThread.main(ActivityThread.java:5127)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:515)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:825)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:641)
        at dalvik.system.NativeStart.main(Native Method)
 Caused by: java.lang.ClassCastException: android.app.ReceiverRestrictedContext cannot be cast to com.vfi.VerifyActivity
        at com.vfi.BinarySMSReceiver.onReceive(BinarySMSReceiver.java:46)
        at android.app.ActivityThread.handleReceiver(ActivityThread.java:2460)

at android.app.ActivityThread.access$1700(ActivityThread.java:145)在 android.app.ActivityThread.access$1700(ActivityThread.java:145)

How can I get activity context in reciever to call my method??如何在接收器中获取活动上下文以调用我的方法?

I was able to solve it by declaring receiver programmatically:我能够通过以编程方式声明接收器来解决它:

In the activity befor sending the message在发送消息之前的活动中

private void sendSMS() {
    BinarySMSReceiver smsReceiver = null;
    smsReceiver = new BinarySMSReceiver();
    smsReceiver.setActivityHandler(this);
    IntentFilter portIntentFilter = new IntentFilter("android.intent.action.DATA_SMS_RECEIVED");
    portIntentFilter.addDataAuthority("*", "9512");
    portIntentFilter.addDataScheme("sms");
    registerReceiver(smsReceiver, portIntentFilter);



        String messageText = etMobile.getText().toString().trim();
        short SMS_PORT = 9512;
        SmsManager smsManager = SmsManager.getDefault();
        smsManager.sendDataMessage(etMobile.getText().toString().trim(), null, SMS_PORT, messageText.getBytes(), null, null);
}

In receiver class在接收器类中

 public class BinarySMSReceiver extends BroadcastReceiver {
    VerifyActivity vAct = null;

    void setActivityHandler(VerifyActivity main) {
        vAct = main;
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        Bundle bundle = intent.getExtras();
        SmsMessage[] msgs = null;

        if (null != bundle) {
            String info = "SMS from ";
            String sender = "";
            String msg = "";

            Object[] pdus = (Object[]) bundle.get("pdus");

            msgs = new SmsMessage[pdus.length];
            byte[] data = null;

            for (int i = 0; i < msgs.length; i++) {
                msgs[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
                sender += msgs[i].getOriginatingAddress();
                info += msgs[i].getOriginatingAddress() + "\n";

                data = msgs[i].getUserData();

                for (int index = 0; index < data.length; ++index) {
                    info += Character.toString((char) data[index]);
                    msg += Character.toString((char) data[index]);
                }
            }

            Log.e("message", "receiver " + msg);
            Log.e("sender", "from " + info);
            vAct.msgReceived(msg);  //activity method
        }
    }
}

Unregister the receiver取消注册接收器

 @Override
protected void onPause() {
    super.onPause();
    unregisterReceiver(smsReceiver);
}

The error you get is that you are wrongly casting a android.app.ReceiverRestrictedContext to a com.vfi.VerifyActivity .您得到的错误是您错误地将android.app.ReceiverRestrictedContext转换为com.vfi.VerifyActivity

If you want to achieve what you want to do simply start your activity by giving it some extra information.如果您想实现您想做的事情,只需提供一些额外信息即可开始您的活动。

public class BinarySMSReceiver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
    Bundle bundle = intent.getExtras();
    SmsMessage[] msgs = null;

    if (null != bundle) {
        String info = "SMS from ";
        String sender = "";
        String msg = "";

        Object[] pdus = (Object[]) bundle.get("pdus");

        msgs = new SmsMessage[pdus.length];
        byte[] data = null;

        for (int i = 0; i < msgs.length; i++) {
            msgs[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
            sender += msgs[i].getOriginatingAddress();
            info += msgs[i].getOriginatingAddress() + "\n";

            data = msgs[i].getUserData();

            for (int index = 0; index < data.length; ++index) {
                info += Character.toString((char) data[index]);
                msg += Character.toString((char) data[index]);
            }
        }
        Log.e("SakjsdMS", "akjsdhkas" + msg);
        Log.e("sender", "asdasdasdasdasdasd" + info);

        // HERE COMES THE CHANGE
        Intent intent = new Intent(context, YourActivityToLaunch.class);
        intent.putExtra("message_received", msg);
        context.startActivity(intent);
    }
}
}

And in your other class simply retrieve your message this way :在您的其他班级中,只需以这种方式检索您的消息:

Intent intent = getIntent();
String message = intent.getStringExtra("message_received");

That's it.就是这样。

Hope this help !希望这有帮助!

The Context that your BinarySMSReceiver is passed in onReceive is not an Activity - it is the Context in which the receiver is running .您的BinarySMSReceiveronReceive传递的Context不是活动 - 它是接收器运行上下文 To start an Activity, you need to use context.startActivity(Intent) and pass any additional data to the Activity using the Intent.要启动 Activity,您需要使用context.startActivity(Intent)并使用context.startActivity(Intent)将任何其他数据传递给 Activity。

that ((VerifyActivity)context).msgReceived(msg);((VerifyActivity)context).msgReceived(msg); that's your mistake.那是你的错误。 Why are you assuming that this context is your activity?为什么你假设这个上下文是你的活动?

The best way (without 3rd party libraries) to do this is to send a local broadcast.最好的方法(没有 3rd 方库)是发送本地广播。

On this other answer I gave a general idea on how to use LocalBroadcast Best practice to launch AsyncTask from custom view在另一个答案中,我对如何使用LocalBroadcast 最佳实践从自定义视图启动 AsyncTask给出了一个大致的想法

if you're Ok using 3rd party libraries I suggest you check Otto from Square如果您可以使用 3rd 方库,我建议您查看Square Otto

Your BroadcastReceiver doesn't know anything about any activity by default.默认情况下,您的 BroadcastReceiver 对任何活动一无所知。 You will have to give the context to it, for example in your constructor when you create the broadcastReceiver.您必须为其提供上下文,例如在创建广播接收器时在构造函数中。

private Activity activity;
public BroadcastReceiver(Activity activity) {
    super();
    this.activity = activity;
}

In you onReceive method you will now be able to use your activity in whatever way you like.在您的 onReceive 方法中,您现在可以以任何您喜欢的方式使用您的活动。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM