• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
onCreate(Bundle savedInstanceState)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         }
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      * Implementation for the CreateNdefMessageCallback interface
69      */
70     @Override
createNdefMessage(NfcEvent event)71     public NdefMessage createNdefMessage(NfcEvent event) {
72         Time time = new Time();
73         time.setToNow();
74         String text = ("Beam me up!\n\n" +
75                 "Beam Time: " + time.format("%H:%M:%S"));
76         NdefMessage msg = new NdefMessage(
77                 new NdefRecord[] { createMimeRecord(
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
onNdefPushComplete(NfcEvent arg0)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
onResume()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
onNewIntent(Intent intent)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      */
processIntent(Intent intent)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     /**
142      * Creates a custom MIME type encapsulated in an NDEF record
143      *
144      * @param mimeType
145      */
createMimeRecord(String mimeType, byte[] payload)146     public NdefRecord createMimeRecord(String mimeType, byte[] payload) {
147         byte[] mimeBytes = mimeType.getBytes(Charset.forName("US-ASCII"));
148         NdefRecord mimeRecord = new NdefRecord(
149                 NdefRecord.TNF_MIME_MEDIA, mimeBytes, new byte[0], payload);
150         return mimeRecord;
151     }
152 
153     @Override
onCreateOptionsMenu(Menu menu)154     public boolean onCreateOptionsMenu(Menu menu) {
155         // If NFC is not available, we won't be needing this menu
156         if (mNfcAdapter == null) {
157             return super.onCreateOptionsMenu(menu);
158         }
159         MenuInflater inflater = getMenuInflater();
160         inflater.inflate(R.menu.options, menu);
161         return true;
162     }
163 
164     @Override
onOptionsItemSelected(MenuItem item)165     public boolean onOptionsItemSelected(MenuItem item) {
166         switch (item.getItemId()) {
167             case R.id.menu_settings:
168                 Intent intent = new Intent(Settings.ACTION_NFCSHARING_SETTINGS);
169                 startActivity(intent);
170                 return true;
171             default:
172                 return super.onOptionsItemSelected(item);
173         }
174     }
175 }
176