Tuesday, July 22, 2025

Implementing “Share To...” in Android: A Real Example from My QR Contact App

 (Originally published in LinkedIn)

In Android, “Share To…” is a powerful feature that allows your app to receive data (like text, images, or contacts) from other apps. But how do you actually implement it in your own project?

In this article, I’ll walk through how I built a simple Android app called QR Contact Share, which takes a contact (shared from the Contacts app), parses the vCard, and turns it into a scannable QR code.

We’ll cover:

  • Declaring your app as a “Share To…” target
  • Receiving the data via Intent.ACTION_SEND
  • Building a QR code from shared content
  • UX niceties like boosting screen brightness temporarily


Step 1: Declare the Intent Filter

To let Android know your app can handle a specific type of shared content, declare an intent filter in your AndroidManifest.xml.

In our case, we handle contacts shared as vCards (text/x-vcard):

<activity android:name=".ShareToQRActivity"
    android:exported="true">
    <intent-filter>
        <action android:name="android.intent.action.SEND" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:mimeType="text/x-vcard" />
    </intent-filter>
</activity>

Now, whenever a contact is shared from another app, Android will offer your app as a target.


Step 2: Handle the Incoming vCard Data

In your ShareToQRActivity.java, you can access the data with:

final Intent intent = getIntent();
if (Intent.ACTION_SEND.equals(intent.getAction()) &&
    "text/x-vcard".equals(intent.getType())) {
    final Uri vcardUri = intent
        .getParcelableExtra(Intent.EXTRA_STREAM);
    if (vcardUri != null) {
        try (final InputStream inputStream =
            getContentResolver().openInputStream(vcardUri)){
            generateQRCode(readStreamToString(inputStream));
        } catch (Exception e) {
            e.printStackTrace();
            Toast.makeText(this, "Failed to read contact", Toast.LENGTH_SHORT).show();
        }
    }
}

Step 3: Clean Up the vCard (Optional but Crucial)

vCard files often include embedded images (like contact photos), which can be too large to encode in a QR code. This can cause the app to crash or the QR to fail.

To avoid this, we scan through the vCard and strip out photo-related fields (typically encoded as base64). It’s a simple pre-processing step that ensures your QR code stays within size limits without affecting core contact details like name, phone, or email.


Step 4: Generate and Display the QR Code

We use ZXing (a popular QR code library) to generate the bitmap:

private void generateQRCode(String text) {
    final QRCodeWriter writer = new QRCodeWriter();
    try {
        final Bitmap bitmap = toBitmap(writer.encode(text, BarcodeFormat.QR_CODE, 800, 800));
        qrImageView.setImageBitmap(bitmap);
    } catch (WriterException e) {
        e.printStackTrace();
        Toast.makeText(this, "QR generation failed", Toast.LENGTH_SHORT).show();
    }
}

private static Bitmap toBitmap(BitMatrix matrix) {
    final int width = matrix.getWidth();
    final int height = matrix.getHeight();
    final Bitmap bmp = Bitmap.createBitmap(
        width, height, Bitmap.Config.RGB_565);
    for (int x = 0; x < width; x++)
        for (int y = 0; y < height; y++)
            bmp.setPixel(x, y, matrix.get(x, y) ?
                0xFF000000 : 0xFFFFFFFF);
    return bmp;
}

Bonus: Make It Easier to Scan

To improve usability, we temporarily maximize the screen brightness while displaying the QR code. This ensures the code is easy to scan under bright sunlight or on dim screens — a subtle but thoughtful UX enhancement.

Here’s how we do it:

 private static final float DEFAULT_BRIGHTNESS = -1f;
    private ImageView qrImageView;
    private float originalBrightness = DEFAULT_BRIGHTNESS;

    @Override
    protected void onResume() {
        super.onResume();
        increaseScreenBrightness();
    }

    @Override
    protected void onPause() {
        super.onPause();
        restoreScreenBrightness();
    }

    private void increaseScreenBrightness() {
        final Window window = getWindow();
        final WindowManager.LayoutParams layoutParams = window.getAttributes();
        originalBrightness = layoutParams.screenBrightness;
        layoutParams.screenBrightness = 1f;
        window.setAttributes(layoutParams);
    }

    private void restoreScreenBrightness() {
        if (originalBrightness != DEFAULT_BRIGHTNESS) {
            final Window window = getWindow();
            final WindowManager.LayoutParams layoutParams = window.getAttributes();
            layoutParams.screenBrightness = originalBrightness;
            window.setAttributes(layoutParams);
        }
    }

Full Source Code

The project is open source and available on GitHub: https://github.com/The-Java-Druid/qr-contact-share

You can also install in your Android phone from here: https://play.google.com/store/apps/details?id=com.qrcontactshare

Feel free to explore, fork it, or contribute ideas.


Final Thoughts

This project is a minimal example of how powerful Android's intent system is. With just a few lines of code, you can tap into user workflows and make your app part of the ecosystem.

Have you used the “Share To…” system in your own apps? What’s your use case? Let’s connect and discuss.

No comments:

Post a Comment

Your Friendly Guide to Mastering the Linux Kernel with kernel-update

If you have ever explored the inner workings of Linux, you probably know that the kernel is the heart of your operating system. While most u...