Comment faire une capture d'écran d'une autre application par programme sans autorisation root, comme Screenshot UX Trial?
Je sais que je peux capturer le bitmap de la vue racine dans mon application. Mais je ne peux pas obtenir la vue racine de l'autre application lorsque mon application s'exécute en arrière-plan
bitmap = Bitmap.createBitmap(rootview.getDrawingCache());
Il existe une autorisation pour capturer le tampon de trame actuel dans le manifeste: Android.permission.READ_FRAME_BUFFER
. Mais certains sites Web disent que c'est uniquement pour l'application de signature.
Après avoir essayé la version d'essai de Screenshot UX, j'ai lu l'autorisation:
Il semble soit SYSTEM_ALERT_WINDOW
ou GET_TASKS
autorise l'application à prendre une capture d'écran. J'ai deux hypothèses sur la façon dont cela fonctionne:
Activity
de l'activité de premier plan, il obtient la vue racine du Activity
, capture sa capture d'écran.glreadpixels
Si vous essayez une de mes suppositions, faites-moi savoir le résultat.
C'est extrêmement difficile. J'ai passé plusieurs années à essayer de le faire. J'ai finalement réussi, mais toute solution impliquera des efforts commerciaux et techniques.
La plupart des éléments ci-dessous ne sont plus à jour. Il y a maintenant, après toutes ces années, un package Android.media.projection
https://developer.Android.com/reference/Android/media/projection/package-summary.html qui permet enfin ce vous avez besoin!
Pour être complet, je veux inclure votre propre commentaire selon lequel vous pouvez capturer une image de votre propre application en utilisant Bitmap.createBitmap(rootview.getDrawingCache());
et des mécanismes similaires.
READ_FRAMEBUFFER
Premièrement, vous avez raison de dire qu'une application normale ne peut pas utiliser l'autorisation READ_FRAMEBUFFER
, Car c'est le niveau "signature". Cela signifie que vous devez être signé avec la même clé que le système Android ROM) pour pouvoir prendre une telle capture d'écran.
Je pensais que c'était un peu triste, donc en 2009, j'ai fait un Android soumission de projet open-source pour demander qu'il soit ouvert 1 . La réponse de Dianne Hackborn, l'architecte Android était:
Um non. Absolument pas.
Alors ça s'est bien passé! Par conséquent, cette autorisation est toujours au niveau signature
- à ce jour.
Si vous aviez cette autorisation, cependant, vous pourriez appeler le membre captureScreen
de ISurfaceComposer
2 . Vous auriez besoin d'écrire du code natif pour accéder à cette fonction, en utilisant le Android NDK et aussi quelques API non documentées. Cependant, c'est possible.
En interne dans le sous-système graphique Android, cela utilise un appel glReadPixels
pour récupérer les pixels du GPU vers le CPU. (Le GPU est utilisé pour la plupart des compositing sur Android . En fait Android 4.0+ prend en charge des compositeurs matériels supplémentaires, et le Surface Flinger doit faire encore plus de travail pour ramener ces pixels vers le CPU.)
Cet appel fonctionne à merveille, à l'exception de quelques petits problèmes:
... et un gros problème ...
Pourtant, sur la plupart des appareils Android Android, vous pouvez obtenir 10 images par seconde. Mieux encore, cette API prend en charge la mise à l'échelle de l'image résultante dans le matériel sur le GPU , donc si vous êtes intelligent, vous pouvez pré-redimensionner l'image à la taille dont vous avez besoin, avant même que les pixels n'atteignent le CPU. Cela peut donc être extrêmement performant.
Notez bien sûr qu'en tant que rédacteur d'applications, vous ne pouvez pas appeler glReadPixels
car vous n'avez pas accès au contexte OpenGL approprié. Il appartient au déflecteur de surface.
/dev/graphics/fb0
Et similaireCertains sont tentés d'essayer de lire ces fichiers de périphériques Linux qui représentent le framebuffer. Cependant, il y a trois problèmes:
captureScreen
ci-dessus pour obtenir une image correcte.Nous entrons maintenant dans les solutions qui nécessitent une action commerciale.
Parler avec les fabricants de chipsets Android présente souvent une solution. Comme ils conçoivent le matériel, ils ont accès au framebuffer - et ils sont souvent capables de fournir des bibliothèques qui évitent complètement le Android modèle d'autorisations en accédant simplement à leurs pilotes de noyau personnalisés directement.
Si vous visez un modèle de téléphone spécifique, c'est souvent une bonne voie à suivre. Bien sûr, les chances sont que vous devrez coopérer avec le fabricant de téléphones ainsi qu'avec le fabricant de silicium.
Parfois, cela peut fournir des résultats exceptionnels . Par exemple, j'ai entendu dire qu'il est possible sur certains matériels de diriger le tampon de trame matériel du téléphone directement dans l'encodeur vidéo H.264 du matériel du téléphone, et de récupérer un flux vidéo pré-encodé de tout ce qui est sur l'écran du téléphone. Exceptionnel. (Malheureusement, je sais seulement que cela est possible sur les puces TI OMAP, qui se retirent progressivement du marché du téléphone ).
Android applique de manière rigide son modèle d'autorisation et présente quelques failles de sécurité. Cependant, les OEM Android peuvent parfois être plus négligents.
Par exemple, un grand OEM dont le nom commence par S a mis en place un moyen de capturer l'écran à l'aide d'une touche. Il l'enregistre dans un fichier lisible par le monde sur la carte SD. En théorie, vous pourriez trouver ce qui intercepte ces clés et voir comment cela fonctionne. Vous pourriez peut-être faire quelque chose de similaire.
Et il y a peut-être un moyen pour un autre grand OEM dont le nom commence également par S.
Non, je ne vais pas entrer dans les détails de cette section. Pour savoir comment faire ces choses, j'aurais besoin d'un logiciel de rétro-ingénierie, ce qui pourrait être illégal. Bonne chance cependant.
Comme décrit précédemment, les fabricants de téléphones ont un accès facile à une API qui fonctionne . Et les fabricants de téléphones ont les autorisations de niveau signature
requises.
Donc, tout ce que vous devez faire est de faire signer votre logiciel par le fabricant de téléphone.
C'est cependant difficile . En signant le logiciel, le fabricant de téléphones garantit sa qualité - il devrait donc vouloir auditer votre code source. De plus, en raison de la nature de Android - s'ils signent le logiciel, ils doivent être ceux qui le distribuent. Vous ne pouvez pas le mettre sur le marché s'il est signé par la signature de quelqu'un d'autre) .
Cependant, l'OEM n'a pas besoin de l'inclure sur le ROM - ils peuvent toujours le distribuer sur le marché Android. Mais vous ne pouvez pas.
Une bonne solution serait que chaque fournisseur signe une petite bibliothèque à laquelle il serait alors possible d'accéder par un SDK commun. Ce qui m'amène à ...
J'en sais beaucoup parce que je travaillais chez RealVNC. Nous avons travaillé avec tous les principaux fournisseurs de téléphones Android pour obtenir l'accès à ces API au niveau de la signature. Je ne saurais trop insister sur les nombreuses années-hommes d'efforts (commerciaux et techniques) nécessaires pour y parvenir. Certains OEM ont rendu public ce travail - par exemple 4 .
Je ne travaille plus chez RealVNC, je n'ai donc rien à gagner à faire la publicité de leur logiciel. Mais si vous voulez vraiment vraiment pouvoir capturer l'écran sur plusieurs appareils Android Android, vous voudrez peut-être vous approcher les sur la réutilisation de leur service de contrôle à distance ou Android SDK VNC 5 . Ce n'est pas open-source, vous devez donc vous attendre à payer, et croyez-moi, c'est juste) assez étant donné l'effort épique impliqué dans le travail avec tous ces OEM Android OEM.
Dans un souci d'équilibre, je dois souligner que d'autres fournisseurs ont également travaillé avec les fabricants de téléphones à ce sujet - par exemple Soti. Mais je pense qu'ils offrent tous des solutions de gestion de périphériques spécifiques, plutôt qu'un SDK général de contrôle à distance/injection d'événements.
Une autre option - le démon adb
qui écoute le débogage des connexions via USB a légèrement plus de privilèges qu'une application normale, c'est pourquoi il est capable de saisir l'écran (vous pouvez voir son image en utilisant le ddms
outil). Si vous pouvez exécuter n'importe quelle commande en utilisant adb
, vous pouvez également obtenir ces privilèges (selon la bibliothèque de captures d'écran Android liée précédemment).
Finalement, ce problème m'a réduit en poussière, et je suis parti pour des pâturages plus verts qui n'impliquaient pas d'essayer d'extraire les pixels de Android téléphones.
Avant de quitter RealVNC, nous avons à nouveau essayé de contribuer ces API au projet open-source Android. Cette fois, nous avons eu une réaction plus positive 6 . En bref, il a été suggéré que notre approche de la sécurité était presque la bonne, mais que le système graphique était trop perturbé pour accepter nos correctifs. Eh bien, la grande nouvelle est que le système graphique n'est plus en ébullition - en fait, il a maintenant que captureScreen
API ce qui signifie qu'aucune modification du système graphique n'est nécessaire, il peut donc être possible de soumettre un nouveau mécanisme de sécurité à l'AOSP autour de cette API qui résout finalement ce problème.
Bonne chance!
Peut-être que Android-screenshot-library peut vous aider. Mais bien sur leur page d'utilisation, il dit qu'il a besoin d'un service natif démarré avec adb (à partir du sdk Android)).
PS: N'oubliez pas que Screenshot UX ne fonctionne pas pour tous les téléphones non rootés.