Skip to content

Commit

Permalink
Merge pull request #13 from linhvovan29546/fix/prevent-multiple-click
Browse files Browse the repository at this point in the history
fix: #11, #12
feat: Auto launch app when pressed notification, prevent click notification action
  • Loading branch information
linhvovan29546 authored Nov 12, 2022
2 parents 2b97289 + a268373 commit 309e113
Show file tree
Hide file tree
Showing 14 changed files with 222 additions and 104 deletions.
18 changes: 13 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,22 @@ In `AndroidManifest.xml`:
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
<application ....>
<activity android:name="com.reactnativefullscreennotificationincomingcall.IncomingCallActivity"
android:exported="true"
<activity android:name="com.reactnativefullscreennotificationincomingcall.IncomingCallActivity"
android:theme="@style/incomingCall"
android:showOnLockScreen="true"
android:taskAffinity=""
android:launchMode="singleTask"
android:excludeFromRecents="true"
/>
android:exported="true"
android:showWhenLocked="true"
android:turnScreenOn="true"
/>
<activity android:name="com.reactnativefullscreennotificationincomingcall.NotificationReceiverActivity"
android:theme="@style/incomingCall"
android:launchMode="singleTask"
android:excludeFromRecents="true"
android:exported="true"
android:showWhenLocked="true"
android:turnScreenOn="true"
/>
<service
android:name="com.reactnativefullscreennotificationincomingcall.IncomingCallService"
android:enabled="true"
Expand Down
2 changes: 1 addition & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,6 @@ repositories {
dependencies {
//noinspection GradleDynamicVersion
implementation "com.facebook.react:react-native:+" // From node_modules
implementation "com.airbnb.android:lottie:5.0.3" // create ui animation
implementation "com.airbnb.android:lottie:5.1.1" // create ui animation
implementation 'com.squareup.picasso:picasso:2.71828'
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,7 @@ public class Constants {
//event press answer/decline call
public static final String RNNotificationAnswerAction="RNNotificationAnswerAction";
public static final String RNNotificationEndCallAction="RNNotificationEndCallAction";
public static final String onPressNotification="onPressNotification";


}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import android.view.View;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.airbnb.lottie.LottieAnimationView;
import androidx.appcompat.app.AppCompatActivity;
Expand All @@ -26,9 +27,13 @@ public class IncomingCallActivity extends AppCompatActivity {
private TextView tvDecline;
private TextView tvAccept;
private ImageView ivAvatar;
private LottieAnimationView acceptCallBtn;
private LottieAnimationView rejectCallBtn;
private LinearLayout lnDeclineCall;
private LinearLayout lnAcceptCall;

private String uuid = "";
static boolean active = false;
private static Activity fa;
static IncomingCallActivity instance;

public static IncomingCallActivity getInstance() {
Expand Down Expand Up @@ -57,7 +62,6 @@ public void onDestroy() {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
fa = this;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
setShowWhenLocked(true);
setTurnScreenOn(true);
Expand All @@ -69,10 +73,6 @@ protected void onCreate(Bundle savedInstanceState) {
}
}
setContentView(R.layout.activity_call_incoming);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
setShowWhenLocked(true);
setTurnScreenOn(true);
}
getWindow().addFlags(
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
| WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
Expand All @@ -84,11 +84,12 @@ protected void onCreate(Bundle savedInstanceState) {
ivAvatar = findViewById(R.id.ivAvatar);
tvDecline=findViewById(R.id.tvDecline);
tvAccept=findViewById(R.id.tvAccept);
lnDeclineCall = findViewById(R.id.lnDeclineCall);
lnAcceptCall = findViewById(R.id.lnAcceptCall);
Bundle bundle = getIntent().getExtras();
if (bundle != null) {
if (bundle.containsKey("uuid")) {
uuid = bundle.getString("uuid");

}
if (bundle.containsKey("name")) {
String name = bundle.getString("name");
Expand All @@ -114,8 +115,7 @@ protected void onCreate(Bundle savedInstanceState) {
}
}

LottieAnimationView acceptCallBtn = findViewById(R.id.ivAcceptCall);
acceptCallBtn.setOnClickListener(new View.OnClickListener() {
lnAcceptCall.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
try {
Expand All @@ -129,8 +129,7 @@ public void onClick(View view) {
}
});

LottieAnimationView rejectCallBtn = findViewById(R.id.ivDeclineCall);
rejectCallBtn.setOnClickListener(new View.OnClickListener() {
lnDeclineCall.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
dismissDialing(Constants.ACTION_REJECTED_CALL);
Expand Down Expand Up @@ -159,21 +158,7 @@ public void destroyActivity(Boolean isReject) {
private void acceptDialing() {
active=false;
WritableMap params = Arguments.createMap();
params.putBoolean("accept", true);
params.putString("callUUID", uuid);
KeyguardManager mKeyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
if (mKeyguardManager.isDeviceLocked()) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
mKeyguardManager.requestDismissKeyguard(this, new KeyguardManager.KeyguardDismissCallback() {
@Override
public void onDismissSucceeded() {
super.onDismissSucceeded();
}
});
}
}
}
FullScreenNotificationIncomingCallModule.sendEventToJs(Constants.RNNotificationAnswerAction, params);
stopService(new Intent(this, IncomingCallService.class));
if (Build.VERSION.SDK_INT >= 21) {
Expand All @@ -186,7 +171,6 @@ public void onDismissSucceeded() {
private void dismissDialing(String action) {
active=false;
WritableMap params = Arguments.createMap();
params.putBoolean("accept", false);
params.putString("callUUID", uuid);
params.putString("endAction",action);
FullScreenNotificationIncomingCallModule.sendEventToJs(Constants.RNNotificationEndCallAction, params);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,19 @@
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Resources;
import android.graphics.Color;
import android.media.AudioAttributes;
import android.media.AudioManager;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.VibrationEffect;
import android.os.Vibrator;
import android.util.Log;


import androidx.annotation.Nullable;
import androidx.core.app.NotificationCompat;
import androidx.core.content.ContextCompat;
Expand All @@ -37,15 +32,15 @@ public class IncomingCallService extends Service {
public static Handler callhandle;
private String uuid = "";
private Integer timeoutNumber=0;
private boolean isRegistered = false;
// you can perform a click only once time
private Bundle bundleData;
private static final String TAG = "FullscreenSevice";
public int onStartCommand(Intent intent, int flags, int startId) {
String action = intent.getAction();
if (action != null) {
if (action.equals(Constants.ACTION_SHOW_INCOMING_CALL)) {
IntentFilter filter = new IntentFilter();
filter.addAction(Constants.ACTION_PRESS_ANSWER_CALL);
filter.addAction(Constants.ACTION_PRESS_DECLINE_CALL);
getApplicationContext().registerReceiver(mReceiver, filter);
NotificationReceiverHandler.updateCanClick(true);
Bundle bundle = intent.getExtras();
uuid= bundle.getString("uuid");
if(bundle.containsKey("timeout")){
Expand Down Expand Up @@ -78,24 +73,25 @@ public void onTaskRemoved(Intent rootIntent) {
stopSelf();
}

private PendingIntent onButtonNotificationClick(int id, String action) {
Intent buttonIntent= new Intent();
buttonIntent.setAction(action);
return PendingIntent.getBroadcast(this,id , buttonIntent, PendingIntent.FLAG_IMMUTABLE);

private PendingIntent onButtonNotificationClick(int id, String action,String eventName) {
Intent emptyScreenIntent = new Intent(this, NotificationReceiverActivity.class);
emptyScreenIntent.setAction(action);
emptyScreenIntent.putExtras(bundleData);
emptyScreenIntent.putExtra("eventName",eventName);
return PendingIntent.getActivity(this, 0, emptyScreenIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
}

private Notification buildNotification(Context context, Intent intent) {
Intent fullScreenIntent = new Intent(context, IncomingCallActivity.class);

Intent emptyScreenIntent = new Intent(context, NotificationReceiverActivity.class);
Bundle bundle = intent.getExtras();
fullScreenIntent.putExtra("uuid", uuid);
fullScreenIntent.putExtra("name", bundle.getString("name"));
fullScreenIntent.putExtra("avatar", bundle.getString("avatar"));
fullScreenIntent.putExtra("info", bundle.getString("info"));
fullScreenIntent.putExtra("declineText", bundle.getString("declineText"));
fullScreenIntent.putExtra("answerText", bundle.getString("answerText"));
bundleData=bundle;
emptyScreenIntent.putExtras(bundle);
emptyScreenIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
emptyScreenIntent.setAction(Constants.onPressNotification);
String channelId=bundle.getString("channelId");
fullScreenIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent fullScreenPendingIntent = PendingIntent.getActivity(context, 0, fullScreenIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
PendingIntent emptyPendingIntent = PendingIntent.getActivity(context, 0, emptyScreenIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel notificationChannel=new NotificationChannel(channelId, bundle.getString("channelName"), NotificationManager.IMPORTANCE_HIGH);
Expand All @@ -117,16 +113,16 @@ private Notification buildNotification(Context context, Intent intent) {
.setContentText(bundle.getString("info"))
.setPriority(NotificationCompat.PRIORITY_MAX)
.setCategory(NotificationCompat.CATEGORY_CALL)
.setContentIntent(fullScreenPendingIntent)
.setContentIntent(emptyPendingIntent)
.addAction(
0,
bundle.getString("declineText"),
onButtonNotificationClick(0,Constants.ACTION_PRESS_DECLINE_CALL)
onButtonNotificationClick(0,Constants.ACTION_PRESS_DECLINE_CALL,Constants.RNNotificationEndCallAction)
)
.addAction(
0,
bundle.getString("answerText"),
onButtonNotificationClick(1,Constants.ACTION_PRESS_ANSWER_CALL)
onButtonNotificationClick(1,Constants.ACTION_PRESS_ANSWER_CALL,Constants.RNNotificationAnswerAction)
)
.setAutoCancel(true)
.setOngoing(true)
Expand All @@ -138,7 +134,7 @@ private Notification buildNotification(Context context, Intent intent) {
// interacts with the notification. Also, if your app targets Android 10
// or higher, you need to request the USE_FULL_SCREEN_INTENT permission in
// order for the platform to invoke this notification.
.setFullScreenIntent(fullScreenPendingIntent, true);
.setFullScreenIntent(emptyPendingIntent, true);
if(bundle.getString("notificationColor")!=null){
notificationBuilder.setColor(getColorForResourceName(context,bundle.getString("notificationColor")));
}
Expand All @@ -164,6 +160,7 @@ public void onDestroy() {
cancelTimer();
stopForeground(true);
}

public void setTimeOutEndCall(String uuid) {
callhandle=new Handler();
handleTimeout=new Runnable() {
Expand All @@ -186,39 +183,7 @@ public void cancelTimer(){
callhandle.removeCallbacks(handleTimeout);
}
}
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action != null) {
if (action.equals(Constants.ACTION_PRESS_ANSWER_CALL)) {
cancelTimer();

if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
Intent it = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
context.sendBroadcast(it);
}
if (IncomingCallActivity.active) {
IncomingCallActivity.getInstance().destroyActivity(false);
}
WritableMap params = Arguments.createMap();
params.putString("callUUID", uuid);
FullScreenNotificationIncomingCallModule.sendEventToJs(Constants.RNNotificationAnswerAction,params);
stopForeground(true);
}else if(action.equals(Constants.ACTION_PRESS_DECLINE_CALL)){
cancelTimer();
if (IncomingCallActivity.active) {
IncomingCallActivity.getInstance().destroyActivity(false);
}
WritableMap params = Arguments.createMap();
params.putString("callUUID", uuid);
params.putString("endAction", Constants.ACTION_REJECTED_CALL);
FullScreenNotificationIncomingCallModule.sendEventToJs(Constants.RNNotificationEndCallAction,params);
stopForeground(true);
}
}
}
};
private int getResourceIdForResourceName(Context context, String resourceName) {
int resourceId = context.getResources().getIdentifier(resourceName, "drawable", context.getPackageName());
if (resourceId == 0) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.reactnativefullscreennotificationincomingcall;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;

public class NotificationReceiverActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
NotificationReceiverHandler.handleNotification(this, getIntent());
finish();
}

@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
NotificationReceiverHandler.handleNotification(this, intent);
finish();
}
}
Loading

0 comments on commit 309e113

Please sign in to comment.