studio startforeground notification manager developer create android android-service android-notifications

startforeground - show notifications android studio



NotificationListenerService Implementación (8)

Estoy intentando implementar NotificationListnerService que se agrega en Android 4.3 pero no puedo obtener los detalles de la notificación.

Mi código es el siguiente

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

Archivo manifiesto de Android es

<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>

pero después de la notificación, haga clic o en la publicación de notificación NotificationListenerService no se está llamando. ¿Cómo implementarlo?


Al menos un problema con su código es que su implementación de onBind ()

No hay necesidad de anular este método. Pero si debe hacerlo, al menos devuelva el IBinder devuelto por la superclase.

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


Debe otorgar acceso a su aplicación para leer las notificaciones: "Configuración> Seguridad> Acceso a notificaciones" y verificar su aplicación.


Dentro del NotificationListenerService, necesita un looper para comunicarse con el hilo de la GUI para que pueda crear una transmisión para manejar la interacción de la GUI.

Espero que this ejemplo te ayude.


Estoy haciendo lo mismo que en GitHub, pero aún no estoy ingresando a la clase de notificación.

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


La notificación que creas no tiene "tickerText". He encontrado que si la notificación no tiene tickerText, onNotificationPosted no se llama.

En su código, agregue mBuilder.setTicker ("su texto aquí").

onNotificationPosted ahora debe llamarse asumiendo que el resto de la configuración de NotificationListenerService es copacetic.


Me encontré con el mismo problema y he encontrado algunas pistas para eso.

NotificationListenerService puede no estar ejecutándose a menos que llame a bindService() para iniciarlo.

A veces se iniciaba automáticamente cuando habilitabas "Acceso a notificaciones" y otras veces no.


Puede que sea un poco tarde. Pero hace unos meses también luché para que NotificationListenerService funcione.

Desde entonces, he aprendido cómo implementarlo y sentí como construir un tutorial de implementación para ayudar a otros que pasaron por lo mismo que yo.

Si alguien está interesado, consulte el proyecto aquí: https://github.com/Chagall/notification-listener-service-example

Espero que ayude a alguien que está luchando con él.


Sé que es demasiado tarde para responder a la pregunta, pero como no pude encontrar Configuración> Sonido y notificaciones -> Acceso a las notificaciones, por lo tanto, permito directamente el acceso de las notificaciones a mi aplicación al disparar esta intención:

startActivity (nueva Intención (Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS));