Search code examples
androidnotificationsbroadcastreceiverandroid-notifications

android: Calling function from Broadcastreceiver: Unable to start receiver ... java.lang.ClassCastException: android.app.ReceiveRestrictedContext


I am trying to call a function from an activity called "TrackingScreen" from a Broadcast Receiver called "Notification Activity" by means of a button in an action button in the notification.

The code causes the program to crash with the error as mentioned in the title.

Thanks in advance for any help on this :)

Here are the codes:

Code for Creating Notification in TrackingScreen.java

public void updateNotification(){

      boolean firstTime = true;

      NotificationManager mNotificationManager =
                (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

        nID = 1;     

        NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this);


        Intent intent= new Intent(this, TrackingScreen.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);

        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_ONE_SHOT);
        mBuilder.setContentIntent(pendingIntent);




        Intent stoptracking = new Intent(TrackingScreen.this, NotificationActivity.class);
        stoptracking.putExtra("notificationId",nID);
        PendingIntent btPendingIntent = PendingIntent.getBroadcast(this, 0, stoptracking,0);


        mBuilder.setSmallIcon(R.drawable.ic_launcher)
        .setContentTitle("MRT Alarm - Tracking Location")
        .setOnlyAlertOnce(true)
        .setWhen(0)
        .addAction(R.drawable.fail, "Stop Tracking", btPendingIntent);

        if (distance < 1500){
            mBuilder.setContentText("Distance Remaining: " + distance + " m");

        }else if (distance > 1500){
            mBuilder.setContentText("Distance Remaining: " + distance/1000 + " km");


        }

        mNotificationManager.notify(nID, mBuilder.build());
    }

Code for Stop Tracking function called by Broadcast Receiver in TrackingScreen.java

public void stoptracking(){

        TrackingScreen.this.unregisterReceiver(TrackingScreen.this.proximityIntentReceiver);    
        NotificationManager notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.cancel(nID);
        selection = null;
        mUpdater.removeCallbacks(mUpdateView);
        index = 0;
        Intent intent = new Intent();
        setResult(2,intent);
        TrackingScreen.this.finish();       

}

Code for Broadcast Receiver in NotificationActivity.java

public class NotificationActivity extends BroadcastReceiver {




@Override
public void onReceive(Context context, Intent intent) {

    int notificationId = intent.getIntExtra("notificationId", 0);


    TrackingScreen localtrackingscreen = (TrackingScreen)context;
//    localtrackingscreen.stoptracking();


    NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
    manager.cancel(notificationId);
}



}  

Manifest

    <receiver
android:name=".NotificationActivity"
android:enabled="true"
>
</receiver>

LOGCAT

  02-02 16:48:39.277: E/AndroidRuntime(17152): FATAL EXCEPTION: main
02-02 16:48:39.277: E/AndroidRuntime(17152): java.lang.RuntimeException: Unable to start receiver com.androidhive.googleplacesandmaps.NotificationActivity: java.lang.ClassCastException: android.app.ReceiverRestrictedContext cannot be cast to com.androidhive.googleplacesandmaps.TrackingScreen
02-02 16:48:39.277: E/AndroidRuntime(17152):    at android.app.ActivityThread.handleReceiver(ActivityThread.java:2495)
02-02 16:48:39.277: E/AndroidRuntime(17152):    at android.app.ActivityThread.access$1500(ActivityThread.java:150)
02-02 16:48:39.277: E/AndroidRuntime(17152):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1374)
02-02 16:48:39.277: E/AndroidRuntime(17152):    at android.os.Handler.dispatchMessage(Handler.java:99)
02-02 16:48:39.277: E/AndroidRuntime(17152):    at android.os.Looper.loop(Looper.java:213)
02-02 16:48:39.277: E/AndroidRuntime(17152):    at android.app.ActivityThread.main(ActivityThread.java:5225)
02-02 16:48:39.277: E/AndroidRuntime(17152):    at java.lang.reflect.Method.invokeNative(Native Method)
02-02 16:48:39.277: E/AndroidRuntime(17152):    at java.lang.reflect.Method.invoke(Method.java:525)
02-02 16:48:39.277: E/AndroidRuntime(17152):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:741)
02-02 16:48:39.277: E/AndroidRuntime(17152):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:557)
02-02 16:48:39.277: E/AndroidRuntime(17152):    at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:126)
02-02 16:48:39.277: E/AndroidRuntime(17152):    at dalvik.system.NativeStart.main(Native Method)
02-02 16:48:39.277: E/AndroidRuntime(17152): Caused by: java.lang.ClassCastException: android.app.ReceiverRestrictedContext cannot be cast to com.androidhive.googleplacesandmaps.TrackingScreen
02-02 16:48:39.277: E/AndroidRuntime(17152):    at com.androidhive.googleplacesandmaps.NotificationActivity.onReceive(NotificationActivity.java:23)
02-02 16:48:39.277: E/AndroidRuntime(17152):    at android.app.ActivityThread.handleReceiver(ActivityThread.java:2488)
02-02 16:48:39.277: E/AndroidRuntime(17152):    ... 11 more

Solution

  • try this code

    public class TrackingScreen extends Activity {
    
        public static TrackingScreen instance = null;
    
        public void onCreate(Bundle savedInstanceState) {
            instance = this;
        }
    }
    

    and in the onRecieve function:

    public void onReceive(Context context, Intent intent) {
    
        int notificationId = intent.getIntExtra("notificationId", 0);
        TrackingScreen localtrackingscreen = TrackingScreen.instance;
        localtrackingscreen.stoptracking();
        NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
        manager.cancel(notificationId);
    }