Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c1970190 authored by Martijn Coenen's avatar Martijn Coenen Committed by Android (Google) Code Review
Browse files

Merge "Add an API to manually invoke Android Beam."

parents 7d99b5a4 7fe9fa16
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -15844,6 +15844,7 @@ package android.nfc {
    method public static android.nfc.NdefRecord createApplicationRecord(java.lang.String);
    method public static android.nfc.NdefRecord createExternal(java.lang.String, java.lang.String, byte[]);
    method public static android.nfc.NdefRecord createMime(java.lang.String, byte[]);
    method public static android.nfc.NdefRecord createTextRecord(java.lang.String, java.lang.String);
    method public static android.nfc.NdefRecord createUri(android.net.Uri);
    method public static android.nfc.NdefRecord createUri(java.lang.String);
    method public int describeContents();
@@ -15880,6 +15881,7 @@ package android.nfc {
    method public deprecated void enableForegroundNdefPush(android.app.Activity, android.nfc.NdefMessage);
    method public void enableReaderMode(android.app.Activity, android.nfc.NfcAdapter.ReaderCallback, int, android.os.Bundle);
    method public static android.nfc.NfcAdapter getDefaultAdapter(android.content.Context);
    method public boolean invokeBeam(android.app.Activity);
    method public boolean isEnabled();
    method public boolean isNdefPushEnabled();
    method public void setBeamPushUris(android.net.Uri[], android.app.Activity);
+1 −0
Original line number Diff line number Diff line
@@ -48,6 +48,7 @@ interface INfcAdapter
    void setForegroundDispatch(in PendingIntent intent,
            in IntentFilter[] filters, in TechListParcel techLists);
    void setAppCallback(in IAppCallback callback);
    void invokeBeam();

    void dispatch(in Tag tag);

+40 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import android.content.Intent;
import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;

import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
@@ -473,6 +474,45 @@ public final class NdefRecord implements Parcelable {
        return new NdefRecord(TNF_EXTERNAL_TYPE, b, null, data);
    }

    /**
     * Create a new NDEF record containing UTF-8 text data.<p>
     *
     * The caller can either specify the language code for the provided text,
     * or otherwise the language code corresponding to the current default
     * locale will be used.
     *
     * Reference specification: NFCForum-TS-RTD_Text_1.0
     * @param languageCode The languageCode for the record. If locale is empty or null,
     *                     the language code of the current default locale will be used.
     * @param text   The text to be encoded in the record. Will be represented in UTF-8 format.
     * @throws IllegalArgumentException if text is null
     */
    public static NdefRecord createTextRecord(String languageCode, String text) {
        if (text == null) throw new NullPointerException("text is null");

        byte[] textBytes = text.getBytes(StandardCharsets.UTF_8);

        byte[] languageCodeBytes = null;
        if (languageCode != null && !languageCode.isEmpty()) {
            languageCodeBytes = languageCode.getBytes(StandardCharsets.US_ASCII);
        } else {
            languageCodeBytes = Locale.getDefault().getLanguage().
                    getBytes(StandardCharsets.US_ASCII);
        }
        // We only have 6 bits to indicate ISO/IANA language code.
        if (languageCodeBytes.length >= 64) {
            throw new IllegalArgumentException("language code is too long, must be <64 bytes.");
        }
        ByteBuffer buffer = ByteBuffer.allocate(1 + languageCodeBytes.length + textBytes.length);

        byte status = (byte) (languageCodeBytes.length & 0xFF);
        buffer.put(status);
        buffer.put(languageCodeBytes);
        buffer.put(textBytes);

        return new NdefRecord(TNF_WELL_KNOWN, RTD_TEXT, null, buffer.array());
    }

    /**
     * Construct an NDEF Record from its component fields.<p>
     * Recommend to use helpers such as {#createUri} or
+10 −1
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package android.nfc;

import android.app.Activity;
import android.app.Application;
import android.content.Intent;
import android.net.Uri;
import android.nfc.NfcAdapter.ReaderCallback;
import android.os.Binder;
@@ -327,6 +328,7 @@ public final class NfcActivityManager extends IAppCallback.Stub
        NfcAdapter.CreateNdefMessageCallback ndefCallback;
        NfcAdapter.CreateBeamUrisCallback urisCallback;
        NdefMessage message;
        Activity activity;
        Uri[] uris;
        int flags;
        synchronized (NfcActivityManager.this) {
@@ -338,6 +340,7 @@ public final class NfcActivityManager extends IAppCallback.Stub
            message = state.ndefMessage;
            uris = state.uris;
            flags = state.flags;
            activity = state.activity;
        }

        // Make callbacks without lock
@@ -362,7 +365,13 @@ public final class NfcActivityManager extends IAppCallback.Stub
                }
            }
        }

        if (uris != null && uris.length > 0) {
            for (Uri uri : uris) {
                // Grant the NFC process permission to read these URIs
                activity.grantUriPermission("com.android.nfc", uri,
                        Intent.FLAG_GRANT_READ_URI_PERMISSION);
            }
        }
        return new BeamShareData(message, uris, flags);
    }

+39 −0
Original line number Diff line number Diff line
@@ -1248,6 +1248,45 @@ public final class NfcAdapter {
        mNfcActivityManager.disableReaderMode(activity);
    }

    /**
     * Manually invoke Android Beam to share data.
     *
     * <p>The Android Beam animation is normally only shown when two NFC-capable
     * devices come into range.
     * By calling this method, an Activity can invoke the Beam animation directly
     * even if no other NFC device is in range yet. The Beam animation will then
     * prompt the user to tap another NFC-capable device to complete the data
     * transfer.
     *
     * <p>The main advantage of using this method is that it avoids the need for the
     * user to tap the screen to complete the transfer, as this method already
     * establishes the direction of the transfer and the consent of the user to
     * share data. Callers are responsible for making sure that the user has
     * consented to sharing data on NFC tap.
     *
     * <p>Note that to use this method, the passed in Activity must have already
     * set data to share over Beam by using method calls such as
     * {@link #setNdefPushMessageCallback(CreateNdefMessageCallback, Activity, Activity...)} or
     * {@link #setBeamPushUrisCallback(CreateBeamUrisCallback, Activity)}.
     *
     * @param activity the current foreground Activity that has registered data to share
     * @return whether the Beam animation was successfully invoked
     */
    public boolean invokeBeam(Activity activity) {
        if (activity == null) {
            throw new NullPointerException("activity may not be null.");
        }
        enforceResumed(activity);
        try {
            sService.invokeBeam();
            return true;
        } catch (RemoteException e) {
            Log.e(TAG, "invokeBeam: NFC process has died.");
            attemptDeadServiceRecovery(e);
            return false;
        }
    }

    /**
     * Enable NDEF message push over NFC while this Activity is in the foreground.
     *