Open-source project
mattprecious/telescope avatar
mattprecious/telescope

Telescope turns a multi-finger gesture in your Android app into a bug report

A simple tool to allow easy bug report capturing within your app.

1,168 stars115 forksJavaApache-2.0

At a glance

What is it?
Telescope is an Apache-2.0 licensed Android library from 2014 that you wrap around your activity's view hierarchy in debug builds, so a multi-finger touch captures a screenshot and hands it to a Lens that composes an email, optionally pre-filled with app and device information. It is small, it has no UI of its own, and the screenshot cleanup is the developer's job.
Who is it for?
Telescope fits an Android team that wants a repeatable way for testers to send a screenshot and device context from a build they can install, and that already has an email flow to attach it to. It does not fit a team that wants automatic crash uploads to a service, since the built-in Lenses only compose an email, and it does not fit production builds, since the README's guidance is to wrap the activity layouts only in debug builds.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 3 days ago.
What is it written in?
Mainly Java, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A view wrapper you place at the root of your hierarchy

Telescope is described as a simple tool to allow easy bug report capturing within your app, and the whole integration is two steps.

Place a TelescopeLayout at the root of your hierarchy, then add a callback to the view group with setLens(Lens). That is the entire API surface described in the README, and it is worth noting what is absent: there is no registration step, no service, no configuration file and no network code.

The mechanism is a gesture. The library watches for a multi-finger touch on the view group it wraps, shows a progress indication while the touch is held, captures a screenshot, and then hands that screenshot and the gesture context to the Lens. A screenshot of the app as the tester sees it, at the moment they noticed the bug, is the artefact the tool is built around, and the reason it exists as a view rather than as a library of helper functions is that it has to sit on top of your content to see it.

Two default implementations of Lens are provided.

* EmailLens: Compose an email with the provided addresses and subject (optional). * EmailDeviceInfoLens: Enhances EmailLens by pre-populating the email body with app and device info.

The second one is the reason to use this at all. A screenshot alone tells a developer what the screen looked like; a screenshot plus the device model, the app version and whatever else the lens puts in the body tells them whether the bug is version-specific or device-specific. A bug report that arrives with that context attached saves the round trip of asking the tester to go and find it.

The reference implementation the README points at is the u2020 project, described as a more advanced example, which is a good place to look if the two built-in lenses are not what you need.

Screenshots persist in private storage until you delete them

The storage behaviour is the detail that matters most for an Android library, and the README is specific about it.

Screenshots will be stored on the external storage in your app's private directory. To have Telescope clean up the screenshots folder, call TelescopeLayout.cleanUp(Context). Ideally, this would be called in the onDestroy() method of your Activity or Fragment.

Two things follow. The files are on external storage, which is the shared volume rather than the app's internal sandbox, so they are not protected by the app's private data directory in the way the phrase private directory might suggest on a modern Android, and they survive the app being killed. And they are not cleaned up for you, so a library that captures screenshots on a gesture and never deletes them will fill up the user's storage over time, which is exactly the kind of thing that gets an app flagged.

The permission story follows from the same decision. Pre-KitKat, WRITE_EXTERNAL_STORAGE is required for saving screenshots, and the README notes that screenshots can be disabled using the configuration options below. That is the escape hatch: if you do not want the permission and do not want the files, turn the screenshot off and the lens receives the bug report without an image.

So the honest summary of the storage design is that Telescope optimises for the report, and the cleanup is a call the integrating app has to remember to make. An app that wires it into an activity without wiring the cleanup has a slow leak, and the README's ideally is doing a lot of work in that sentence.

Six knobs, and the trigger count is the one you will change

The configuration is a short list, and almost every entry has both an XML attribute and a setter, which is the usual Android pattern for making a view configurable in a layout and in code.

* Set the number of fingers to trigger with app:telescope_pointerCount / setPointerCount(int) * Set the progress color with app:telescope_progressColor / setProgressColor(int) * Change the screenshot method with app:telescope_screenshotMode / setScreenshotMode(ScreenshotMode) * Screenshot children only with app:telescope_screenshotChildrenOnly / setScreenshotChildrenOnly(boolean) * Set the screenshot target with setScreenshotTarget(View) * Disable vibration with app:telescope_vibrate / setVibrate(boolean)

The pointer count is the setting that decides whether the tool is usable in practice, because a multi-finger gesture has to be unlikely to happen by accident while a user is interacting with the app. Two fingers is the conventional choice for a screen that might have pinch gestures, and more is safer for a screen with no multi-touch of its own.

The screenshot mode and the target are the settings for making the capture match what you want to see. A screenshot of the whole window includes the system chrome and the status bar, while a screenshot of a specific target view captures just that region, which is usually what you want when the bug is in a particular component. Screenshot children only narrows the capture to the children of the view group rather than the group itself, and the vibration flag lets you turn off the haptic tick so the trigger is silent.

The progress colour is a small thing, but it is the one piece of the tool the user actually sees, since it is the feedback that the gesture has been recognised and that a capture is in progress.

It ships as an apklib, which is not a normal jar

The download section gives two forms, and the difference between them is the sort of detail that trips people up.

For Gradle:

groovy
compile 'com.mattprecious.telescope:telescope:2.4.0'

For Maven:

xml
<dependency>
  <groupId>com.mattprecious.telescope</groupId>
  <artifactId>telescope</artifactId>
  <version>2.4.0</version>
  <type>apklib</type>
</dependency>

The type element is apklib, which is the old Android library format, a zip that contains resources and a manifest rather than a plain jar of classes. That was the normal way to ship an Android library with resources before the Android Gradle plugin made that unnecessary, and it is the reason this dependency is not interchangeable with an ordinary jar.

Two other things are worth knowing. The compile configuration in the Gradle snippet is the older configuration mechanism, not the modern implementation or api, so a project on a recent Android Gradle plugin will need to adjust it. And the version in the README, 2.4.0, is a specific release; the project is not on a continuous integration channel for consumers, it is on Maven Central with numbered versions.

The README also points at a Sonatype repository redirect for the LATEST version, which is the path to follow if you want the newest published artefact rather than the one written into the documentation.

The repository itself is a Gradle project with a telescope/ module for the library, a telescope-sample/ module for the sample application, an images/ directory with the demo, a CHANGELOG.md, a renovate.json for dependency updates, and gradlew wrappers.

The README is from a 2014 Android, and that constrains what you can use

The licence header in the README dates the work. Copyright 2014 Matthew Precious, and the text is the Apache 2.0 licence in full, which matches the repository metadata and the LICENSE.txt at the root. That is a permissive licence, and you can use, modify and redistribute the library, including in a commercial app, provided the notice and licence text are kept. This is a licensing fact rather than legal advice.

The age shows in the technical details, and an adopter should know where the boundaries are. The permission discussion is about pre-KitKat, which is the Android 4.4 era, and the write-to-external-storage model is from the same period. The build instructions use the compile configuration and the apklib packaging type, both of which predate the current Android Gradle plugin conventions. The project is in the usual position of a library that was written for a specific era of the platform and has been kept compiling since.

Maintenance is at least current, and that is the more surprising part. The repository is not archived, the default branch is main, and the last push was on 2026-10-13. There are no GitHub releases, so the version history lives in the CHANGELOG.md and in Maven Central rather than in a release feed, and the renovate.json configuration suggests the dependency updates are automated rather than manual.

So the honest picture is of a small, stable, Apache-licensed Android library that still receives commits, whose API is a handful of view and setter methods, and whose era is visible in the packaging.

One last recommendation from the README is the one that keeps it out of production. If you are using the Gradle-based build system, you can wrap this view group around your activity layouts only in the debug builds. A tool that captures screenshots of your app on a multi-finger gesture has no business being in the build your users download.

The alternative is u2020, which is a debug app rather than a view

The README points at the u2020 project as a more advanced example, and the difference in approach is instructive.

Telescope is a component. It has no interface of its own beyond the progress indicator, it produces one artefact, a screenshot, and it hands that artefact to a callback. Everything else, where the report goes, whether an email, a ticket, a chat message or an upload to your own endpoint, is the integrating app's problem. The Lens abstraction is the seam where that decision lives, and the two default implementations are only the two easiest answers to it.

Telescope sits inside your app's view hierarchy and uses your app's own context, which is the difference that matters for a tool of this kind.

That difference decides the case for each. Telescope is the better choice when you control the build, when you want the report to carry your own context, and when you want the report to flow through your own channel rather than a third party's.

There is also the option of writing no library at all and adding a debug-only capture to your own code. That is more work than it sounds, because the hard part is not the screenshot, it is the gesture that does not collide with your app's own touch handling, and the progress feedback that tells the tester the gesture was understood. Telescope is a small, opinionated answer to exactly those two problems, and that is a reasonable reason to take it even if you write the Lens yourself.

Editorial conclusion

Telescope fits an Android team that wants a repeatable way for testers to send a screenshot and device context from a build they can install, and that already has an email flow to attach it to. It does not fit a team that wants automatic crash uploads to a service, since the built-in Lenses only compose an email, and it does not fit production builds, since the README's guidance is to wrap the activity layouts only in debug builds. Before adopting it, put the TelescopeLayout in your debug variant, wire a Lens that reaches your own reporting endpoint, and call TelescopeLayout.cleanUp(Context) where you can, because the screenshots persist until something removes them.

Frequently asked questions

How do I add Telescope to an Android app?

Place a TelescopeLayout at the root of your view hierarchy, then call setLens(Lens) on it with a Lens implementation. Two are provided, EmailLens, which composes an email with the provided addresses and subject, and EmailDeviceInfoLens, which adds app and device information to the email body.

Where does Telescope store screenshots and how are they cleaned up?

Screenshots are stored on the external storage in the app's private directory, and they are not removed automatically. You call TelescopeLayout.cleanUp(Context), ideally from the onDestroy() method of your Activity or Fragment, as the README instructs.

Can I disable screenshots in Telescope?

Yes. The README notes that screenshots can be disabled using the configuration options, and the screenshot behaviour is controlled by app:telescope_screenshotMode / setScreenshotMode(ScreenshotMode), along with app:telescope_screenshotChildrenOnly and setScreenshotTarget(View).

How do I get the Telescope dependency?

From Maven Central, as com.mattprecious.telescope:telescope at version 2.4.0 in the README. The Gradle snippet uses compile and the Maven snippet uses type apklib, the old Android library packaging rather than a plain jar.

Should Telescope be included in release builds?

No. The README says that with the Gradle-based build system you can wrap the view group around your activity layouts only in the debug builds, which is sensible for a tool that captures screenshots of your app on a multi-finger gesture.

Official sources

  1. Issues
  2. License: Apache-2.0
  3. mattprecious/telescope on GitHub
  4. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/mattprecious-telescope.svg)](https://hysenlabs.com/projects/mattprecious-telescope)

Was this useful?