意外と知られていない!? Android Beam(アンドロイドビーム)っていうAirDropみたいな機能のご紹介。(サンプルソースあり)

こんにちは。あなたの街の東野です。

iOSが7になり、

  • フラットデザインがダサい
  • アプリが動かなくなった

などと世間を賑わしましたが、ちゃんと素晴らしい機能も搭載されていました。

AirDrop

連絡先を知らない人にも、非接触で写真や動画などのコンテンツを送る事が出来るという機能。とても便利ですよね。

img01

実は、このAirDropに近い機能が、
AndroidにもOS4.1から搭載されているという事はあまり知られていません。

Android Beam(アンドロイドビーム)

スパロボの必殺技みたいな名前ですね。
おサイフケータイなどで使われるNFCチップ同士を使った通信です。

今回は、そんなAndroid Beamの使い方と、簡単なサンプル実装をご紹介いたします。


Android Beamを使ってみる

それでは、まず実際にAndroid Beamがどんなものなかのか使ってみましょう。

準備

まずは、設定からNFC通信にチェックを入れます。

img00

Bluetooth通信のチェックやペアリングは必要ありません。

基本的な使い方 その1:

アプリを起動した状態で、端末のNFCチップを近づけます。
すると「タップしてビーム」と表示されるので画面をタップします。
※送受信する双方の端末ともに、「タップしてビーム」が表示されたら、送信したい方の画面をタップして下さい。
受信側は同じアプリが入っていれば自動でそのアプリを起動し、入っていなければそのアプリを探しにGooglePlayを開きます

送信側の画面イメージ

Android Beamの送信側は、このような画面になります。

img02

受信側の画面イメージ

Android Beamの受信側は、このような画面になります。

img03

基本的な使い方 その2:

端末に保存されている写真または動画を選択した状態で、端末のNFCチップを近づけます。
タップしてビーム」と表示されるので画面をタップします。

ファイルの送信が開始されると受信側で「ビームを受信しています…」と表示されます。
そうなったらNFCはもう離しても大丈夫です、通信はNFCからBluetoothに切り替わっていますから。

受信が完了すると端末の内部ストレージに保存されます。

送信側の画面イメージ

img04

受信側の画面イメージ

img05

Android Beamのサンプル実装(OS4.0方式)

それでは、次はいよいよ、Android Beamをプログラミングしてみましょう。
そもそもAndroid BeamはOS4.0から搭載され、それがOS4.1で拡張されました。
OS4.0とOS4.1では通信方式もプログラミングも異なります。
まずはOS4.0方式から見ていきましょう。

マニフェスト

マニフェストファイルのパーミッションには、NFCを追加します。


送信側の実装

次に、Android Beamの送信側をつくっていきます。
その際に、必要なメソッドは以下になります。

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
    mNfcAdapter.setNdefPushMessageCallback(this, this);
}

@Override
public NdefMessage createNdefMessage(NfcEvent event) {
    String string1 = "test1";
    String string2 = "test2";
    byte[] bytes1 = string1.getBytes(Charset.forName("US-ASCII"));
    byte[] bytes2 = string2.getBytes(Charset.forName("US-ASCII"));
    NdefMessage msg = new NdefMessage(new NdefRecord[] {
        createMimeRecord("application/com.example.beamtest", byte1),
        createMimeRecord("application/com.example.beamtest", byte2),
    });
    return msg;
}

public NdefRecord createMimeRecord(String mimeType, byte[] payload) {
    byte[] mimeBytes = mimeType.getBytes(Charset.forName("US-ASCII"));
    NdefRecord mimeRecord = new NdefRecord(
        NdefRecord.TNF_MIME_MEDIA, mimeBytes, new byte[0], payload);
    return mimeRecord;
}

“test1”,”test2″という文字列を同時に送る場合のサンプルソースです。
NfcAdapterを取得し、setNdefPushMessageCallback(this, this)をセットします。
NdefMessageに複数のNdefRecordを入れる事で同時に送る事が出来ます。
この“application/com.example.beamtest”がキーになります。

受信側の実装

次に、Android Beamの受信側をつくっていきます。
まず、マニフェストファイルに受信側のActivityにIntent-Filterを設ける必要があります。


    
        
        
        
    

送信側で設定したキーをmimeTypeに設定します。

実際の受信処理は、以下のようになります。

@Override
public synchronized void onResume() {
    super.onResume();
    Intent intent = getIntent();
    if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction())) {
        Parcelable[] rawMsgs = intent.getParcelableArrayExtra( NfcAdapter.EXTRA_NDEF_MESSAGES);
        NdefMessage msg = (NdefMessage) rawMsgs[0];
        String string1 = new String(msg.getRecords()[0].getPayload());
        String string2 = new String(msg.getRecords()[1].getPayload());
    }
}

getIntent()の中からNdefMessageを取り出します。
メッセージが複数ある場合は、配列で取り出します。

string1,string2には、それぞれ”test1″,”test2″が入ります。

OS4.0方式の弱点を克服したOS4.1方式(BTSSP)の登場

お気づきかもしれませんが、文字列を送信する時に
byte[] bytes1 = string1.getBytes(Charset.forName(“US-ASCII”));

文字列をバイトデータに変換していました。
つまりバイトデータにすれば文字列だけでなく、どんなデータでも送れるのではないか?

理論上は可能です。
ただし、NFC通信には致命的な弱点がありました。

NFC通信は、通信速度が遅い。

実際に10kバイトほどの小さな画像データの転送を試みたところ、数十秒かかりました。
Android Beamでは、結局文字列程度の小さなデータしか送れなかったのです。

そこで、OS4.1から通信方式が拡張されました。

NFC通信を起点として、Bluetooth通信でファイル転送を可能にしました。
これをBTSSPと呼びます。

Android Beamのサンプル実装拡張(OS4.1方式)

拡張した、OS4.1の通信方法の実装ですが、マニフェストファイルのパーミッションにはNFCのみでOKです。

実際の通信には、Bluetoothが使用されますが、OSのサポートによりBluetoothのパーミッションは宣言する必要がありません。

前述の通り、事前のBluetooth通信のチェックやペアリングも必要ありません。

送信側の実装

送信側、Activityの実装です。
onCreate()に”mNfcAdapter.setNdefPushMessageCallback(this, this);”
ではなく
NfcAdapter.setBeamPushUrisCallback(this, this);
を実装します。

実際の送信箇所のソースコードは、以下になります。

@Override
public Uri[] createBeamUris(NfcEvent event) {
    String filename = "test.png";
    File dir = getFilesDir();
    File mFile = new File(dir, filename);
    Uri[] uri = new Uri[] { Uri.fromFile(mFile) };
    return uri;
}

ローカルに保存されているファイルのURIを返してやれば、通信が開始されます。

受信側の実装

受信側は、特にプログラムを作る必要がありません。

OSレベルでファイルの受け渡しが行われるからです。
受信が完了するとローカルにファイルが保存されます。


Android Beamの注意する点

注意が必要なのは、OS4.0とOS4.1の通信方式は共存出来ないという点です。
すると文字列・ファイルのどちらかを一方向でしか、送信出来ないものだという事です。

これでは、Android Beamの実装には利便性をあまり感じません。

それでは、次回はAndroid Beamを起点とした双方向通信について記載したいと思います。
お楽しみに。

コメントを残す

メールアドレスが公開されることはありません。