Google berkomitmen untuk mendorong terwujudnya keadilan ras bagi komunitas Kulit Hitam. Lihat caranya.

Mengirim file ke perangkat lain dengan NFC

Tutorial ini menunjukkan cara mendesain aplikasi Anda untuk mengirim file berukuran besar ke perangkat lain menggunakan transfer file Android Beam. Untuk mengirim file, Anda perlu meminta izin penggunaan NFC dan penyimpanan eksternal, melakukan pengujian untuk memastikan perangkat Anda dapat mendukung NFC, dan memberikan URI ke transfer file Android Beam.

Fitur transfer file Android Beam memiliki persyaratan berikut:

  1. Transfer file Android Beam untuk file berukuran besar hanya tersedia di Android 4.1 (API level 16) dan yang lebih baru.
  2. File yang ingin ditransfer harus berada di penyimpanan eksternal. Untuk mempelajari lebih lanjut cara menggunakan penyimpanan eksternal, baca Menggunakan penyimpanan eksternal.
  3. Setiap file yang ingin ditransfer harus dapat dibaca secara global. Anda dapat menetapkan izin ini dengan memanggil metode File.setReadable(true,false).
  4. Anda harus memberikan URI file untuk file yang ingin ditransfer. Transfer file Android Beam tidak dapat menangani URI konten yang dihasilkan oleh FileProvider.getUriForFile.

Mendeklarasikan fitur dalam manifes

Edit manifes aplikasi terlebih dahulu untuk mendeklarasikan izin dan fitur yang dibutuhkan aplikasi Anda.

Minta izin

Agar aplikasi dapat menggunakan transfer file Android Beam untuk mengirim file dari penyimpanan eksternal menggunakan NFC, Anda harus meminta izin berikut dalam manifes aplikasi:

NFC
Izinkan aplikasi Anda mengirim data melalui NFC. Untuk menentukan izin ini, tambahkan elemen berikut sebagai turunan dari elemen <manifest>:
        <uses-permission android:name="android.permission.NFC" />
    
READ_EXTERNAL_STORAGE
Izinkan aplikasi Anda membaca dari penyimpanan eksternal. Untuk menentukan izin ini, tambahkan elemen berikut sebagai turunan dari elemen <manifest>:
        <uses-permission
                android:name="android.permission.READ_EXTERNAL_STORAGE" />
    

Catatan: Mulai Android 4.2.2 (API level 17), izin ini sudah tidak diberlakukan. Versi platform selanjutnya mungkin memerlukannya untuk aplikasi yang ingin membaca dari penyimpanan eksternal. Untuk memastikan kompatibilitas maju, minta izin sekarang sebelum diminta.

Tentukan fitur NFC

Tentukan bahwa aplikasi Anda menggunakan NFC, dengan menambahkan elemen <uses-feature> sebagai turunan dari elemen <manifest>. Tetapkan atribut android:required ke true untuk menunjukkan bahwa aplikasi Anda tidak akan berfungsi kecuali NFC ada.

Cuplikan berikut menunjukkan cara menentukan elemen <uses-feature>:

    <uses-feature
        android:name="android.hardware.nfc"
        android:required="true" />

Perlu diketahui bahwa jika aplikasi Anda hanya menggunakan NFC sebagai salah satu opsi, tetapi masih dapat berfungsi tanpa NFC, Anda harus menetapkan android:required ke false, lalu menguji NFC dalam kode.

Tentukan transfer file Android Beam

Karena transfer file Android Beam hanya tersedia di Android 4.1 (API level 16) dan yang lebih baru, jika aplikasi Anda bergantung pada transfer file Android Beam untuk bagian penting dari fungsionalitasnya, Anda harus menentukan elemen <uses-sdk> dengan atribut android:minSdkVersion="16". Jika tidak, Anda dapat menetapkan android:minSdkVersion ke nilai lain yang diperlukan, lalu menguji versi platform dalam kode, seperti yang dijelaskan di bagian berikut.

Melakukan pengujian untuk dukungan transfer file Android Beam

Untuk menentukan dalam manifes aplikasi Anda bahwa NFC bersifat opsional, gunakan elemen berikut ini:

    <uses-feature android:name="android.hardware.nfc" android:required="false" />

Jika menetapkan atribut android:required="false", Anda harus menguji dukungan NFC dan dukungan transfer file Android Beam dalam kode.

Untuk menguji dukungan transfer file Android Beam dalam kode, mulailah dengan menguji bahwa perangkat mendukung NFC dengan memanggil PackageManager.hasSystemFeature() beserta argumen FEATURE_NFC. Selanjutnya, pastikan versi Android mendukung transfer file Android Beam dengan menguji nilai SDK_INT. Jika transfer file Android Beam didukung, dapatkan instance dari pengontrol NFC, yang memungkinkan Anda berkomunikasi dengan hardware NFC. Contoh:

Kotlin

    class MainActivity : Activity() {
        ...
        private lateinit var nfcAdapter: NfcAdapter
        // Flag to indicate that Android Beam is available
        private var androidBeamAvailable = false
        ...
        override fun onCreate(savedInstanceState: Bundle?) {
            ...
            androidBeamAvailable = if (!packageManager.hasSystemFeature(PackageManager.FEATURE_NFC)) {
                // NFC isn't available on the device
                /*
                  * Disable NFC features here.
                  * For example, disable menu items or buttons that activate
                  * NFC-related features
                  */
                false
            // Android Beam file transfer isn't supported
            } else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
                // If Android Beam isn't available, don't continue.
                androidBeamAvailable = false
                /*
                 * Disable Android Beam file transfer features here.
                 */
                ...
                false
            } else {
                // Android Beam file transfer is available, continue
                nfcAdapter = NfcAdapter.getDefaultAdapter(this)
                ...
                true
            }
        }
        ...
    }
    

Java

    public class MainActivity extends Activity {
        ...
        NfcAdapter nfcAdapter;
        // Flag to indicate that Android Beam is available
        boolean androidBeamAvailable  = false;
        ...
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            ...
            // NFC isn't available on the device
            if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_NFC)) {
                /*
                 * Disable NFC features here.
                 * For example, disable menu items or buttons that activate
                 * NFC-related features
                 */
                ...
            // Android Beam file transfer isn't supported
            } else if (Build.VERSION.SDK_INT <
                    Build.VERSION_CODES.JELLY_BEAN_MR1) {
                // If Android Beam isn't available, don't continue.
                androidBeamAvailable = false;
                /*
                 * Disable Android Beam file transfer features here.
                 */
                ...
            // Android Beam file transfer is available, continue
            } else {
                androidBeamAvailable = true;
                nfcAdapter = NfcAdapter.getDefaultAdapter(this);
            ...
            }
        }
        ...
    }
    

Buat metode callback yang memberikan file

Setelah memverifikasi bahwa perangkat mendukung transfer file Android Beam, tambahkan metode callback yang akan dipanggil sistem saat transfer file Android Beam mendeteksi bahwa pengguna ingin mengirim file ke perangkat lain yang mendukung NFC. Dalam metode callback ini, tampilkan array objek Uri. Transfer file Android Beam akan menyalin file yang direpresentasikan oleh URI ini ke perangkat penerima.

Untuk menambahkan metode callback, implementasikan antarmuka NfcAdapter.CreateBeamUrisCallback dan metodenya createBeamUris(). Cuplikan berikut menunjukkan cara untuk melakukannya:

Kotlin

    public class MainActivity : Activity() {
        ...
        // List of URIs to provide to Android Beam
        private val fileUris = mutableListOf<Uri>()
        ...
        /**
         * Callback that Android Beam file transfer calls to get
         * files to share
         */
        private inner class FileUriCallback : NfcAdapter.CreateBeamUrisCallback {
            /**
             * Create content URIs as needed to share with another device
             */
            override fun createBeamUris(event: NfcEvent): Array<Uri> {
                return fileUris.toTypedArray()
            }
        }
        ...
    }
    

Java

    public class MainActivity extends Activity {
        ...
        // List of URIs to provide to Android Beam
        private Uri[] fileUris = new Uri[10];
        ...
        /**
         * Callback that Android Beam file transfer calls to get
         * files to share
         */
        private class FileUriCallback implements
                NfcAdapter.CreateBeamUrisCallback {
            public FileUriCallback() {
            }
            /**
             * Create content URIs as needed to share with another device
             */
            @Override
            public Uri[] createBeamUris(NfcEvent event) {
                return fileUris;
            }
        }
        ...
    }
    

Setelah Anda mengimplementasikan antarmuka tersebut, berikan callback ke transfer file Android Beam dengan memanggil setBeamPushUrisCallback(). Cuplikan berikut menunjukkan cara untuk melakukannya:

Kotlin

    class MainActivity : Activity() {
        ...
        private lateinit var nfcAdapter: NfcAdapter
        // Flag to indicate that Android Beam is available
        private var androidBeamAvailable = false
        ...
        override fun onCreate(savedInstanceState: Bundle?) {
            ...
            // Android Beam file transfer is available, continue
            nfcAdapter = NfcAdapter.getDefaultAdapter(this).apply {

                /*
                 * Instantiate a new FileUriCallback to handle requests for
                 * URIs
                 */
                fileUriCallback = FileUriCallback()
                // Set the dynamic callback for URI requests.
                nfcAdapter.setBeamPushUrisCallback(fileUriCallback, this@MainActivity)
            }
            ...
        }
        ...
    }
    

Java

    public class MainActivity extends Activity {
        ...
        // Instance that returns available files from this app
        private FileUriCallback fileUriCallback;
        ...
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            ...
            // Android Beam file transfer is available, continue
            ...
            nfcAdapter = NfcAdapter.getDefaultAdapter(this);
            /*
             * Instantiate a new FileUriCallback to handle requests for
             * URIs
             */
            fileUriCallback = new FileUriCallback();
            // Set the dynamic callback for URI requests.
            nfcAdapter.setBeamPushUrisCallback(fileUriCallback,this);
            ...
        }
        ...
    }
    

Catatan: Anda juga dapat menyediakan array objek Uri langsung ke framework NFC melalui instance NfcAdapter aplikasi Anda. Pilih metode ini jika Anda dapat menentukan URI yang akan ditransfer sebelum peristiwa sentuh NFC terjadi. Untuk mempelajari pendekatan ini lebih lanjut, lihat NfcAdapter.setBeamPushUris().

Menentukan file yang akan dikirim

Untuk mentransfer satu atau beberapa file ke perangkat lainnya yang mendukung NFC, dapatkan URI file (URI dengan skema file) untuk setiap file, lalu tambahkan URI ke array objek Uri. Untuk mentransfer file, Anda juga harus memiliki akses baca permanen bagi file tersebut. Sebagai contoh, cuplikan berikut menunjukkan cara mendapatkan URI file dari nama file lalu menambahkan URI tersebut ke array:

Kotlin

            /*
             * Create a list of URIs, get a File,
             * and set its permissions
             */
            val fileUris = mutableListOf<Uri>()
            val transferFile = "transferimage.jpg"
            val extDir = getExternalFilesDir(null)
            val requestFile = File(extDir, transferFile).apply {
                setReadable(true, false)
            }
            // Get a URI for the File and add it to the list of URIs
            Uri.fromFile(requestFile)?.also { fileUri ->
                fileUris += fileUri
            } ?: Log.e("My Activity", "No File URI available for file.")
    

Java

            /*
             * Create a list of URIs, get a File,
             * and set its permissions
             */
            private Uri[] fileUris = new Uri[10];
            String transferFile = "transferimage.jpg";
            File extDir = getExternalFilesDir(null);
            File requestFile = new File(extDir, transferFile);
            requestFile.setReadable(true, false);
            // Get a URI for the File and add it to the list of URIs
            fileUri = Uri.fromFile(requestFile);
            if (fileUri != null) {
                fileUris[0] = fileUri;
            } else {
                Log.e("My Activity", "No File URI available for file.");
            }
    

Untuk informasi lain yang terkait, lihat Opsi Penyimpanan

Untuk kode contoh yang terkait dengan halaman ini, lihat Contoh Android BeamLargeFiles