diff --git a/README.md b/README.md index d46df17..185fd9a 100644 --- a/README.md +++ b/README.md @@ -146,23 +146,27 @@ export default class App extends Component { start: { notify: true, title: "Start Tracking", - description: "You are now tracked" + description: "You are now tracked", + smallIcon: "ic_notification", }, stop: { notify: true, title: "Stopped Tracking", - description: "You are not tracked any longer" + description: "You are not tracked any longer", + smallIcon: "ic_notification", }, enter: { notify: true, title: "Attention", //[value] will be replaced ob geofences' value attribute - description: "You entered a [value] Zone" + description: "You entered a [value] Zone", + smallIcon: "ic_notification", }, exit: { notify: true, title: "Left Zone", - description: "You left a [value] Zone" + description: "You left a [value] Zone", + smallIcon: "ic_notification", } } ); @@ -242,26 +246,31 @@ type SettingObject { notify: boolean, // If Notification should be fired on start tracking title: string, // Title of Notification description: string // Content of Notification + smallIcon: string // Android Only: Name of the drawable for smallIcon (optional) }, stop: { notify: boolean, title: string, - description: string + description: string, + smallIcon: string }, timeout: { // automatic stop by end of duration notify: boolean, title: string, - description: string + description: string, + smallIcon: string }, enter: { notify: boolean, title: string, - description: string + description: string, + smallIcon: string }, exit: { notify: boolean, title: string, - description: string + description: string, + smallIcon: string }, channel: { // Only Android specific title: string, diff --git a/android/src/main/java/com/simplegeofencing/reactnative/GeofenceTransitionsBroadcastReceiver.java b/android/src/main/java/com/simplegeofencing/reactnative/GeofenceTransitionsBroadcastReceiver.java index fd81bb1..b613e77 100644 --- a/android/src/main/java/com/simplegeofencing/reactnative/GeofenceTransitionsBroadcastReceiver.java +++ b/android/src/main/java/com/simplegeofencing/reactnative/GeofenceTransitionsBroadcastReceiver.java @@ -21,7 +21,7 @@ import android.text.TextUtils; import android.util.Log; import android.widget.Toast; - +import android.content.res.Resources; import com.google.android.gms.location.Geofence; import com.google.android.gms.location.GeofencingEvent; import com.facebook.react.bridge.ReactApplicationContext; @@ -97,6 +97,8 @@ public void onReceive(Context context, Intent intent) { Geofence geofence = geofencesWithoutMonitor.get(0); String title = intent.getStringExtra("notifyEnterStringTitle"); String description = intent.getStringExtra("notifyEnterStringDescription"); + String smallIcon = intent.getStringExtra("notifyEnterStringSmallIcon"); + ArrayList geofenceValues = intent.getStringArrayListExtra("geofenceValues"); ArrayList geofenceKeys = intent.getStringArrayListExtra("geofenceKeys"); int index = geofenceKeys.indexOf(geofence.getRequestId()); @@ -110,6 +112,7 @@ public void onReceive(Context context, Intent intent) { postNotification( title, description, + smallIcon, intent.getStringExtra("notifyChannelStringTitle"), intent.getStringExtra("notifyChannelStringDescription"), intent @@ -125,6 +128,7 @@ public void onReceive(Context context, Intent intent) { Geofence geofence = geofencesWithoutMonitor.get(0); String title = intent.getStringExtra("notifyExitStringTitle"); String description = intent.getStringExtra("notifyExitStringDescription"); + String smallIcon = intent.getStringExtra("notifyExitStringSmallIcon"); ArrayList geofenceValues = intent.getStringArrayListExtra("geofenceValues"); ArrayList geofenceKeys = intent.getStringArrayListExtra("geofenceKeys"); int index = geofenceKeys.indexOf(geofence.getRequestId()); @@ -138,6 +142,7 @@ public void onReceive(Context context, Intent intent) { postNotification( title, description, + smallIcon, intent.getStringExtra("notifyChannelStringTitle"), intent.getStringExtra("notifyChannelStringDescription"), intent @@ -199,6 +204,7 @@ private String getTransitionString(int transitionType) { */ private NotificationCompat.Builder getNotificationBuilder(String title, String content, + String smallIcon, String channelTitle, String channelDescription, Intent pIntent @@ -211,11 +217,15 @@ private NotificationCompat.Builder getNotificationBuilder(String title, //PendingIntent contentIntent = PendingIntent.getBroadcast(this.mContext, NOTIFICATION_ID, intent, PendingIntent.FLAG_UPDATE_CURRENT); //Build notification + Resources res = this.mContext.getResources(); + String packageName = this.mContext.getPackageName(); + int smallIconDrawable = res.getIdentifier(smallIcon, "drawable", packageName); + NotificationCompat.Builder notification = new NotificationCompat.Builder(this.mContext, CHANNEL_ID) .setContentTitle(title) .setStyle(new NotificationCompat.BigTextStyle().bigText(content)) .setContentText(content) - .setSmallIcon(this.mContext.getApplicationInfo().icon) + .setSmallIcon((smallIconDrawable != 0) ? smallIconDrawable : this.mContext.getApplicationInfo().icon) .setContentIntent(contentIntent) .setAutoCancel(true); @@ -238,6 +248,7 @@ private NotificationCompat.Builder getNotificationBuilder(String title, public void postNotification(String title, String content, + String smallIcon, String channelTitle, String channelDescription, Intent pIntent @@ -246,7 +257,7 @@ public void postNotification(String title, // notificationId is a unique int for each notification that you must define notificationManager.notify(NOTIFICATION_TAG, NOTIFICATION_ID, - getNotificationBuilder(title, content, channelTitle, channelDescription, pIntent).build()); + getNotificationBuilder(title, content, smallIcon, channelTitle, channelDescription, pIntent).build()); } public void clearNotification(){ NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this.mContext); diff --git a/android/src/main/java/com/simplegeofencing/reactnative/RNSimpleNativeGeofencingModule.java b/android/src/main/java/com/simplegeofencing/reactnative/RNSimpleNativeGeofencingModule.java index 6b12db5..e7b19d7 100644 --- a/android/src/main/java/com/simplegeofencing/reactnative/RNSimpleNativeGeofencingModule.java +++ b/android/src/main/java/com/simplegeofencing/reactnative/RNSimpleNativeGeofencingModule.java @@ -33,7 +33,7 @@ import com.google.android.gms.location.GeofencingClient; import com.google.android.gms.tasks.OnFailureListener; import com.google.android.gms.tasks.OnSuccessListener; - +import android.content.res.Resources; import java.util.ArrayList; import java.util.List; @@ -53,10 +53,10 @@ public class RNSimpleNativeGeofencingModule extends ReactContextBaseJavaModule { private boolean notifyStop = false; private boolean notifyEnter = false; private boolean notifyExit = false; - private String[] notifyStartString = new String[2]; - private String[] notifyStopString = new String[2]; - private String[] notifyEnterString = new String[2]; - private String[] notifyExitString = new String[2]; + private String[] notifyStartString = new String[3]; + private String[] notifyStopString = new String[3]; + private String[] notifyEnterString = new String[3]; + private String[] notifyExitString = new String[3]; private Long mStartTime; private int mDuration; private LocalBroadcastReceiver mLocalBroadcastReceiver; @@ -96,29 +96,34 @@ public void initNotification(ReadableMap pText){ ReadableMap pChannel = pText.getMap("channel"); notifyChannelString[0] = pChannel.getString("title"); notifyChannelString[1] = pChannel.getString("description"); + ReadableMap pStart = pText.getMap("start"); if(pStart.getBoolean("notify")){ notifyStart = true; notifyStartString[0] = pStart.getString("title"); notifyStartString[1] = pStart.getString("description"); + notifyStartString[2] = pChannel.getString("smallIcon"); } ReadableMap pStop = pText.getMap("stop"); if(pStop.getBoolean("notify")){ notifyStop = true; notifyStopString[0] = pStop.getString("title"); notifyStopString[1] = pStop.getString("description"); + notifyStopString[2] = pStop.getString("smallIcon"); } ReadableMap pEnter = pText.getMap("enter"); if(pEnter.getBoolean("notify")){ notifyEnter = true; notifyEnterString[0] = pEnter.getString("title"); notifyEnterString[1] = pEnter.getString("description"); + notifyEnterString[2] = pEnter.getString("smallIcon"); } ReadableMap pExit = pText.getMap("exit"); if(pExit.getBoolean("notify")){ notifyExit = true; notifyExitString[0] = pExit.getString("title"); notifyExitString[1] = pExit.getString("description"); + notifyExitString[2] = pExit.getString("smallIcon"); } } @@ -218,8 +223,10 @@ public void onSuccess(Void aVoid) { Intent notificationIntent = new Intent(reactContext, ShowTimeoutNotification.class); notificationIntent.putExtra("notifyChannelStringTitle", notifyChannelString[0]); notificationIntent.putExtra("notifyChannelStringDescription", notifyChannelString[1]); + notificationIntent.putExtra("notifyStringTitle", notifyStopString[0]); notificationIntent.putExtra("notifyStringDescription", notifyStopString[1]); + notificationIntent.putExtra("notifyStringSmallIcon", notifyStopString[2]); PendingIntent contentIntent = PendingIntent.getService(reactContext, 0, notificationIntent, PendingIntent.FLAG_CANCEL_CURRENT); @@ -231,9 +238,7 @@ public void onSuccess(Void aVoid) { }else{ am.setExact(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()+mDuration, contentIntent); } - } - } }) .addOnFailureListener(new OnFailureListener() { @@ -282,8 +287,10 @@ public void onSuccess(Void aVoid) { Intent notificationIntent = new Intent(reactContext, ShowTimeoutNotification.class); notificationIntent.putExtra("notifyChannelStringTitle", notifyChannelString[0]); notificationIntent.putExtra("notifyChannelStringDescription", notifyChannelString[1]); + notificationIntent.putExtra("notifyStringTitle", notifyStopString[0]); notificationIntent.putExtra("notifyStringDescription", notifyStopString[1]); + notificationIntent.putExtra("notifyStringSmallIcon", notifyStopString[2]); PendingIntent contentIntent = PendingIntent.getService(reactContext, 0, notificationIntent, PendingIntent.FLAG_CANCEL_CURRENT); @@ -322,7 +329,7 @@ public void onFailure(@NonNull Exception e) { @ReactMethod public void testNotify(){ Log.i(TAG, "TestNotify Callback worked"); - postNotification("TestNotify", "Callback worked", false); + postNotification("TestNotify", "Callback worked", "ic_notification", false); } /* @@ -347,20 +354,26 @@ private PendingIntent getGeofencePendingIntent() { if(notifyEnter == true){ intent.putExtra("notifyEnterStringTitle", notifyEnterString[0]); intent.putExtra("notifyEnterStringDescription", notifyEnterString[1]); + intent.putExtra("notifyEnterStringSmallIcon", notifyEnterString[2]); }else{ intent.putExtra("notifyEnterStringTitle", ""); intent.putExtra("notifyEnterStringDescription", ""); + intent.putExtra("notifyEnterStringSmallIcon", "ic_notification"); } intent.putExtra("notifyExit", notifyExit); if(notifyExit == true){ intent.putExtra("notifyExitStringTitle", notifyExitString[0]); intent.putExtra("notifyExitStringDescription", notifyExitString[1]); + intent.putExtra("notifyExitStringSmallIcon", notifyExitString[2]); + }else{ intent.putExtra("notifyExitStringTitle", ""); intent.putExtra("notifyExitStringDescription", ""); + intent.putExtra("notifyExitStringSmallIcon", "ic_notification"); } intent.putExtra("notifyChannelStringTitle", notifyChannelString[0]); intent.putExtra("notifyChannelStringDescription", notifyChannelString[1]); + intent.putExtra("startTime", (Long) System.currentTimeMillis()); intent.putExtra("duration", mDuration); intent.putStringArrayListExtra("geofenceKeys", geofenceKeys); @@ -378,16 +391,16 @@ private PendingIntent getGeofencePendingIntent() { private void notifyNow(String action){ if(action == "start"){ if(notifyStart == true){ - postNotification(notifyStartString[0], notifyStartString[1], true); + postNotification(notifyStartString[0], notifyStartString[1], notifyStartString[2], true); } } if(action == "stop"){ if(notifyStop == true){ - postNotification(notifyStopString[0], notifyStopString[1], false); + postNotification(notifyStopString[0], notifyStopString[1], notifyStopString[2], false); } } } - private NotificationCompat.Builder getNotificationBuilder(String title, String content) { + private NotificationCompat.Builder getNotificationBuilder(String title, String content, String smallIcon) { //Onclick Intent intent = new Intent(getReactApplicationContext(), this.getCurrentActivity().getClass()); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); @@ -396,11 +409,15 @@ private NotificationCompat.Builder getNotificationBuilder(String title, String c //PendingIntent contentIntent = PendingIntent.getBroadcast(this.getReactApplicationContext(), NOTIFICATION_ID_STOP, intent, PendingIntent.FLAG_UPDATE_CURRENT); //Build notification + Resources res = this.reactContext.getResources(); + String packageName = this.reactContext.getPackageName(); + int smallIconDrawable = res.getIdentifier(smallIcon != null ? smallIcon : "", "drawable", packageName); + NotificationCompat.Builder notification = new NotificationCompat.Builder(this.reactContext, CHANNEL_ID) .setContentTitle(title) .setStyle(new NotificationCompat.BigTextStyle().bigText(content)) .setContentText(content) - .setSmallIcon(getReactApplicationContext().getApplicationInfo().icon) + .setSmallIcon((smallIconDrawable != 0) ? smallIconDrawable : this.reactContext.getApplicationInfo().icon) .setContentIntent(contentIntent); // Create the NotificationChannel, but only on API 26+ because // the NotificationChannel class is new and not in the support library @@ -418,14 +435,14 @@ private NotificationCompat.Builder getNotificationBuilder(String title, String c } return notification; } - public void postNotification(String title, String content, boolean start){ + public void postNotification(String title, String content, String smallIcon, boolean start){ NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this.reactContext); int notifyID = NOTIFICATION_ID_STOP; if(start == true){ notifyID = NOTIFICATION_ID_START; } - notificationManager.notify(NOTIFICATION_TAG, notifyID, getNotificationBuilder(title, content).build()); + notificationManager.notify(NOTIFICATION_TAG, notifyID, getNotificationBuilder(title, content, smallIcon).build()); } /* private static int getNextNotifId(Context context) { diff --git a/android/src/main/java/com/simplegeofencing/reactnative/ShowTimeoutNotification.java b/android/src/main/java/com/simplegeofencing/reactnative/ShowTimeoutNotification.java index f130135..0afe194 100644 --- a/android/src/main/java/com/simplegeofencing/reactnative/ShowTimeoutNotification.java +++ b/android/src/main/java/com/simplegeofencing/reactnative/ShowTimeoutNotification.java @@ -15,6 +15,7 @@ import androidx.core.app.NotificationCompat; import androidx.core.app.NotificationManagerCompat; import android.util.Log; +import android.content.res.Resources; public class ShowTimeoutNotification extends IntentService { private static final String TAG = "GeofenceTimeout"; @@ -38,15 +39,17 @@ protected void onHandleIntent(Intent intent){ postNotification( intent.getStringExtra("notifyStringTitle"), intent.getStringExtra("notifyStringDescription"), + intent.getStringExtra("notifyStringSmallIcon"), intent.getStringExtra("notifyChannelStringTitle"), intent.getStringExtra("notifyChannelStringDescription") - ); + ); } /* Notifications */ private NotificationCompat.Builder getNotificationBuilder(String title, String content, + String smallIcon, String channelTitle, String channelDescription) { //Onclick @@ -54,11 +57,15 @@ private NotificationCompat.Builder getNotificationBuilder(String title, //intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); //PendingIntent pendingIntent = PendingIntent.getActivity(this.reactContext, 0, intent, 0); - //Build notification + //Build notificationnotification + Resources res = this.getResources(); + String packageName = this.getPackageName(); + int smallIconDrawable = res.getIdentifier(smallIcon, "drawable", packageName); + NotificationCompat.Builder notification = new NotificationCompat.Builder(this, CHANNEL_ID) .setContentTitle(title) .setContentText(content) - .setSmallIcon(this.getApplicationInfo().icon) + .setSmallIcon((smallIconDrawable != 0) ? smallIconDrawable : this.getApplicationInfo().icon) .setLargeIcon(BitmapFactory.decodeResource(this.getResources(), this.getApplicationInfo().icon)) .setAutoCancel(true); @@ -70,6 +77,7 @@ private NotificationCompat.Builder getNotificationBuilder(String title, int importance = NotificationManager.IMPORTANCE_DEFAULT; NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance); channel.setDescription(description); + // Register the channel with the system; you can't change the importance // or other notification behaviors after this NotificationManager notificationManager = this.getSystemService(NotificationManager.class); @@ -78,15 +86,16 @@ private NotificationCompat.Builder getNotificationBuilder(String title, } return notification; } - public void postNotification(String Title, - String Content, + public void postNotification(String title, + String content, + String smallIcon, String channelTitle, String channelDescription){ NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this); // notificationId is a unique int for each notification that you must define notificationManager.notify(getNextNotifId(this.getApplicationContext()), - getNotificationBuilder(Title, Content, channelTitle, channelDescription).build()); + getNotificationBuilder(title, content, smallIcon, channelTitle, channelDescription).build()); }