コンテンツ共有用NFC共有ファイル
10420 ワード
Androidでは、Android Beam機能で大きなファイルを転送できますが、NFCとAndroidバージョン(4.1以上のAPI 16)を備えたデバイスでのみ実行できます.さらにAndroid BeamについてはBeaming NDEF Messages to Other Devices、NFCのNear Field Communicationを参照してください.
1.他のデバイスへのファイルの送信
NFCでファイルを送信するには、以下の3つの点が必要です.は権限(NFCとexternal storageの使用権限)を要求する. デバイスがNFCをサポートするかどうかをテストする. Android BeamにURIを提供する.
Android Beamファイル転送機能には、次の4つの要件があります.はAndroid 4.1(API 16)以上をサポートする. で転送するファイルはexternal storageにある必要があります. あなたが送信するすべてのファイルはworld-readableでなければなりません.Fileを通じてもいいです.setReadable(true,false)は、この権限を設定する. 転送するファイルに対応するURIを提供する必要があります(FileProvider.getUriForFileで生成されたContent URIは使用できません).
1.1マニフェストで宣言
1.1.1要求権限
注意
1.1.2 NFC featureの設定
NFCはhardware featureに属するため、以下のようにラベルを追加する必要があります.
注意: この属性は告知的なもので、Google Playはこの属性であなたのデバイスがサポートしていないアプリケーションをフィルタします. は、対応する権限を追加することを忘れないように設定する.
1.1.3 SDKバージョンの設定
Android BeamはAndroid 4.1(API 16)以上しかサポートしていないため、appはこの機能を必要とし、
1.2デバイスがAndroid Beamに対応しているかどうかをテストする
デバイスがAndroid Beamをサポートしているかどうかをテストするには、次の3つのステップが必要です.
i.NFCというfeatrueをoptionalに設定し、以下のようにする.
ii. デバイスがNFCをサポートするかどうかをテストする.PackageManagerを呼び出すhasSystemFeature()メソッドおよびFEATURE_NFCがパラメータとして入力.
iii.デバイスがAndroid Beamをサポートするかどうかをテストする.Androidバージョンを判断することでテストする.
デバイスがNFCとAndroid Beamをサポートすることを検証した後、使用時にデバイスがNFCとAndroid Beamの機能をオンにしたかどうかを判断する方法もあり、それぞれa.NfcAdapterのisEnabled()でNFCの機能がオンかどうかを検証することができる.b.NfcAdapterのisNdefPushEnabled()は、Android Beam機能がオンであることを検証する.
1.3提供ファイルのコールバック方法の作成
デバイスがAndroid Beamをサポートしてファイル転送を行うことを検証すると、転送したいファイルのレプリカのURIであるUriオブジェクトのセットを返すコールバックメソッドを追加する必要がありますが、Android Beamが他のデバイスにファイルを共有したいと検出すると、システムはコールバックメソッドを呼び出します.このコールバックメソッドを追加するには、NfcAdapterを実装します.CreateBeamUrisCallbackというインタフェースを作成し、overrideの中のcreateBeamUris()という抽象的な方法を以下の例に示します.
インタフェースが実装されると、このインタフェース実装クラスのインスタンスをAndroid Beamに提供し、setBeamPushUrisCallback()メソッドを使用します.
注意:setBeamPushUrisCallback()によってURIを提供するほか、setBeamPushUris()を使用することもできる(方法は、前者は動的であり、後者は固定的である.
1.4送信するファイルの設定上記ファイルURIの取得は、Uriにより行う.fromFile()メソッド 上記のコードはAndroid Beamの一部を使用しているだけで、もっと知りたいならBeaming NDEF Messages to Other Devicesを見てください.
2.他装置からのファイル受信
2.1展示データの要求に応える
Android Beamが質問ファイルを転送すると、actionからACTION_VIEW、MIMEタイプは、最初のファイルのファイルタイプと、最初のファイルのURIとからなる.ユーザがこのnotificationをクリックすると、このintentが発行される.アプリを鳴らすにはmanifestの対応するActivityの下にラベルを追加する必要があります.次の例を示します.
2.2ファイル読み込み権限の要求
2.3コピーしたファイルのパスを取得する
Android Beamは、コピーされたすべてのファイルを1つのパスの下に配置します.上記のintentには最初のファイルのURIが含まれていますが、あなたのappはAndroid Beamではなく他のappによって起動される可能性があります.他のappを起動するintentが持っているURIは異なるフォーマットである可能性があります.そのため、Uriのschemeとauthorityを判断して、どのように処理するかを決定します.
2.3.1 file URIの処理
File URIには、ファイルの絶対パスとファイル名が含まれています.次のように処理されます.
2.3.2 Content URIの処理
intentがcontent URIを含む場合、そのURIが指すファイルのパスとファイル名はMediaStoreに存在する可能性がある.URIのauthorityの値をテストしてMediaStoreから来たかどうかを判断することができます.MediaStoreのURIはAndroid Beamから送られてきたのかもしれないし、他のappから送られてきたのかもしれないが、どちらもパスとファイル名を得ることができる.URIのauthorityからcontent providerのタイプを判断し、対応する処理を行います.
Reference Sharing Files with NFC Sending Files to Another Device Receiving Files from Another Device
1.他のデバイスへのファイルの送信
NFCでファイルを送信するには、以下の3つの点が必要です.
Android Beamファイル転送機能には、次の4つの要件があります.
1.1マニフェストで宣言
1.1.1要求権限
// NFC
//READ_EXTERNAL_STORAGE
注意
READ_EXTERNAL_STORAGE
という権限は、API 19以前には不要だったが、API 19から必要になったので、ここに加えて、互換性のためである.1.1.2 NFC featureの設定
NFCはhardware featureに属するため、以下のようにラベルを追加する必要があります.
注意:
android:required
はtrueであり、デバイスがfeatureを持っていない場合、appが実行できないことを示しています.この機能が選択可能な機能である場合は、android:required
の値をfalseに設定する必要があります.1.1.3 SDKバージョンの設定
Android BeamはAndroid 4.1(API 16)以上しかサポートしていないため、appはこの機能を必要とし、
android:minSdkVersion="16"
を設定する必要があります.1.2デバイスがAndroid Beamに対応しているかどうかをテストする
デバイスがAndroid Beamをサポートしているかどうかをテストするには、次の3つのステップが必要です.
i.NFCというfeatrueをoptionalに設定し、以下のようにする.
ii. デバイスがNFCをサポートするかどうかをテストする.PackageManagerを呼び出すhasSystemFeature()メソッドおよびFEATURE_NFCがパラメータとして入力.
// 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
}
iii.デバイスがAndroid Beamをサポートするかどうかをテストする.Androidバージョンを判断することでテストする.
// Android Beam file transfer isn't supported
if (Build.VERSION.SDK_INT <
Build.VERSION_CODES.JELLY_BEAN_MR1) {
// If Android Beam isn't available, don't continue.
mAndroidBeamAvailable = false;
/*
* Disable Android Beam file transfer features here.
*/
// Android Beam file transfer is available, continue
}
デバイスがNFCとAndroid Beamをサポートすることを検証した後、使用時にデバイスがNFCとAndroid Beamの機能をオンにしたかどうかを判断する方法もあり、それぞれa.NfcAdapterのisEnabled()でNFCの機能がオンかどうかを検証することができる.b.NfcAdapterのisNdefPushEnabled()は、Android Beam機能がオンであることを検証する.
1.3提供ファイルのコールバック方法の作成
デバイスがAndroid Beamをサポートしてファイル転送を行うことを検証すると、転送したいファイルのレプリカのURIであるUriオブジェクトのセットを返すコールバックメソッドを追加する必要がありますが、Android Beamが他のデバイスにファイルを共有したいと検出すると、システムはコールバックメソッドを呼び出します.このコールバックメソッドを追加するには、NfcAdapterを実装します.CreateBeamUrisCallbackというインタフェースを作成し、overrideの中のcreateBeamUris()という抽象的な方法を以下の例に示します.
public class MainActivity extends Activity {
...
// List of URIs to provide to Android Beam
private Uri[] mFileUris = 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 mFileUris;
}
}
...
}
インタフェースが実装されると、このインタフェース実装クラスのインスタンスをAndroid Beamに提供し、setBeamPushUrisCallback()メソッドを使用します.
public class MainActivity extends Activity {
...
// Instance that returns available files from this app
private FileUriCallback mFileUriCallback;
...
@Override
protected void onCreate(Bundle savedInstanceState) {
...
// Android Beam file transfer is available, continue
...
mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
/*
* Instantiate a new FileUriCallback to handle requests for
* URIs
*/
mFileUriCallback = new FileUriCallback();
// Set the dynamic callback for URI requests.
mNfcAdapter.setBeamPushUrisCallback(mFileUriCallback,this);
...
}
...
}
注意:setBeamPushUrisCallback()によってURIを提供するほか、setBeamPushUris()を使用することもできる(方法は、前者は動的であり、後者は固定的である.
1.4送信するファイルの設定
/*
* Create a list of URIs, get a File,
* and set its permissions
*/
private Uri[] mFileUris = 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) {
mFileUris[0] = fileUri;
} else {
Log.e("My Activity", "No File URI available for file.");
}
2.他装置からのファイル受信
2.1展示データの要求に応える
Android Beamが質問ファイルを転送すると、actionからACTION_VIEW、MIMEタイプは、最初のファイルのファイルタイプと、最初のファイルのURIとからなる.ユーザがこのnotificationをクリックすると、このintentが発行される.アプリを鳴らすにはmanifestの対応するActivityの下にラベルを追加する必要があります.次の例を示します.
...
...
2.2ファイル読み込み権限の要求
2.3コピーしたファイルのパスを取得する
Android Beamは、コピーされたすべてのファイルを1つのパスの下に配置します.上記のintentには最初のファイルのURIが含まれていますが、あなたのappはAndroid Beamではなく他のappによって起動される可能性があります.他のappを起動するintentが持っているURIは異なるフォーマットである可能性があります.そのため、Uriのschemeとauthorityを判断して、どのように処理するかを決定します.
public class MainActivity extends Activity {
...
// A File object containing the path to the transferred files
private File mParentPath;
// Incoming Intent
private Intent mIntent;
...
/*
* Called from onNewIntent() for a SINGLE_TOP Activity
* or onCreate() for a new Activity. For onNewIntent(),
* remember to call setIntent() to store the most
* current Intent
*
*/
private void handleViewIntent() {
...
// Get the Intent action
mIntent = getIntent();
String action = mIntent.getAction();
/*
* For ACTION_VIEW, the Activity is being asked to display data.
* Get the URI.
*/
if (TextUtils.equals(action, Intent.ACTION_VIEW)) {
// Get the URI from the Intent
Uri beamUri = mIntent.getData();
/*
* Test for the type of URI, by getting its scheme value
*/
if (TextUtils.equals(beamUri.getScheme(), "file")) {
mParentPath = handleFileUri(beamUri);
} else if (TextUtils.equals(
beamUri.getScheme(), "content")) {
mParentPath = handleContentUri(beamUri);
}
}
...
}
...
}
2.3.1 file URIの処理
File URIには、ファイルの絶対パスとファイル名が含まれています.次のように処理されます.
...
public String handleFileUri(Uri beamUri) {
// Get the path part of the URI
String fileName = beamUri.getPath();
// Create a File object for this filename
File copiedFile = new File(fileName);
// Get a string containing the file's parent directory
return copiedFile.getParent();
}
...
2.3.2 Content URIの処理
intentがcontent URIを含む場合、そのURIが指すファイルのパスとファイル名はMediaStoreに存在する可能性がある.URIのauthorityの値をテストしてMediaStoreから来たかどうかを判断することができます.MediaStoreのURIはAndroid Beamから送られてきたのかもしれないし、他のappから送られてきたのかもしれないが、どちらもパスとファイル名を得ることができる.URIのauthorityからcontent providerのタイプを判断し、対応する処理を行います.
...
public String handleContentUri(Uri beamUri) {
// Position of the filename in the query Cursor
int filenameIndex;
// File object for the filename
File copiedFile;
// The filename stored in MediaStore
String fileName;
// Test the authority of the URI
if (!TextUtils.equals(beamUri.getAuthority(), MediaStore.AUTHORITY)) {
/*
* Handle content URIs for other content providers
*/
// For a MediaStore content URI
} else {
// Get the column that contains the file name
String[] projection = { MediaStore.MediaColumns.DATA };
Cursor pathCursor =
getContentResolver().query(beamUri, projection,
null, null, null);
// Check for a valid cursor
if (pathCursor != null &&
pathCursor.moveToFirst()) {
// Get the column index in the Cursor
filenameIndex = pathCursor.getColumnIndex(
MediaStore.MediaColumns.DATA);
// Get the full file name including path
fileName = pathCursor.getString(filenameIndex);
// Create a File object for the filename
copiedFile = new File(fileName);
// Return the parent directory of the file
return new File(copiedFile.getParent());
} else {
// The query didn't work; return null
return null;
}
}
}
...
Reference