5

I have an action to Dial a number via

uri = Uri.parse("tel:" + address);
Intent intent = new Intent(Intent.ACTION_DIAL);
intent.setData(uri);
PendingIntent pd = PendingIntent.getActivity(context, 0,intent, 
       PendingIntent.FLAG_UPDATE_CURRENT);
notif.addAction(R.drawable.ic_menu_call, "Call", pd);

but the problem is that I don't know

how/when to call the NotificationManager's manager.cancel() function

so as to dismiss the notification when the call action is clicked!

Andrew Barber
  • 39,603
  • 20
  • 94
  • 123
Daksh
  • 1,177
  • 2
  • 18
  • 28

2 Answers2

2

I had the same situation and I managed to solve it by creating a broadcast receiver that is called when the action button is pressed. The broadcast receiver then receives an intent with the notification id that you want to dismiss and the number you want to dial.

The is the code that creates the notification:

NotificationManager notificationManager =
  (NotificationManager)MyApplication.getAppContext().getSystemService(Context.NOTIFICATION_SERVICE);
//for some versions of android you may need to create a channel with the id you want
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    NotificationChannel chan = new NotificationChannel("your_channel_id", "ChannelName", NotificationManager.IMPORTANCE_DEFAULT);
    notificationManager.createNotificationChannel(chan);
}
Intent intent = new Intent(MyApplication.getAppContext(), ActionReciever.class);
intent.putExtra("phoNo", phoneNumber);

// num is the notification id
intent.putExtra("id", num);

PendingIntent myPendingIntent = PendingIntent.getBroadcast(
                  MyApplication.getAppContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT
                );
Notification n = new NotificationCompat.Builder(MyApplication.getAppContext(),
                        "your_channel_id")
                        .setSmallIcon(R.drawable.app_pic)
                        .addAction(R.drawable.app_pic, "Dial now", myPendingIntent)
                        .setAutoCancel(true)
                        .build();
notificationManager.notify(num, n);

This is the broadcast receiver code, it is called when the action button is pressed. The received intent here is the intent inside the pending intent we prepared in the notification:

public class ActionReciever extends BroadcastReceiver {
    @SuppressLint("MissingPermission")
    @Override
    public void onReceive(Context context, Intent intent) {
        String phoneNumber = intent.getStringExtra("phoNo");
        int id = intent.getIntExtra("id",0);
        Intent i = new Intent(Intent.ACTION_DIAL);
        i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        i.setData(Uri.parse("tel:" + phoneNumber));
        NotificationManager notificationManager =
                (NotificationManager) MyApplication.getAppContext().getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.cancel(id);
        context.startActivity(i);
    }
}

Register the BroadcastReceiver in the app manifest inside application tag

<receiver android:name=".ActionReciever" />

MyApplication is a class that extends the default Application so I can have a place to store the context I need.

public class MyApplication extends Application {
    private static Context context;

    public void onCreate() {
        super.onCreate();
        MyApplication.context = getApplicationContext();
    }

    public static Context getAppContext() {
        return MyApplication.context;
    }

}

Note that you need to update the manifest to run the MyApplication class like this:

android:name="com.example.yourpackage.MyApplication"

This code works even if the app is down and without a background service.

harelon
  • 65
  • 7
0

See Android READ PHONE STATE? - about phone state.

case TelephonyManager.CALL_STATE_RINGING:
    notificationManager = (NotificationManager) context
                .getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.cancel(100); // cancel notification by ID
                    break;

// build your notification.

intent notificationIntent = new Intent(context,
                    YourPhoneActivity.class);
            notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
                    | Intent.FLAG_ACTIVITY_SINGLE_TOP);
            PendingIntent intent = PendingIntent.getActivity(context, 0,
                    notificationIntent, 0);

            Bitmap bm = BitmapFactory.decodeResource(context.getResources(),
                    iconLarge);
            NotificationCompat.Builder builder = new NotificationCompat.Builder(
                    context).setSmallIcon(iconSmall).setLargeIcon(bm)
                    .setContentTitle(title).setContentText(message)
                    .setAutoCancel(false).setContentIntent(intent).setWhen(when)
                    .setTicker(message);
             builder.getNotification();
Community
  • 1
  • 1
Yahor10
  • 2,123
  • 1
  • 13
  • 13
  • for the above, i'll have to launch an activity, right? i want the notification to be dismissed without starting any activity that creates a phonestatelistener. Simply : Receive Notification->Click Call->Open Phone app, and dismiss notification. any other way like a broadcastreceiver? – Daksh Dec 27 '12 at 12:30
  • First - you should create notification somewhere(activity,service) – Yahor10 Dec 27 '12 at 12:45
  • I create the notification inside the BroadcastReceiver. Isn't there a way like to register a Dial intent receiver or something that can simply be started when the Dial intent is being sent? Or any other way that doesn't involve a separate activity to be launched, or a service to be run in the background for such a petty task! – Daksh Dec 27 '12 at 13:00
  • create your notification in a service – Yahor10 Dec 27 '12 at 13:08
  • Even if you create the notification in a service: how do you dismiss a notification which, for example, starts the Bluetooth (with `BluetoothAdapter.ACTION_REQUEST_ENABLE`)? If the user says no, you can't know it has been clicked. – Marc Plano-Lesay Jul 02 '15 at 15:25