Home | History | Annotate | Download | only in beam
      1 /*
      2  * Copyright (C) 2011 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.example.android.beam;
     18 
     19 import android.app.Activity;
     20 import android.content.Intent;
     21 import android.nfc.NdefMessage;
     22 import android.nfc.NdefRecord;
     23 import android.nfc.NfcAdapter;
     24 import android.nfc.NfcAdapter.CreateNdefMessageCallback;
     25 import android.nfc.NfcAdapter.OnNdefPushCompleteCallback;
     26 import android.nfc.NfcEvent;
     27 import android.os.Bundle;
     28 import android.os.Handler;
     29 import android.os.Message;
     30 import android.os.Parcelable;
     31 import android.provider.Settings;
     32 import android.text.format.Time;
     33 import android.view.Menu;
     34 import android.view.MenuInflater;
     35 import android.view.MenuItem;
     36 import android.widget.TextView;
     37 import android.widget.Toast;
     38 
     39 import java.nio.charset.Charset;
     40 
     41 
     42 public class Beam extends Activity implements CreateNdefMessageCallback,
     43         OnNdefPushCompleteCallback {
     44     NfcAdapter mNfcAdapter;
     45     TextView mInfoText;
     46     private static final int MESSAGE_SENT = 1;
     47 
     48     @Override
     49     public void onCreate(Bundle savedInstanceState) {
     50         super.onCreate(savedInstanceState);
     51         setContentView(R.layout.main);
     52 
     53         mInfoText = (TextView) findViewById(R.id.textView);
     54         // Check for available NFC Adapter
     55         mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
     56         if (mNfcAdapter == null) {
     57             mInfoText = (TextView) findViewById(R.id.textView);
     58             mInfoText.setText("NFC is not available on this device.");
     59         } else {
     60             // Register callback to set NDEF message
     61             mNfcAdapter.setNdefPushMessageCallback(this, this);
     62             // Register callback to listen for message-sent success
     63             mNfcAdapter.setOnNdefPushCompleteCallback(this, this);
     64         }
     65     }
     66 
     67 
     68     /**
     69      * Implementation for the CreateNdefMessageCallback interface
     70      */
     71     @Override
     72     public NdefMessage createNdefMessage(NfcEvent event) {
     73         Time time = new Time();
     74         time.setToNow();
     75         String text = ("Beam me up!\n\n" +
     76                 "Beam Time: " + time.format("%H:%M:%S"));
     77         NdefMessage msg = new NdefMessage(NdefRecord.createMime(
     78                 "application/com.example.android.beam", text.getBytes())
     79          /**
     80           * The Android Application Record (AAR) is commented out. When a device
     81           * receives a push with an AAR in it, the application specified in the AAR
     82           * is guaranteed to run. The AAR overrides the tag dispatch system.
     83           * You can add it back in to guarantee that this
     84           * activity starts when receiving a beamed message. For now, this code
     85           * uses the tag dispatch system.
     86           */
     87           //,NdefRecord.createApplicationRecord("com.example.android.beam")
     88         );
     89         return msg;
     90     }
     91 
     92     /**
     93      * Implementation for the OnNdefPushCompleteCallback interface
     94      */
     95     @Override
     96     public void onNdefPushComplete(NfcEvent arg0) {
     97         // A handler is needed to send messages to the activity when this
     98         // callback occurs, because it happens from a binder thread
     99         mHandler.obtainMessage(MESSAGE_SENT).sendToTarget();
    100     }
    101 
    102     /** This handler receives a message from onNdefPushComplete */
    103     private final Handler mHandler = new Handler() {
    104         @Override
    105         public void handleMessage(Message msg) {
    106             switch (msg.what) {
    107             case MESSAGE_SENT:
    108                 Toast.makeText(getApplicationContext(), "Message sent!", Toast.LENGTH_LONG).show();
    109                 break;
    110             }
    111         }
    112     };
    113 
    114     @Override
    115     public void onResume() {
    116         super.onResume();
    117         // Check to see that the Activity started due to an Android Beam
    118         if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) {
    119             processIntent(getIntent());
    120         }
    121     }
    122 
    123     @Override
    124     public void onNewIntent(Intent intent) {
    125         // onResume gets called after this to handle the intent
    126         setIntent(intent);
    127     }
    128 
    129     /**
    130      * Parses the NDEF Message from the intent and prints to the TextView
    131      */
    132     void processIntent(Intent intent) {
    133         Parcelable[] rawMsgs = intent.getParcelableArrayExtra(
    134                 NfcAdapter.EXTRA_NDEF_MESSAGES);
    135         // only one message sent during the beam
    136         NdefMessage msg = (NdefMessage) rawMsgs[0];
    137         // record 0 contains the MIME type, record 1 is the AAR, if present
    138         mInfoText.setText(new String(msg.getRecords()[0].getPayload()));
    139     }
    140 
    141     @Override
    142     public boolean onCreateOptionsMenu(Menu menu) {
    143         // If NFC is not available, we won't be needing this menu
    144         if (mNfcAdapter == null) {
    145             return super.onCreateOptionsMenu(menu);
    146         }
    147         MenuInflater inflater = getMenuInflater();
    148         inflater.inflate(R.menu.options, menu);
    149         return true;
    150     }
    151 
    152     @Override
    153     public boolean onOptionsItemSelected(MenuItem item) {
    154         switch (item.getItemId()) {
    155             case R.id.menu_settings:
    156                 Intent intent = new Intent(Settings.ACTION_NFCSHARING_SETTINGS);
    157                 startActivity(intent);
    158                 return true;
    159             default:
    160                 return super.onOptionsItemSelected(item);
    161         }
    162     }
    163 }
    164