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:
- Transfer file Android Beam untuk file berukuran besar hanya tersedia di Android 4.1 (API level 16) dan yang lebih baru.
- File yang ingin ditransfer harus berada di penyimpanan eksternal. Untuk mempelajari lebih lanjut cara menggunakan penyimpanan eksternal, baca Menggunakan penyimpanan eksternal.
-
Setiap file yang ingin ditransfer harus dapat dibaca secara global. Anda dapat menetapkan izin ini dengan memanggil metode
File.setReadable(true,false)
. -
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