Intereting Posts

Реализация NotificationListenerService

Я пытаюсь реализовать NotificationListnerService, который добавлен в android 4.3, но я не могу получить информацию о уведомлении.

Мой код ниже

public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this); mBuilder.setSmallIcon(R.drawable.ic_launcher); mBuilder.setContentTitle("notification test"); mBuilder.setContentText("Notification text"); mBuilder.setAutoCancel(true); Intent resultIntent = new Intent(this, ResultActivity.class); TaskStackBuilder stackBuilder = TaskStackBuilder.create(this); // Adds the back stack for the Intent (but not the Intent itself) stackBuilder.addParentStack(ResultActivity.class); // Adds the Intent that starts the Activity to the top of the stack stackBuilder.addNextIntent(resultIntent); PendingIntent resultPendingIntent = stackBuilder.getPendingIntent( 0, PendingIntent.FLAG_UPDATE_CURRENT ); mBuilder.setContentIntent(resultPendingIntent); NotificationManager manager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE); manager.notify(1, mBuilder.build()); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } } public class NotificationListenerTesting extends NotificationListenerService{ public static String TAG = "NotificationListenerTesting"; //private StatusBarNotification[] mStatusBarNotification; @Override public void onCreate(){ super.onCreate(); Log.d(TAG, "Inside on create"); } @Override public IBinder onBind(Intent intent) { return null; } @Override public void onNotificationPosted(StatusBarNotification sbn) { TAG = "onNotificationPosted"; Log.d(TAG, "id = " + sbn.getId() + "Package Name" + sbn.getPackageName() + "Post time = " + sbn.getPostTime() + "Tag = " + sbn.getTag()); } @Override public void onNotificationRemoved(StatusBarNotification sbn) { TAG = "onNotificationRemoved"; Log.d(TAG, "id = " + sbn.getId() + "Package Name" + sbn.getPackageName() + "Post time = " + sbn.getPostTime() + "Tag = " + sbn.getTag()); } } 

Файл манифеста Android

 <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.notificationtest" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="18" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.example.notificationtest.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name="com.example.notificationtest.ResultActivity"></activity> <service android:name="com.example.notificationtest.NotificationListenerTesting" android:label="notification" android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"> <intent-filter> <action android:name="android.service.notification.NotificationListenerService"/> </intent-filter> </service> </application> </manifest> 

Но после уведомления нажмите или на уведомлении сообщение NotificationListenerService не получает вызов, что не так в этом или я пропустил что-то? Как его реализовать?

Solutions Collecting From Web of "Реализация NotificationListenerService"

Внутри NotificationListenerService вам нужен петлитель для связи с потоком графического интерфейса, чтобы вы могли создавать широковещательную передачу для взаимодействия с графическим интерфейсом.

Надеюсь, этот пример поможет вам.

Вы должны предоставить доступ к своему приложению для чтения уведомлений: «Настройки> Безопасность> Доступ к уведомлениям» и проверьте свое приложение.

По крайней мере, одна проблема с вашим кодом заключается в том, что ваша реализация onBind ()

Нет необходимости переопределять этот метод. Но если вам нужно, то, по крайней мере, вернуть IBinder, возвращенный суперклассом.

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

Я столкнулся с той же проблемой и нашел некоторые подсказки для этого.

NotificationListenerService может не работать, если вы не вызываете bindService() чтобы запустить его.

Иногда он запускался автоматически, когда вы включали «Доступ к уведомлению», а иногда это не так.

В уведомлении, которое вы создаете, нет «tickerText». Я обнаружил, что если в уведомлении нет tickerText, onNotificationPosted не вызывается.

В вашем коде добавьте mBuilder.setTicker («ваш текст здесь»).

OnNotificationPosted теперь следует называть предполагать, что остальная часть службы NotificationListenerService установлена ​​на коаксиальный.

Я делаю то же самое, что и в GitHub, но все же я не собираюсь в класс уведомлений.

 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(); } } 

Это может быть немного поздно. Но несколько месяцев назад я также боролся с тем, чтобы работать с NotificationListenerService.

С тех пор я узнал, как его реализовать, и хотел создать учебник по внедрению, чтобы помочь другим, кто прошел через меня

Если кому-то интересно, проверьте проект здесь: https://github.com/Chagall/notification-listener-service-example

Надеюсь, это помогает кому-то, кто борется с этим.

Я знаю, что слишком поздно ответить на этот вопрос, но поскольку я не смог найти «Настройки»> «Звуки и уведомления» -> «Доступ к уведомлению», я напрямую разрешаю доступ к уведомлениям в своем приложении, уволив это намерение:

StartActivity (новый Intent (Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS));