How to check if there are any notifications programmatically in android? - android

Does anyone know how can I check if there are any notifications programmatically in android?
I want to check if there is any notification currently available in the notifications list.
for example, if there is any notification, the LED light is turned on and if the notifications list is cleared, the LED light is turned off.
I just want to know the condition or the code that allow us to check if there are any notifications available in the notifications list.
if ( condition - there are any notifications )
// my code

You can use NotificationListener API, which is available on Android 4.3+. To do that you just simply need to create a simple Service that extends NotificationListenerService.
Here is some sample code
import android.service.notification.NotificationListenerService;
import android.service.notification.StatusBarNotification;
import android.util.Log;
public class NLService extends NotificationListenerService {
private String TAG = this.getClass().getSimpleName();
#Override
public void onCreate() {
super.onCreate();
}
#Override
public void onDestroy() {
super.onDestroy();
}
#Override
public void onNotificationPosted(StatusBarNotification sbn) {
Log.i(TAG, "Notification posted");
Log.i(TAG, "ID :" + sbn.getId() + "t" + sbn.getNotification().tickerText + "t" + sbn.getPackageName());
}
#Override
public void onNotificationRemoved(StatusBarNotification sbn) {
Log.i(TAG, "Notification Removed");
Log.i(TAG, "ID :" + sbn.getId() + "t" + sbn.getNotification().tickerText + "t" + sbn.getPackageName());
}
}
A complete tutorial is available here
Prior to this version of Android, you can make a hack through the AccessibilityService as described here

Related

Why does my app always show the default icon on a push notification display in system tray?

This question and related ones has been asked many times, but I'm asking for help in my specific trouble because I have reviewed the Firebase guides, and various questions/answers on how to add an icon to the push notification and can't seem to get it.
I believe I have a small mistake somewhere. I'm hoping you can glance my code and spot it.
Here's my app's AndroidManifest.xml.
<application
android:allowBackup="false"
android:hardwareAccelerated="true"
android:icon="#mipmap/ic_launcher"
android:roundIcon="#mipmap/ic_launcher_round"
android:label="#string/app_name"
android:theme="#style/AppThemeFull">
<meta-data android:name="com.google.firebase.messaging.default_notification_icon"
android:resource="#mipmap/ic_launcher_round" />
<meta-data android:name="com.google.firebase.messaging.default_notification_color"
android:resource="#color/white" />
My mipmap/ic_launcher_round/ic_launcher_round.xml:
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="#mipmap/ic_launcher_background"/>
<foreground android:drawable="#mipmap/ic_launcher_foreground"/>
</adaptive-icon>
I icons listed on the left show up just fine in Android Studio if you double click each of them. (I feel there's probably more things to show which I'm not aware. Please add a comment if you're missing something and I'll promptly edit the question.)
Here's my push notification service:
package my.package;
import android.content.Intent;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;
import java.util.Map;
public class Notifications extends FirebaseMessagingService {
private final String TAG = "XXX-PUSHNOTES";
public Notifications() {
Log.d(TAG, "instantiating class!");
}
private void sendMessage(Map<String, String> map) {
Intent intent = new Intent("LOAD_APP_GOING_TO_URL");
for (Map.Entry e : map.entrySet()) {
Log.d(TAG, "Key: " + e.getKey() + " Value: " + e.getValue());
intent.putExtra((String) e.getKey(), (String) e.getValue());
}
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
#Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "push notes service created");
}
#Override
public void onDestroy() {
super.onDestroy();
Log.d(TAG, "push notes service destroyed");
}
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
// TODO(developer): Handle FCM messages here.
Log.d(TAG, "From: " + remoteMessage.getFrom());
// Check if message contains a data payload.
if (remoteMessage.getData().size() > 0) {
Log.d(TAG, "Message data payload: " + remoteMessage.getData());
Log.d(TAG, remoteMessage.getData().get("LOAD_APP_GOING_TO_URL"));
sendMessage(remoteMessage.getData());
if (/* Check if data needs to be processed by long running job */ true) {
// For long-running tasks (10 seconds or more) use Firebase Job Dispatcher.
//scheduleJob();
} else {
// Handle message within 10 seconds
Log.d(TAG, "Not handling the message.");
}
}
// Check if message contains a notification payload.
if (remoteMessage.getNotification() != null) {
Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
}
}
}
Here's my main activity handling the broadcast from the service above:
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
final String TAG = "XXX-WA-BROADCAST";
#Override
public void onReceive(Context context, Intent intent) {
// Extract data included in the Intent
String LOAD_APP_GOING_TO_URL = intent.getStringExtra("LOAD_APP_GOING_TO_URL");
String LOAD_APP_GOING_TO_URL_TOAST_MSG = intent.getStringExtra("LOAD_APP_GOING_TO_URL_TOAST_MSG");
Log.d(TAG, LOAD_APP_GOING_TO_URL);
Log.d(TAG, LOAD_APP_GOING_TO_URL_TOAST_MSG);
Toast t = Toast.makeText(getApplicationContext(), LOAD_APP_GOING_TO_URL_TOAST_MSG, Toast.LENGTH_LONG);
t.setGravity(Gravity.TOP, 0, 0);
t.show();
}
};
Which part of your code is ceating a notification? If I understand your code right, you are creating toast with the message on the top of the screen instead of real notifications?
You can create messages as you want:
private Notification buildForegroundNotification(String message) {
NotificationCompat.Builder b = new NotificationCompat.Builder(this, ChannelID);
b.setOngoing(true)
.setContentTitle("test")
.setContentText(message)
.setSmallIcon(1)//set there the Ressource id
.setTicker("test");
return (b.build());
}

about background services

I'm developing an app for Android that should receive some notifications via a protocol similar to MQTT from an Arduino device. This notification will be a sort of alarm and will not be continuous but it will be rare. The service will do a lite job: receive single notification, it registry in a sqlite database and sends a notification to system bar. What kind of background service I should use for API level 26 or higher. I know thet the system imposes restrictions on running background services
thanks
Luigi
/*Note: IntentService is a service, and is therefore subject to the new restrictions on background services. As a result, many apps that rely on IntentService do not work properly when targeting Android 8.0 or higher. For this reason, Android Support Library 26.0.0 introduces a new JobIntentService class, which provides the same functionality as IntentService but uses jobs instead of services when running on Android 8.0 or higher.*/
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.SystemClock;
import android.support.v4.app.JobIntentService;
import android.util.Log;
import android.widget.Toast;
/**
* Example implementation of a JobIntentService.
*/
public class SimpleJobIntentService extends JobIntentService {
/**
* Unique job ID for this service.
*/
static final int JOB_ID = 1000;
/**
* Convenience method for enqueuing work in to this service.
*/
static void enqueueWork(Context context, Intent work) {
enqueueWork(context, SimpleJobIntentService.class, JOB_ID, work);
}
#Override
protected void onHandleWork(Intent intent) {
// We have received work to do. The system or framework is already
// holding a wake lock for us at this point, so we can just go.
Log.i("SimpleJobIntentService", "Executing work: " + intent);
String label = intent.getStringExtra("label");
if (label == null) {
label = intent.toString();
}
toast("Executing: " + label);
for (int i = 0; i < 5; i++) {
Log.i("SimpleJobIntentService", "Running service " + (i + 1)
+ "/5 # " + SystemClock.elapsedRealtime());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
}
Log.i("SimpleJobIntentService", "Completed service # " + SystemClock.elapsedRealtime());
}
#Override
public void onDestroy() {
super.onDestroy();
toast("All work complete");
}
final Handler mHandler = new Handler();
// Helper for showing tests
void toast(final CharSequence text) {
mHandler.post(new Runnable() {
#Override public void run() {
Toast.makeText(SimpleJobIntentService.this, text, Toast.LENGTH_SHORT).show();
}
});
}
}

How to remove a specific "system notification" in android?

I'm want to remove the "system" screenshot notification. I already achieved it, using the Notification Listener Service and the ID which I got from my phone. But I found out that the ID for the system notification is changing on some samsung and other devices. How can I make sure to remove the notification also on other devices. is there a different way to detect that the system screenshot notification has shown? Some specific TAG?
Edit: This how I do it right now:
#Override
public void onNotificationPosted(StatusBarNotification sbn) {
//super.onNotificationPosted(sbn);
Log.i(TAG, "ID: " + sbn.getId());
Log.i(TAG, "Package: " + sbn.getPackageName());
//Remove Notification
if (sbn.getId() == 2131820569) {
if(status.getBoolean("comboserviceaktiv",false) || status.getBoolean("serviceaktiv",false) && standardprefs.getBoolean("settings_silent",false)){
if(Build.VERSION.SDK_INT >= 21) {
this.cancelNotification(sbn.getKey());
Log.i(TAG, "System Screenshot Notification deleted");
} else {
this.cancelNotification(sbn.getPackageName(),sbn.getTag(),sbn.getId());
Log.i(TAG, "System Sreenshot Notification deleted");
}
}
}
}
Thank you very much!

How to parse the stacked messages in a notification (Whatsapp notification)

I am trying to parse the Whatsapp notifications that i receive on my device using NotificationListenerService.
On receiving a notification for the first time, i am able to retrieve the Text message. However, when the second message arrives, i get the message: "2 new messages". So basically here the messages in the notification are getting stacked.
Below is the code i have used:
public class NLService extends NotificationListenerService {
private String TAG = this.getClass().getSimpleName();
#Override
public void onCreate() {
super.onCreate();
}
#Override
public void onDestroy() {
super.onDestroy();
}
#Override
public void onNotificationPosted(StatusBarNotification sbn) {
Log.i(TAG,"********** onNotificationPosted");
String key = sbn.getKey();
sbn.getNotification().tickerText + "\n Package Name:" + sbn.getPackageName());
Log.i(TAG,"getTAG:"+sbn.getTag());
Log.i(TAG,"getKey:"+sbn.getKey());
Log.i(TAG,"getGrpKey:"+sbn.getGroupKey());*/
Bundle bundle = sbn.getNotification().extras;
String title = bundle.getString("android.title");
String text = bundle.getCharSequence("android.text").toString();//This gives me the actual message, the first time the notification arrives
Log.i(TAG,"Bundle is:"+bundle);
Log.i(TAG,"Title:"+title);
Log.i(TAG,"Text:"+text);
NLService.this.cancelNotification(key);
}
#Override
public void onNotificationRemoved(StatusBarNotification sbn) {
Log.i(TAG,"********** onNOtificationRemoved");
Log.i(TAG,"ID :" + sbn.getId() + "\t" + sbn.getNotification().tickerText +"\t" + sbn.getPackageName());
}
}
So my query here is, how do i parse/fetch messages from this notification? Or is there another way to fetch incoming whatsapp messages?
One approach that i can think of is marking the message as "Read", but has anyone able to mark a whatsapp message as "read" programmatically?
I have read most of the older posts on Stackoverflow and also whatsapp official site provides us a way of send a message.
Any sort of suggestions shall be really helpful.

Why is this NotificationListenerService not working

I'm fighting against the NotificationListenerService without much luck.
I tried a lot of recipes found here and there, especially on so... But it works quite inconsistently.
A first look at the code :
Manifest :
<service
android:name=".services.NLService"
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE" >
<intent-filter>
<action android:name="android.service.notification.NotificationListenerService" />
</intent-filter>
</service>
Then the service itself :
public class NLService extends NotificationListenerService {
private String TAG = "NLService";
// bind and unbind seems to make it work with Android 6...
// but is never called with Android 4.4...
#Override
public IBinder onBind(Intent mIntent) {
IBinder mIBinder = super.onBind(mIntent);
Log.i(TAG, "onBind");
return mIBinder;
}
#Override
public boolean onUnbind(Intent mIntent) {
boolean mOnUnbind = super.onUnbind(mIntent);
Log.i(TAG, "onUnbind");
isNotificationAccessEnabled = false;
try {
} catch (Exception e) {
Log.e(TAG, "Error during unbind", e);
}
return mOnUnbind;
}
// onCreate is called with Android 4.4
// because the service is explicitly started from the MainActivity.
// Not on Android 6 where the system binds this service itself...
#Override
public void onCreate() {
super.onCreate();
Log.i(TAG, "********** onCreate");
#Override
public void onNotificationPosted(StatusBarNotification sbn) {
Log.i(TAG, "********** onNotificationPosted");
Log.i(TAG, "ID :" + sbn.getId() + "\t" + sbn.getNotification().tickerText + "\t" + sbn.getPackageName());
}
#Override
public void onNotificationRemoved(StatusBarNotification sbn) {
Log.i(TAG, "********** onNOtificationRemoved");
Log.i(TAG, "ID :" + sbn.getId() + "\t" + sbn.getNotification().tickerText + "\t" + sbn.getPackageName());
}
}
And in the main Activity the service is started or we ask the user to enable the setting if needed :
if (!Utilities.hasNotificationAccess(this))
{
Intent intent = new Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS");
startActivity(intent);
Log.i(TAG,"hasNotificationAccess NO");
}
else
{
Log.i(TAG,"hasNotificationAccess YES");
// without this startService, it never works with Android 4.4...
// but this is not needed in Android 6...
Intent mServiceIntent = new Intent(this, NLService.class);
startService(mServiceIntent);
}
Obviously, the secure setting access for notifications is enabled...
On Android 6 :
On the NLService itself, the addition of the onBind and onUnbind methods make it work, I can se the onBind log, and the onNotificationPosted is triggered nicely. But it lasts until the next launch of the app, then no more binding, no more onNotificationPosted, just nothing happens until I go back to security settings to uncheck-recheck the notifications access: repeating this each time the App is started is not something possible in a production environment.
On Android 4.4 :
In contrast to Android 6, in the MainActivity I need to explicitly start the NLService otherwise it never stats by itself. But once again it works for the first launch and never works again until uncheck-recheck the security setting...
Did I miss something obvious ?
There is a problem with Android caching. When you upload app on the device, OS connects your service to Notification Manager. If you ran your app before, Android founds this service in cache so it's not reconnected.
Workaround: before pushing the app on your device, rename your service (refactor option in Android Studio works well) - Android will recognize this service as new one and connect to Notification Manager.
https://developer.android.com/reference/android/service/notification/NotificationListenerService.html#onListenerConnected() - this method will be invoked after connecting to Notification Manager so you can check if your service is connected or not.

Categories

Resources