Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android 10 Incoming call notification like whats app when we are in another app

Once we received FCM push notification message in android 10 background start activities restricted. Need a solution like WhatsApp and Skype notification incoming call when we are in another app.

enter image description here

int NOTIFICATIONID = 1234;
       // Uri sound =  RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        Uri sound = Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.capv_callingtone);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationManager notificationManager =
                    (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

            AudioAttributes audioAttributes = new AudioAttributes.Builder()
                    .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
                    .setUsage(AudioAttributes.USAGE_NOTIFICATION)
                    .build();
            String CHANNEL_ID = BuildConfig.APPLICATION_ID.concat("_notification_id");
            String CHANNEL_NAME = BuildConfig.APPLICATION_ID.concat("_notification_name");
            assert notificationManager != null;

            NotificationChannel mChannel = notificationManager.getNotificationChannel(CHANNEL_ID);
            if (mChannel == null) {
                mChannel = new NotificationChannel(CHANNEL_ID, CHANNEL_NAME, NotificationManager.IMPORTANCE_HIGH);
                mChannel.setSound(sound, audioAttributes);
                notificationManager.createNotificationChannel(mChannel);
            }
            in.setClass(CapVFirebaseMessagingService.this, DashBoardActivity.class);
            in.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
            in.putExtra(NOTIFICATION_ID, NOTIFICATIONID);
            Intent buttonIntent = new Intent(getBaseContext(), NotificationReceiver.class);
            buttonIntent.putExtra(NOTIFICATION_ID, NOTIFICATIONID);
            buttonIntent.putExtra(CapV.MESSAGE_TYPE,in.getSerializableExtra(CapV.MESSAGE_TYPE));
            Log.d("Audiotask",""+in.getSerializableExtra(CapV.MESSAGE_TYPE));
            PendingIntent dismissIntent = PendingIntent.getBroadcast(getBaseContext(), 0, buttonIntent, 0);
            SharedPreferences localPrefs = getSharedPreferences(LOCAL_PREFERENCES,MODE_PRIVATE);
            SharedPreferences.Editor editor = getSharedPreferences(LOCAL_PREFERENCES, MODE_PRIVATE).edit();
            editor.putBoolean("Fragment_created",true).commit();
            editor.putBoolean("Incoming_call",true).commit();
            // The PendingIntent to launch activity.
            PendingIntent activityPendingIntent = PendingIntent.getActivity(this, 0,
                    in, 0);
            NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID);

            builder.setSmallIcon(R.drawable.logo)
                    .setContentTitle(("Incoming Call"))
                    .setContentText("Group")
                    .setDefaults(0)
                    .addAction(R.drawable.answer, getString(R.string.answer),
                            activityPendingIntent)
                    .addAction(R.drawable.reject, getString(R.string.reject),
                            dismissIntent)
                    .setPriority(NotificationCompat.PRIORITY_MAX)
                    .setCategory(NotificationCompat.CATEGORY_CALL)
                    .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
                    .setSound(sound)
                    .setOngoing(true);
            android.app.Notification notification = builder.build();
            notificationManager.notify(1234, notification);

Any help will be highly appreciated.

below code for foreground service and a time-sensitive notification.

startForeground(1234, getNotification(incomingCallIntent));

private android.app.Notification getNotification(Intent in) {



    in.putExtra(EXTRA_STARTED_FROM_NOTIFICATION, true);

   PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,in, PendingIntent.FLAG_UPDATE_CURRENT);
    NotificationCompat.Builder builder = new NotificationCompat.Builder(this,"")
            .setSmallIcon(R.drawable.logo)
            .setAutoCancel(true)
            .setPriority(NotificationCompat.PRIORITY_HIGH)
            .setFullScreenIntent(pendingIntent, true);

    // Set the Channel ID for Android O.
        //builder.setChannelId("115"); // Channel ID

   return builder.build();


}
like image 982
user1847921 Avatar asked Jan 22 '20 14:01

user1847921


People also ask

Why incoming call are not showing while on another call?

Enable special app access If you are using another application during an incoming call, the incoming call might not show on the screen, but the phone is ringing. This is because you have not enabled special app access. To enable this feature open your phone settings and follow the steps.

How can I fix WhatsApp call notification?

Make sure Do not disturb is turned off or you have allowed WhatsApp notifications in priority mode in your phone's Settings app > Sound > Do not disturb. Make sure all of WhatsApp's permissions are granted in your phone's Settings app > Apps > WhatsApp > Permissions.


1 Answers

I find a solution for that. You need to create a foreground service for that. This will also help you to show the ringing dialer on the lock screen also. In this code, I add ringtone and vibration.

CallNotificationService

public class HeadsUpNotificationService extends Service implements MediaPlayer.OnPreparedListener  {
private String CHANNEL_ID = AppController.getInstance().getContext().getString(R.string.app_name)+"CallChannel";
private String CHANNEL_NAME = AppController.getInstance().getContext().getString(R.string.app_name)+"Call Channel";MediaPlayer mediaPlayer;
Vibrator mvibrator;
AudioManager audioManager;
AudioAttributes  playbackAttributes;
private Handler handler;
AudioManager.OnAudioFocusChangeListener afChangeListener;
private boolean status = false;
private boolean vstatus = false;


@Nullable
@Override
public IBinder onBind(Intent intent) {
    return null;
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    Bundle data = null;
    String name="",callType="";
    int NOTIFICATION_ID=120;try {
        audioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE);

        if (audioManager != null) {
            switch (audioManager.getRingerMode()) {
                case AudioManager.RINGER_MODE_NORMAL:
                    status = true;
                    break;
                case AudioManager.RINGER_MODE_SILENT:
                    status = false;
                    break;
                case AudioManager.RINGER_MODE_VIBRATE:
                    status = false;
                    vstatus=true;
                    Log.e("Service!!", "vibrate mode");
                    break;
            }
        }

        if (status) {
            Runnable delayedStopRunnable = new Runnable() {
                @Override
                public void run() {
                    releaseMediaPlayer();
                }
            };

            afChangeListener =  new AudioManager.OnAudioFocusChangeListener() {
               public void onAudioFocusChange(int focusChange) {
                   if (focusChange == AudioManager.AUDIOFOCUS_LOSS) {
                       // Permanent loss of audio focus
                       // Pause playback immediately
                       //mediaController.getTransportControls().pause();
                       if (mediaPlayer!=null) {
                           if (mediaPlayer.isPlaying()) {
                               mediaPlayer.pause();
                           }
                       }
                       // Wait 30 seconds before stopping playback
                       handler.postDelayed(delayedStopRunnable,
                               TimeUnit.SECONDS.toMillis(30));
                   }
                   else if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT) {
                       // Pause playback
                   } else if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK) {
                       // Lower the volume, keep playing
                   } else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) {
                       // Your app has been granted audio focus again
                       // Raise volume to normal, restart playback if necessary
                   }
               }
           };
             KeyguardManager keyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);


            mediaPlayer= MediaPlayer.create(this, Settings.System.DEFAULT_RINGTONE_URI);
            mediaPlayer.setLooping(true);
            //mediaPlayer.setAudioStreamType(AudioManager.STREAM_VOICE_CALL);

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                 handler = new Handler();


              playbackAttributes = new AudioAttributes.Builder()
                    .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)
                    .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
                    .build();

                AudioFocusRequest focusRequest = new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN_TRANSIENT)
                        .setAudioAttributes(playbackAttributes)
                        .setAcceptsDelayedFocusGain(true)
                        .setOnAudioFocusChangeListener(afChangeListener, handler)
                        .build();
                int res = audioManager.requestAudioFocus(focusRequest);
                if (res == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
                      if(!keyguardManager.isDeviceLocked()) {

                          mediaPlayer.start();
                         }

                }
            }else {

                // Request audio focus for playback
                int result = audioManager.requestAudioFocus(afChangeListener,
                        // Use the music stream.
                        AudioManager.STREAM_MUSIC,
                        // Request permanent focus.
                        AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);

                if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
                    if(!keyguardManager.isDeviceLocked()) {
                        // Start playback
                        mediaPlayer.start();
                    }
                }

            }

        }
        else if(vstatus){
            mvibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
            // Start without a delay
            // Each element then alternates between vibrate, sleep, vibrate, sleep...
            long[] pattern = {0, 250, 200, 250, 150, 150, 75,
                    150, 75, 150};

            // The '-1' here means to vibrate once, as '-1' is out of bounds in the pattern array
            mvibrator.vibrate(pattern,0);
            Log.e("Service!!", "vibrate mode start");

        }

    } catch (Exception e) {
        e.printStackTrace();
    }         
         
    if (intent != null && intent.getExtras() != null) {
       
        data = intent.getExtras();
        name =data.getString("inititator");
        if(AppController.getInstance().getCall_type().equalsIgnoreCase(ApplicationRef.Constants.AUDIO_CALL)){
            callType ="Audio";
        }
        else {
            callType ="Video";
        }

    }
    try {
        Intent receiveCallAction = new Intent(AppController.getInstance().getContext(), CallNotificationActionReceiver.class);

        receiveCallAction.putExtra("ConstantApp.CALL_RESPONSE_ACTION_KEY", "ConstantApp.CALL_RECEIVE_ACTION");
        receiveCallAction.putExtra("ACTION_TYPE", "RECEIVE_CALL");
        receiveCallAction.putExtra("NOTIFICATION_ID",NOTIFICATION_ID);
        receiveCallAction.setAction("RECEIVE_CALL");

        Intent cancelCallAction = new Intent(AppController.getInstance().getContext(), CallNotificationActionReceiver.class);
        cancelCallAction.putExtra("ConstantApp.CALL_RESPONSE_ACTION_KEY", "ConstantApp.CALL_CANCEL_ACTION");
        cancelCallAction.putExtra("ACTION_TYPE", "CANCEL_CALL");
        cancelCallAction.putExtra("NOTIFICATION_ID",NOTIFICATION_ID);
        cancelCallAction.setAction("CANCEL_CALL");

        Intent callDialogAction = new Intent(AppController.getInstance().getContext(), CallNotificationActionReceiver.class);
        callDialogAction.putExtra("ACTION_TYPE", "DIALOG_CALL");
        callDialogAction.putExtra("NOTIFICATION_ID",NOTIFICATION_ID);
        callDialogAction.setAction("DIALOG_CALL");

        PendingIntent receiveCallPendingIntent = PendingIntent.getBroadcast(AppController.getInstance().getContext(), 1200, receiveCallAction, PendingIntent.FLAG_UPDATE_CURRENT);
        PendingIntent cancelCallPendingIntent = PendingIntent.getBroadcast(AppController.getInstance().getContext(), 1201, cancelCallAction, PendingIntent.FLAG_UPDATE_CURRENT);
        PendingIntent callDialogPendingIntent = PendingIntent.getBroadcast(AppController.getInstance().getContext(), 1202, callDialogAction, PendingIntent.FLAG_UPDATE_CURRENT);

        createChannel();
        NotificationCompat.Builder notificationBuilder = null;
        if (data != null) {
           // Uri ringUri= Settings.System.DEFAULT_RINGTONE_URI;
            notificationBuilder = new NotificationCompat.Builder(this, CHANNEL_ID)
                    .setContentTitle(name)
                    .setContentText("Incoming "+callType+" Call")
                    .setSmallIcon(R.drawable.ic_call_icon)
                    .setPriority(NotificationCompat.PRIORITY_MAX)
                    .setCategory(NotificationCompat.CATEGORY_CALL)
                    .addAction(R.drawable.ic_call_decline, getString(R.string.reject_call), cancelCallPendingIntent)
                    .addAction(R.drawable.ic_call_accept, getString(R.string.answer_call), receiveCallPendingIntent)
                    .setAutoCancel(true)
                    //.setSound(ringUri)
                    .setFullScreenIntent(callDialogPendingIntent, true);
            
        }

        Notification incomingCallNotification = null;
        if (notificationBuilder != null) {
            incomingCallNotification = notificationBuilder.build();
        }
        startForeground(NOTIFICATION_ID, incomingCallNotification);

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

    return START_STICKY;
}

@Override
public void onDestroy() {
    super.onDestroy();// release your media player here audioManager.abandonAudioFocus(afChangeListener);
    releaseMediaPlayer();
    releaseVibration();
}

public void createChannel() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        try {
            Uri ringUri= Settings.System.DEFAULT_RINGTONE_URI;
            NotificationChannel channel = new NotificationChannel(CHANNEL_ID, CHANNEL_NAME, NotificationManager.IMPORTANCE_HIGH);
            channel.setDescription("Call Notifications");
            channel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
           /* channel.setSound(ringUri,
                    new AudioAttributes.Builder().setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
                            .setLegacyStreamType(AudioManager.STREAM_RING)
                            .setUsage(AudioAttributes.USAGE_VOICE_COMMUNICATION).build());*/
            Objects.requireNonNull(AppController.getInstance().getContext().getSystemService(NotificationManager.class)).createNotificationChannel(channel);
            
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}public void releaseVibration(){
    try {
        if(mvibrator!=null){
            if (mvibrator.hasVibrator()) {
                mvibrator.cancel();
            }
            mvibrator=null;
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}
private void releaseMediaPlayer() {
    try {
        if (mediaPlayer != null) {
            if (mediaPlayer.isPlaying()) {
                mediaPlayer.stop();
                mediaPlayer.reset();
                mediaPlayer.release();
            }
            mediaPlayer = null;
        }

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

@Override
public void onPrepared(MediaPlayer mediaPlayer) {

}}

Service receiver

CallNotificationActionReceiver

public class CallNotificationActionReceiver extends BroadcastReceiver {


Context mContext;

@Override
public void onReceive(Context context, Intent intent) {
    this.mContext=context;
    if (intent != null && intent.getExtras() != null) {
      
        String action ="";
        action=intent.getStringExtra("ACTION_TYPE");

        if (action != null&& !action.equalsIgnoreCase("")) {
            performClickAction(context, action);
        }

        // Close the notification after the click action is performed.
        Intent iclose = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
        context.sendBroadcast(iclose);
        context.stopService(new Intent(context, CallNotificationService.class));

    }


}
private void performClickAction(Context context, String action) {
    if(action.equalsIgnoreCase("RECEIVE_CALL")) {

        if (checkAppPermissions()) {                
        Intent intentCallReceive = new Intent(mContext, VideoCallActivity.class);
        intentCallReceive.putExtra("Call", "incoming");
            intentCallReceive.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
            mContext.startActivity(intentCallReceive);               
        }
        else{
                    Intent intent = new Intent(AppController.getInstance().getContext(), VideoCallRingingActivity.class);
                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
                    intent.putExtra("CallFrom","call from push");
                    mContext.startActivity(intent);                  
            
        }
    }
    else if(action.equalsIgnoreCase("DIALOG_CALL")){

                // show ringing activity when phone is locked
                Intent intent = new Intent(AppController.getInstance().getContext(), VideoCallRingingActivity.class);
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
                mContext.startActivity(intent);
            }

    else {            
        context.stopService(new Intent(context, CallNotificationService.class));
        Intent it = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
        context.sendBroadcast(it);
    }
}

private Boolean checkAppPermissions() {
    return hasReadPermissions() && hasWritePermissions() && hasCameraPermissions() && hasAudioPermissions();
}

private boolean hasAudioPermissions() {
    return (ContextCompat.checkSelfPermission(AppController.getInstance().getContext(), Manifest.permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED);
}

private boolean hasReadPermissions() {
    return (ContextCompat.checkSelfPermission(AppController.getInstance().getContext(), Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED);
}

private boolean hasWritePermissions() {
    return (ContextCompat.checkSelfPermission(AppController.getInstance().getContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED);
}
private boolean hasCameraPermissions() {
    return (ContextCompat.checkSelfPermission(AppController.getInstance().getContext(), Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED);
}
}

We need to set these two in the manifest inside the application tab

manifest

<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT"/>
<uses-permission android:name="android.permission.VIBRATE" />
  <!-- Incoming call  -->
    <service android:name=".CallNotificationService"/>
    <receiver
        android:name=".CallNotificationActionReceiver"
        android:enabled="true">
        <intent-filter android:priority="999">
            <action android:name="ConstantApp.CALL_RECEIVE_ACTION" />
            <action android:name="ConstantApp.CALL_CANCEL_ACTION"/>
        </intent-filter>
    </receiver>

To start the service you need to call it from your firebase notification service.

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
    Intent serviceIntent = new Intent(getApplicationContext(), CallNotificationService.class);
                                    Bundle mBundle = new Bundle();
                                    mBundle.putString("inititator", name);
                                    mBundle.putString("call_type",callType);
                                    serviceIntent.putExtras(mBundle);
                                    ContextCompat.startForegroundService(getApplicationContext(), serviceIntent);
}

To stop the Notification

getApplicationContext().stopService(new Intent(AppController.getInstance().getContext(), HeadsUpNotificationService.class));
                                    Intent istop = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
                                    getApplicationContext().sendBroadcast(istop);
like image 86
Dinil ps Avatar answered Oct 29 '22 06:10

Dinil ps