NotificationListenerService Implementation

隐身守侯 提交于 2019-11-27 03:36:11

Inside the NotificationListenerService you need a looper to communicate with GUI thread so you can create a broadcast to handle the GUI interaction.

Hope this example will help you.

You need to grant access to your app to read notifications: "Settings > Security > Notification access" and check your app.

At least one problem with your code is that your implementation of onBind()

There is no necessity to override this method. But if you must, then at least return the IBinder returned by the superclass.

@Override
public IBinder onBind(Intent intent) {
    return super.onBind(intent);
}

It might be a bit late. But a few months ago I also struggled with making NotificationListenerService work.

Since then I`ve learned how to implement it and felt like building a implementation tutorial to help others who went through the same as me

If anyone is interested, check the project here: https://github.com/Chagall/notification-listener-service-example

Hope it helps someone who is struggling with it.

I know its too late to answer the question , but as I was not able to find Settings > Sound and notifications -> Notification access, so I directly allow access of notifications to my app by firing this intent:

startActivity(new Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS));

I ran into the same problem and have found some clues for that.

NotificationListenerService may not be running unless you call bindService() to start it.

Sometimes it started automatically when you enabled "Notification access" and sometimes it's not.

The notification that you build does not have "tickerText." I have found that if the notification does not have tickerText, onNotificationPosted does not get called.

In your code add mBuilder.setTicker( "your text here" ).

onNotificationPosted should now be called assuming that the rest of the NotificationListenerService set up is copacetic.

I am doing the same thing as in GitHub, but still I am not going into the notification class.

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.IBinder;
import android.service.notification.NotificationListenerService;
import android.service.notification.StatusBarNotification;
import android.util.Log;

/**
 * @author dinesh
 *
 */
public class UserNotificationService extends NotificationListenerService {

    private String TAG = "UserNotificationService";
    UserNotificationServiceReceiver notfRcvr;

    @Override
    public void onNotificationRemoved(StatusBarNotification sbn) {

        Log.i(TAG,"********** onNotificationRemoved");
    Log.i(TAG,"ID :" + sbn.getId() + "\t" + sbn.getNotification().tickerText +"\t" + sbn.getPackageName());
    Intent i = new Intent("de.tu.darmstadt.moodsense.services.Notification");
    i.putExtra("notification event", "On notification removed");
    sendBroadcast(i);

    }

    @Override
    public IBinder onBind(Intent intent) {
        return super.onBind(intent);
    }

    @Override
    public void onNotificationPosted(StatusBarNotification sbn) {

        Log.i(TAG,"**********  onNotificationPosted");
    Log.i(TAG,"ID :" + sbn.getId() + "\t" + sbn.getNotification().tickerText + "\t" + sbn.getPackageName());
    Intent i = new Intent("de.tu.darmstadt.moodsense.services.Notification");
    i.putExtra("notification event", "On notification posted");
    sendBroadcast(i);

    }

    @Override
    public void onCreate() {
        super.onCreate();
        notfRcvr = new UserNotificationServiceReceiver();
        IntentFilter filter = new IntentFilter();
        filter.addAction("de.tu.darmstadt.moodsense.services.Notification");
        registerReceiver(notfRcvr, filter);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        unregisterReceiver(notfRcvr);
    }

    class UserNotificationServiceReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            // TODO Auto-generated method stub
            if(intent.getStringExtra("command").equals("clearall")) {
                UserNotificationService.this.cancelAllNotifications();
            }
        }

    }
}



import java.lang.Thread.State;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import twitter4j.Status;
import twitter4j.TwitterException;
import de.tu.darmstadt.moodsense.R;
import de.tu.darmstadt.moodsense.app.UserMood;
import de.tu.darmstadt.moodsense.constants.Constants;
import de.tu.darmstadt.moodsense.util.MqttMoodClient;
import de.tu.darmstadt.moodsense.util.TwitterMoodUtils;
import de.tu.darmstadt.moodsense.util.TwitterUtils;
import android.app.AlarmManager;
import android.app.Notification;
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.SharedPreferences;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.IBinder;
import android.os.SystemClock;
import android.preference.PreferenceManager;
import android.support.v4.app.NotificationCompat;
import android.util.Log;


/**
 * @author dinesh
 * Added for V1.1
 * Code style based on : https://newcircle.com/s/post/1049/
 *                       tutorial_services_part_1_android_bootcamp_series_2012
 *
 */
public class UserMoodService extends Service{

    static final String TAG = "UserMoodService";
    public static boolean userMoodSet = false;
    //declarations for twitter
    private SharedPreferences prefs;
    SharedPreferences userPref;
    String userTwitterMood = "";
    String worldTwitterMood = "";
    String screenName, userName;
    int m_counter;
    long shortMinutes;
    boolean m_enterMood;
    int m_myMood;
    int m_moodIntensity;
    MqttMoodClient mqc;
    TwitterMoodUtils tmu;
    Calendar cal = Calendar.getInstance();  

    private static final int MY_NOTIFICATION_ID=1;
    NotificationManager notificationManager;
    Notification myNotification;
    UserMoodNotificationReceiver usrMoodNotfnnRcvr;

    public UserMoodService() {
        // TODO Auto-generated constructor stub
        mqc = new MqttMoodClient();
        tmu = new TwitterMoodUtils();
    }
    public void reset() {

        m_myMood = Constants.NUM_MOOD_TYPES;
        m_moodIntensity = Constants.MILD;
        m_enterMood = false;

        m_counter = 0;

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

    @Override
    public void onTaskRemoved(Intent rootIntent) {
        // TODO Auto-generated method stub
        Intent restartService = new Intent(getApplicationContext(),this.getClass());
        restartService.setPackage(getPackageName());
        PendingIntent restartServicePI = PendingIntent.getService(getApplicationContext(),
                1, restartService, PendingIntent.FLAG_ONE_SHOT);

         AlarmManager alarmService = (AlarmManager)getApplicationContext().getSystemService(Context.ALARM_SERVICE);
        alarmService.set(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() +100, restartServicePI);
    }

    /** (non-Javadoc)
     * @see android.app.Service#onCreate()
     */
    @Override
    public void onCreate() {
        Log.d(TAG, "OnCreation");
        //super.onCreate();
        usrMoodNotfnnRcvr = new UserMoodNotificationReceiver();
        IntentFilter filter = new IntentFilter();
        filter.addAction("Notofication Obj");
        registerReceiver(usrMoodNotfnnRcvr, filter);

    }


    /** (non-Javadoc)
     * @see android.app.Service#onStartCommand(android.content.Intent, int, int)
     */
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {  
        Log.d(TAG, "OnStartCommand");
        try {
            ConnectivityManager cm =
                (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo netInfo = cm.getActiveNetworkInfo();
            if (netInfo != null && netInfo.isConnectedOrConnecting()) { 
                Log.d(TAG,"Twitter loop enter");
                //Check the user's mood on twitter
                computeMoodOnTwitter();
                if(userMoodSet) {
                    Log.d(TAG, "user's twitter mood" + userTwitterMood);
                } /*else {
                    Log.d(TAG, "user mood not set, world mood computation started");
                    //If user's mood is not set then check for world's mood
                }*/

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

        return START_STICKY;
    }

    private void computeMoodOnTwitter() {
        // TODO Auto-generated method stub
        reset();
        this.prefs = PreferenceManager.getDefaultSharedPreferences(this);
        Thread twitterThread;
        twitterThread = new Thread() {
            public void run() {
                //userMoodSet = false;
                Log.d(TAG, "User mood is :: "+ userMoodSet);
            /*try {
                  String usrNme =  TwitterUtils.getUserName(prefs).toString();

                  List<Status> statuses = TwitterUtils.getHomeTimeline(prefs);

                     for(int i=0; i < Constants.NUM_MOOD_TYPES; i++) {                  
                        for (int j =0 ; j < Constants.NUM_MOOD_TYPES; j++)
                        {           
                            for (twitter4j.Status status : statuses) {

                                //Check if the status is from the user and it matches our mood strings
                            if(status.getText().contains(Constants.searchStrings[i][j])
                                    && (status.getUser().getScreenName().equals(usrNme))) {
                                Date date = status.getCreatedAt();
                                long Minutes = tmu.getMinuteDifference(cal.getTime(), date);

                                if((Constants.sdf.format(date).equals(Constants.sdf.format(cal.getTime())))) {
                                  //Increment counter for each tweet
                                    Log.d(TAG, "User has a status");
                                    userMoodSet = true;
                                    m_counter++;
                                   //track time for the first tweet
                                   if(m_counter == 1) {
                                    shortMinutes = Minutes;
                                    m_moodIntensity = computeMoodIntensity(i,j);
                                    m_myMood = i;
                                    Log.d(TAG, "intensity + mood" + m_moodIntensity +","+ m_myMood);
                                    Log.d(TAG,"SocialMood:: mymood- " + Constants.moodIntensityNames[m_moodIntensity]+
                                               " "+ Constants.moodNames[m_myMood]);                                    
                                    Log.d(TAG, "SocialMood:: status-"+status.getText());                                        

                                   } else //counter more than 1   //track time for the later tweets 
                                   {  //take latest tweet only if logged minutes is shorter than earlier minutes
                                       if(Minutes < shortMinutes) {
                                          shortMinutes = Minutes;
                                          Log.d(TAG, "Called compute mood_intensity :: "+ m_counter);
                                          m_moodIntensity = computeMoodIntensity(i,j);
                                          m_myMood = i;
                                        }

                                   }                                    
                                  }
                                }
                              }
                            }
                         }                                                                               
                    } catch(TwitterException te) {
                      userMoodSet = false;                                  
                        Log.d(TAG, "Unable to process twitter get requests "+te.getErrorCode()+ " "+ te.getErrorMessage());

                    } catch (Exception e) {
                        // TODO Auto-generated catch block
                        Log.d(TAG,"Error msg");
                        e.printStackTrace();
                    }*/

                try {
                    stopThread(this);
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        };

        twitterThread.start();  

    }

    public int computeMoodIntensity(int m_detect, int m_type) {
        // TODO Auto-generated method stub
        for(int j=0; j < Constants.m_extreme.length; j++) {
            if(m_type == Constants.m_extreme[m_detect][j])
                return Constants.EXTREME;
        }
        for(int j=0; j < Constants.m_considerable.length; j++) {
            if(m_type == Constants.m_considerable[m_detect][j])
                return Constants.CONSIDERABLE;
        }

        return Constants.MILD;

    }

    private String userStatusToMood(int myMood) {
        // TODO Auto-generated method stub
        String userMood = Constants.userNoTwitter;
         if(m_myMood >= Constants.NUM_MOOD_TYPES) {
             m_enterMood = true;                
         Log.d(TAG, userMood);
         //Unreachable code - maybe we need to delete this ?? QNS
         /*Intent i = new Intent(UserMoodService.this,UserMood.class);
             i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
             startActivity(i);*/
         }
         else {
             userMood = "User mood is "+ Constants.moodNames[m_myMood];
             userTwitterMood = Constants.moodIntensityNames[m_moodIntensity]
                     +" "+Constants.moodNames[m_myMood];

             Log.d(TAG, "Updated user mood is "+userTwitterMood);   
             //call MQTT
             MqttMoodClient mqc = new MqttMoodClient();

             mqc.setupMqttClient();
             mqc.sendMessage(userTwitterMood);

         }
         return userMood;
    }

    private void stopThread(Thread theThread) throws Exception {
        // method to stop the worker thread once the process needed to do has been completed
        Log.d(TAG,"userMoodSet :: "+ userMoodSet);
        if (theThread != null)
        {
            theThread = null;
            Log.d(TAG, "Execution complete inside stop thread");
            if(userMoodSet)
                userStatusToMood(m_myMood);         
        }

        if(!userMoodSet) {
            Log.d(TAG, "In world thread");
            //Call world Service
            //WorldMoodService worldService = new WorldMoodService();
            //worldService.computeWorldMood(this);
            //show notification!!
            /**
             * V1.1 
             * @author dinesh
             * Code adapted from : http://android-er.blogspot.de/2013/06/
             *                     start-activity-once-notification-clicked.html
             */
            Intent myIntent = new Intent(UserMoodService.this, UserMood.class);
            PendingIntent pendingIntent = PendingIntent.getActivity(
                    UserMoodService.this, 
                0, 
                myIntent, 
                Intent.FLAG_ACTIVITY_NEW_TASK);

            myNotification = new NotificationCompat.Builder(UserMoodService.this)
            .setContentTitle("MoodSense notification")
            .setContentText("Please enter mood to play music as per your mood")
            .setTicker("Please enter mood to play music as per your mood")
            .setWhen(System.currentTimeMillis())
            .setContentIntent(pendingIntent)
            .setDefaults(Notification.DEFAULT_SOUND)
            .setAutoCancel(true)
            .setSmallIcon(R.drawable.app_icon)
            .build();

            notificationManager = 
                       (NotificationManager)UserMoodService.this.
                       getSystemService(Context.NOTIFICATION_SERVICE);
                     notificationManager.notify(MY_NOTIFICATION_ID, myNotification);                                

        } else if (userMoodSet) {
            Intent i = new Intent("de.tu.darmstadt.moodsense.services.Notification");
            i.putExtra("command", "clear all");
            sendBroadcast(i);
        }
    }

    public class UserMoodNotificationReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            String temp = intent.getStringExtra("notification event");

        }

    }
    /** (non-Javadoc)
     * @see android.app.Service#onDestroy()
     */
    @Override
    public void onDestroy() {   
        Log.d(TAG, "OnDeletion");
        super.onDestroy();
    }   
}

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!