/* * Copyright (C) 2011 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.tudarmstadt.informatik.hostage.sync; import android.annotation.TargetApi; import android.app.Activity; import android.content.Intent; import android.nfc.NdefMessage; import android.nfc.NdefRecord; import android.nfc.NfcAdapter; import android.nfc.NfcAdapter.CreateNdefMessageCallback; import android.nfc.NfcAdapter.OnNdefPushCompleteCallback; import android.nfc.NfcEvent; import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.os.Parcelable; import android.util.Log; import android.widget.TextView; import android.widget.Toast; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.ArrayList; import java.util.HashMap; import de.tudarmstadt.informatik.hostage.R; import de.tudarmstadt.informatik.hostage.logging.DatabaseHandler; @TargetApi(Build.VERSION_CODES.JELLY_BEAN) public class NFCSync extends Activity implements CreateNdefMessageCallback, OnNdefPushCompleteCallback { NfcAdapter mNfcAdapter; TextView mInfoText; private static final int MESSAGE_SENT = 1; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_nfc); mInfoText = (TextView) findViewById(R.id.textView); // Check for available NFC Adapter mNfcAdapter = NfcAdapter.getDefaultAdapter(this); if (mNfcAdapter == null) { mInfoText = (TextView) findViewById(R.id.textView); mInfoText.setText("NFC is not available on this device."); } else { // Register callback to set NDEF message mNfcAdapter.setNdefPushMessageCallback(this, this); // Register callback to listen for message-sent success mNfcAdapter.setOnNdefPushCompleteCallback(this, this); } } /** * Implementation for the CreateNdefMessageCallback interface */ @Override public NdefMessage createNdefMessage(NfcEvent event) { // Get Networkdata DatabaseHandler dbh = new DatabaseHandler(this); ArrayList> localNetworkInformation = dbh.getNetworkInformation(); Log.i("NFC", "Creating Message"); NdefMessage msg = null; try { msg = new NdefMessage(NdefRecord.createMime( "application/de.tudarmstadt.informatik.hostage", serialize(localNetworkInformation)) /** * The Android Application Record (AAR) is commented out. When a device * receives a push with an AAR in it, the application specified in the AAR * is guaranteed to run. The AAR overrides the tag dispatch system. * You can add it back in to guarantee that this * activity starts when receiving a beamed message. For now, this code * uses the tag dispatch system. */ //,NdefRecord.createApplicationRecord("com.example.android.beam") ); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return msg; } /** * Implementation for the OnNdefPushCompleteCallback interface */ @Override public void onNdefPushComplete(NfcEvent arg0) { // A handler is needed to send messages to the activity when this // callback occurs, because it happens from a binder thread mHandler.obtainMessage(MESSAGE_SENT).sendToTarget(); } /** This handler receives a message from onNdefPushComplete */ private final Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case MESSAGE_SENT: Toast.makeText(getApplicationContext(), "Message sent!", Toast.LENGTH_LONG).show(); Log.i("NFC", "Message sent!"); break; } } }; @Override public void onResume() { super.onResume(); // Check to see that the Activity started due to an Android Beam if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) { processIntent(getIntent()); } } @Override public void onNewIntent(Intent intent) { // onResume gets called after this to handle the intent setIntent(intent); } /** * Parses the NDEF Message from the intent and prints to the TextView */ void processIntent(Intent intent) { Parcelable[] rawMsgs = intent.getParcelableArrayExtra( NfcAdapter.EXTRA_NDEF_MESSAGES); // only one message sent during the beam NdefMessage msg = (NdefMessage) rawMsgs[0]; // record 0 contains the MIME type, record 1 is the AAR, if present Object object; Log.i("NFC", "Getting Message!"); try { object = deserialize(msg.getRecords()[0].getPayload()); ArrayList> remoteNetworkInformation = (ArrayList>) object; DatabaseHandler dbh = new DatabaseHandler(this); dbh.updateNetworkInformation(remoteNetworkInformation); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } //HELPER public static byte[] serialize(Object obj) throws IOException { ByteArrayOutputStream out = new ByteArrayOutputStream(); ObjectOutputStream os = new ObjectOutputStream(out); os.writeObject(obj); return out.toByteArray(); } public static Object deserialize(byte[] data) throws IOException, ClassNotFoundException { ByteArrayInputStream in = new ByteArrayInputStream(data); ObjectInputStream is = new ObjectInputStream(in); return is.readObject(); } }