Search code examples
javaandroidnotificationsandroid-pendingintentbroadcast

PendingIntent.getBroadcast not working on for the default notification click/touch event in the notifications drawer - Android Studio 2.3.3 + Java


I have wired up a notifications action handler with PendingIntent.getBroadcast that shows actions inside the notification. The actions work fine, when I use the default click event on the heads up notification it works fine. My issue comes when the notification is in the tray and I have other notifications in the drawer, I am trying to program the default click/touch event on the notification to broadcast to the receiver and run an action. Here is some code:

Uri alertSound = Uri.parse("android.resource://" + ctx.getPackageName() + "/raw/page_the_doctor");

        NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(ctx)
            .setAutoCancel(true)
            .setSmallIcon(R.mipmap.telemed_logo)
            .setContentTitle("PATIENT READY")
            .setContentText(notification)
            .setDefaults( Notification.DEFAULT_VIBRATE | Notification.DEFAULT_LIGHTS)
            .setSound( alertSound )
            .setPriority(Notification.PRIORITY_MAX)
            .setAutoCancel(true);

        //CLICK ON NOTIFICATION HERE ONLY WORKS ON HEADS UP AND NOT DEFAULT
        Intent notificationIntent = new Intent(ctx, PushNotificationActions.class);
        notificationIntent.putExtra("visitId", visitId);
        notificationIntent.putExtra("link", link);
        notificationIntent.setAction(ACCEPT_EXAM);
        notificationIntent = notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        PendingIntent clickIntent = PendingIntent.getBroadcast(ctx, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        notificationBuilder.setContentIntent(clickIntent);

        //Accept intent action works fine
        Intent acceptExam = new Intent(ctx, PushNotificationActions.class);
        acceptExam.setAction(ACCEPT_EXAM);
        acceptExam.putExtra("visitId", visitId);
        acceptExam.putExtra("link", link);
        PendingIntent pendingAcceptIntent = PendingIntent.getBroadcast(ctx, Integer.parseInt(visitId), acceptExam, PendingIntent.FLAG_UPDATE_CURRENT);
        notificationBuilder.addAction(R.drawable.accept_action_24dp, "ACCEPT", pendingAcceptIntent);

        //Dismiss intent action works fine
        Intent dismissExam = new Intent(ctx, PushNotificationActions.class);
        dismissExam.setAction(DISMISS_EXAM);
        dismissExam.putExtra("visitId", visitId);
        dismissExam.putExtra("link", link);
        PendingIntent pendingDismissIntent = PendingIntent.getBroadcast(ctx, Integer.parseInt(visitId), dismissExam, PendingIntent.FLAG_UPDATE_CURRENT);
        notificationBuilder.addAction(R.drawable.dismiss_action_24dp, "DISMISS", pendingDismissIntent);

        Notification noti = notificationBuilder.build();
        noti.flags |= Notification.FLAG_AUTO_CANCEL | Notification.FLAG_SHOW_LIGHTS;

        NotificationManager mNotificationManager = (NotificationManager) ctx.getSystemService(Context.NOTIFICATION_SERVICE);
        mNotificationManager.notify(Integer.parseInt(visitId), noti);

Here is the onReceive method:

private Context context;

    @Override
    public void onReceive(Context ctx, final Intent intent) {
        Log.d("PushNotificationActions","Started");
        String action = intent.getAction();
        Log.d("<-------------------<<<", "getaction is: " + action);
        context = ctx;
        if (ACCEPT_EXAM.equals(action)) {
            Log.d("ACCEPT_ACTION", "READY FOR EXAM NOW");
            Map<String, String> params = new HashMap();
            params.put("email", email);
            final JSONObject parameters = new JSONObject(params);
            Log.d("parameters: ", parameters.toString());
            volleyJsonObjectPost("ws", parameters, new Login.ServerCallback() {
                public void onSuccess(JSONObject response) {
                    try {
                        final JSONObject loginData = response.getJSONObject("d");

                        DataModel.sharedInstance().key = loginData.getString("key");
                        final String visitLink; String link; final String visitId; Bundle extras = intent.getExtras();
                        if(extras != null) {
                            link = extras.getString("link");
                            visitId = extras.getString("visitId");
                            visitLink = link + loginData.getString("key") + ',' + visitId;

                            JSONObject params = new JSONObject();
                            params.put("key", loginData.getString("key"));
                            Log.d("params: ", params.toString());
                            volleyJsonObjectPost("ws", params, new Login.ServerCallback() {
                                public void onSuccess(JSONObject result) {
                                    try {
                                        final JSONObject acceptExamResultData = result.getJSONObject("d");
                                        Log.d("acceptExamResultData: ", acceptExamResultData.toString());


                                        if (acceptExamResultData.getBoolean("status") == true) {
                                            Intent intent=new Intent(Intent.ACTION_VIEW, Uri.parse(visitLink));
                                            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                                            intent.setPackage("com.android.chrome");
                                            try {
                                                context.startActivity(intent);
                                                NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
                                                mNotificationManager.cancel(Integer.parseInt(visitId));
                                            } catch (ActivityNotFoundException ex) {
                                                // Chrome browser presumably not installed so allow user to choose instead
                                                intent.setPackage(null);
                                                context.startActivity(intent);
                                                NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
                                                mNotificationManager.cancel(Integer.parseInt(visitId));
                                                Intent closeIntent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
                                                context.sendBroadcast(closeIntent);
                                            }
                                        }else {
                                            // Exam was already accepted by another Doc
                                        }



                                    } catch (JSONException e) {
                                        e.printStackTrace();
                                    }
                                }
                            });


                        }
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
            });

        }else if (DISMISS_EXAM.equals(action)) {
            Log.d("DISMISS_ACTION", "I CANNOT TAKE THIS EXAM");
            String visitId; Bundle extras = intent.getExtras();
            if(extras != null) {
                visitId = extras.getString("visitId");
                NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
                Log.d("Visit ID to cancel", visitId);
                mNotificationManager.cancel(Integer.parseInt(visitId));
                Intent closeIntent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
                context.sendBroadcast(closeIntent);
            }

        }

Here is the receiver in the manifest:

<receiver android:name=".PushNotificationActions" >
            <intent-filter>
                <action android:name="com.Telemed.app.ACCEPT_EXAM" />
                <action android:name="com.Telemed.app.DISMISS_EXAM" />
            </intent-filter>
        </receiver>

Since the notification won't slide easy in the drawer in most cases I need this default functionality to mirror the Accept Exam Action. Only I don't want it to be an action, I just want it to work when the user clicks on the notification. I need to use getBroadcast because I am making a web service call (async) to get some data I need to do the next step


Solution

  • So in order to set the default functionality for the notification you have to create a default pending intent before constructing your notification builder:

    Like so:

    //CLICK ON NOTIFICATION
            Intent notificationIntent = new Intent(ctx, PushNotificationActions.class).setAction(ACCEPT_EXAM).putExtra("visitId", visitId).putExtra("link", link);
            PendingIntent clickIntent = PendingIntent.getBroadcast(ctx, Integer.parseInt(visitId), notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
    

    Now after that set this:

    .setContentIntent(clickIntent)
    

    in the new NotificationCompat.Builder. After that you can set up as many actions as you want but the default will still access your action and act as a default in the case where the drawer sticks your notification at the to and you cannot see your programmed actions.

    Uri alertSound = Uri.parse("android.resource://" + ctx.getPackageName() + "/raw/page_the_doctor");
    
            //CLICK ON NOTIFICATION
            Intent notificationIntent = new Intent(ctx, PushNotificationActions.class).setAction(ACCEPT_EXAM).putExtra("visitId", visitId).putExtra("link", link);
            PendingIntent clickIntent = PendingIntent.getBroadcast(ctx, Integer.parseInt(visitId), notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
    
            NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(ctx)
                    .setAutoCancel(true)
                    .setSmallIcon(R.mipmap.telemed_logo)
                    .setContentTitle("TELEMED PATIENT READY")
                    .setContentText(notification)
                    .setDefaults( Notification.DEFAULT_VIBRATE | Notification.DEFAULT_LIGHTS)
                    .setSound( alertSound )
                    .setPriority(Notification.PRIORITY_MAX)
                    .setContentIntent(clickIntent)
                    .setAutoCancel(true);
    
            //Accept intent
            Intent acceptExam = new Intent(ctx, PushNotificationActions.class).setAction(ACCEPT_EXAM).putExtra("visitId", visitId).putExtra("link", link);
            PendingIntent pendingAcceptIntent = PendingIntent.getBroadcast(ctx, Integer.parseInt(visitId), acceptExam, PendingIntent.FLAG_UPDATE_CURRENT);
            notificationBuilder.addAction(R.drawable.accept_action_24dp, "ACCEPT", pendingAcceptIntent);
    
            //Dismiss intent
            Intent dismissExam = new Intent(ctx, PushNotificationActions.class).setAction(DISMISS_EXAM).putExtra("visitId", visitId).putExtra("link", link);
            PendingIntent pendingDismissIntent = PendingIntent.getBroadcast(ctx, Integer.parseInt(visitId), dismissExam, PendingIntent.FLAG_UPDATE_CURRENT);
            notificationBuilder.addAction(R.drawable.dismiss_action_24dp, "DISMISS", pendingDismissIntent);
    
            Notification noti = notificationBuilder.build();
            noti.flags |= Notification.FLAG_AUTO_CANCEL | Notification.FLAG_SHOW_LIGHTS;
    
            NotificationManager mNotificationManager = (NotificationManager) ctx.getSystemService(Context.NOTIFICATION_SERVICE);
            mNotificationManager.notify(Integer.parseInt(visitId), noti);