Extrait de texte de notification de parcelable, contentView ou contentIntent
Si j'ai eu mon AccessibilityService de travail avec le code suivant:
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
if (event.getEventType() == AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED) {
List<CharSequence> notificationList = event.getText();
for (int i = 0; i < notificationList.size(); i++) {
Toast.makeText(this.getApplicationContext(), notificationList.get(i), 1).show();
}
}
}
Il fonctionne très bien pour la lecture du texte affiché lorsque la notification a été créé (1).
Le seul problème est que j'ai aussi besoin de la valeur de (3) qui s'affiche lorsque l'utilisateur ouvre la barre de notification. (2) n'est pas important pour moi, mais il serait bon de savoir comment le lire. Comme vous le savez probablement, toutes les valeurs peuvent être différentes.
Alors, comment puis-je lire (3)? Je doute que cela soit impossible, mais mon notificationList
semble n'avoir qu'une seule entrée (au moins un seul toast est indiqué).
Merci beaucoup!
/edit: j'ai pu extraire la notification colis avec
if (!(parcel instanceof Notification)) {
return;
}
final Notification notification = (Notification) parcel;
Cependant, je n'ai aucune idée de comment faire pour extraire la notification du message de notification
ou notification.contentView
/notification.contentIntent
.
Des idées?
/edit: Pour clarifier ce qui est demandé ici: Comment puis-je lire (3)?
Vous devez vous connecter pour publier un commentaire.
J'ai gâché quelques heures de la dernière jours de trouver un moyen de faire ce que vous (et moi aussi, par la voie) veulent faire. Après en regardant à travers l'ensemble de la source de RemoteViews deux fois, j'ai pensé que la seule façon d'accomplir cette tâche est de la bonne vieille, laide et hacky Java Réflexions.
Ici, il est:
Ce code a bien fonctionné sur un Nexus S avec Android 4.0.3. Cependant, je n'ai pas tester si ça marche sur d'autres versions d'Android. Il est très probable que certaines valeurs, en particulier la viewId changé. Je pense qu'il devrait y avoir des moyens pour supporter toutes les versions d'Android sans coder en dur tous les possibles de l'ids, mais c'est la réponse à une autre question... 😉
PS: La valeur que vous recherchez (en se référant à "(3)" dans votre question initiale) est le "texte"de la valeur.
16908358
n'est pas la valeur du contenu du texte. Toutes les idées qui je peux obtenir ce code de travail en vertu de GO?action.getClass().getDeclaredFields()
afin de les obtenir, vous devez utiliseraction.getClass().getSuperclass().getDeclaredFields()
.J'ai passé la dernière semaine de travail avec un problème similaire et peut proposer une solution similaire à Tom Taché (à l'aide de la réflexion), mais peut-être un peu plus facile à comprendre. La méthode suivante sera peigne une notification pour n'importe quel texte présent et de renvoyer ce texte en une liste de tableaux si possible.
Parce que c'est probablement ce qui ressemble un peu à de la magie noire, laissez-moi vous expliquer plus en détail. Nous avons d'abord tirer la RemoteViews objet de la notification elle-même. Ceci représente le point de vue à l'intérieur de la notification réel. Pour accéder à ces points de vue, nous avons pour gonfler le RemoteViews objet (qui ne fonctionne que lorsqu'un contexte d'activité est présent) ou utiliser la réflexion. La réflexion va travailler dans les deux cas et c'est la méthode utilisée ici.
Si vous examinez la source pour RemoteViews ici, vous verrez que l'un des membres privés est une liste de tableaux, d'objets d'Action. Cela représente ce qui va être fait à l'opinion une fois qu'ils sont gonflés. Par exemple, après les vues sont créées, setText() sera appelée à un certain point à chaque TextView qui est une partie de la hiérarchie à affecter le bon Chaînes. Ce que nous faisons est d'obtenir l'accès à cette liste d'actions et d'itérer à travers elle. L'Action est définie comme suit:
Il y a un certain nombre de sous-classes concrètes d'Action définies dans RemoteViews. Celui qui nous intéresse est appelé ReflectionAction et est définie comme suit:
Cette action est utilisée pour assigner des valeurs aux points de vue. Une seule instance de cette classe serait susceptible d'avoir les valeurs {"setText", 10, "contenu de la textview"}. Donc, nous sommes seulement intéressés par les éléments de mActions qui sont "ReflectionAction" objets et affecter un texte d'une certaine façon. Nous pouvons dire à un particulier de "l'Action" est un "ReflectionAction" en examinant le champ "TAG" dans l'Action, ce qui est toujours le premier de lire la valeur de la parcelle. Les balises de 2 représentent ReflectionAction objets.
Après cela, il nous suffit de lire les valeurs de la parcelle selon l'ordre dans lequel ils ont été écrits (voir le lien vers la source, si vous êtes curieux). Nous trouvons toute la chaîne qui est définie avec setText() et de l'enregistrer dans la liste. (setTime() est également inclus, dans le cas où le délai de notification est également nécessaire. Si non, ces lignes peuvent être supprimés en toute sécurité.)
Alors que je généralement s'opposer à l'utilisation de la réflexion dans des cas comme cela, il y a des moments où il est nécessaire. Sauf si il y a un contexte d'activité disponibles, le "standard" méthode ne fonctionne pas correctement, c'est donc la seule option.
Il y a une autre façon, si vous ne voulez pas utiliser la réflexion: au lieu de parcourant la liste des "actions" qui sont répertoriés dans la RemoteViews objet, vous pouvez "replay" sur un ViewGroup:
Note vous utilisez remoteView.getLayoutId() assurez-vous que le gonflés vue correspond à celui de la notification.
Ensuite, vous pouvez récupérer une partie de la plus-ou-moins standard textviews avec
Pour mon propre but (qui est d'espionner les notifications affichées par un paquet de mon propre) j'ai choisi de parcourir l'ensemble de la hiérarchie, sous localView et de recueillir tous les TextViews.
TextView tv = (TextView) localView.findViewById(16908358);
avec16908358
prises de TomTasche de réponse. Comme indiqué ci-dessus, cela pourrait retourner nil dans certains cas.Ajout sur la réponse de Remi, identifier les différents types de notification et d'extraire des données, utilisez le code ci-dessous.
Pour répondre à votre question: Cela ne pas semble possible dans votre cas. Ci-dessous je vais expliquer pourquoi.
"Le but principal de l'accessibilité de l'événement, c'est s'exposer suffisamment d'informations pour une AccessibilityService de fournir une rétroaction à l'utilisateur." Dans un cas comme le vôtre:
Nous pouvons demander à ce privilège explicitement par la mise en méta-données pour le service de votre android fichier manifeste:
Où votre fichier xml pourrait ressembler à:
Nous demander explicitement le privilège pour l'accès à un événement de la source (le contenu de la fenêtre) et de nous spécifier (en utilisant
accessibilityEventTypes
) les types d'événements de ce service désirez recevoir (dans votre cas, seulementtypeNotificationStateChanged
). Voir AccessibilityService pour plus d'options que vous pouvez définir dans le fichier xml.Normalement (voir ci-dessous, pourquoi pas dans ce cas), il devrait être possible d'appeler
event.getSource()
et obtenir unAccessibilityNodeInfo
et de parcourir à travers le contenu de la fenêtre, car "l'accessibilité de l'événement est envoyé par le premier affichage dans la vue de l'arbre".Tout, il semble possible de le faire maintenant, de plus amples informations dans le AccessibilityEvent de la documentation nous dit:
Apparemment, c'est parce que des raisons de sécurité...
Accrocher sur la façon d'extraire la notification de message à partir de la notification ou de la notification.contentView /notification.contentIntent. Je ne pense pas que vous le pouvez.
La contentView est un RemoteView et ne fournit pas de méthodes pour obtenir de l'information sur la notification.
De même, la contentIntent est un PendingIntent, qui ne dispose pas de méthodes pour obtenir des informations sur l'intention sera lancé lorsque la notification est cliqué. (c'est à dire vous ne pouvez pas obtenir les extras de l'intention par exemple).
En outre, puisque vous n'avez pas fourni d'informations sur la raison pour laquelle vous désirez obtenir la description de la notification et de ce que vous voulez faire avec elle, je ne peux pas vraiment vous fournir une solution pour résoudre ce.
Si vous avez essayé de TomTasche de la solution sur Android 4.2.2, vous remarquerez qu'il ne fonctionne pas.
L'expansion sur de sa réponse, et user1060919 commentaire...
Voici un exemple qui fonctionne pour 4.2.2:
Achep de AcDisplay projet a fourni une solution, vérifiez le code de Extractor.java
Vous pouvez également regarder les champs privés de l'objet de Notification pour des informations supplémentaires,
Comme contentTitle,contentText et tickerText
Voici le code pertinent
Ici est getObjectProperty méthode