123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213 |
- /*
- * 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.nfc;
- 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 java.util.Iterator;
- 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 de.tudarmstadt.informatik.hostage.R;
- import de.tudarmstadt.informatik.hostage.logging.NetworkRecord;
- import de.tudarmstadt.informatik.hostage.logging.SyncInfoRecord;
- import de.tudarmstadt.informatik.hostage.persistence.HostageDBOpenHelper;
- import de.tudarmstadt.informatik.hostage.sync.tracing.TracingSyncService;
- @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
- public class NFCSync extends Activity implements CreateNdefMessageCallback, OnNdefPushCompleteCallback {
- NfcAdapter mNfcAdapter;
- TextView mInfoText;
- private static final int MESSAGE_SENT = 0x1;
- private static final int SYNC_SUCCESSFUL = 0x2;
- private final Handler mHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case MESSAGE_SENT:
- mInfoText.setText("Synchronization data sent, wait for data.");
- Log.i("NFC", "Message sent!");
- break;
- case SYNC_SUCCESSFUL:
- mInfoText.setText("Synchronization successfull!");
- Log.i("NFC", "Message sent!");
- break;
- }
- }
- };
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_nfc);
- mInfoText = (TextView) findViewById(R.id.nfc_text_view);
- // Check for available NFC Adapter
- mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
- if (mNfcAdapter == null) {
- mInfoText.setText("NFC is not available on this device.");
- } else if(!mNfcAdapter.isEnabled()){
- mInfoText.setText("Enable Android Beam before synchronizing.");
- } else {
- mInfoText.setText("Hold phones together to synchronize.");
- // 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
- HostageDBOpenHelper dbh = new HostageDBOpenHelper(this);
- ArrayList<NetworkRecord> localNetworkInformation = dbh.getNetworkInformation();
- HashMap<String, Long> devices_local = dbh.getSyncDevices();
- ArrayList<SyncInfoRecord> syncInfo = dbh.getSyncInfo();
-
- Log.i("NFC", "Creating Message");
- NdefMessage msg = null;
- try {
- NdefRecord netData = NdefRecord.createMime("application/de.tudarmstadt.informatik.hostage", serialize(localNetworkInformation));
- NdefRecord deviceData = NdefRecord.createMime("application/de.tudarmstadt.informatik.hostage", serialize(devices_local));
- NdefRecord syncData = NdefRecord.createMime("application/de.tudarmstadt.informatik.hostage", serialize(syncInfo));
- msg = new NdefMessage(netData, deviceData, syncData);
-
- } catch (IOException e) {
- 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();
- }
- @Override
- public void onNewIntent(Intent intent) {
- // onResume gets called after this to handle the intent
- setIntent(intent);
- }
- // HELPER
- @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());
- }
- }
- /**
- * 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 netData;
- Object deviceData;
- Object syncData;
- Log.i("NFC", "Getting Message!");
- try {
- HostageDBOpenHelper dbh = new HostageDBOpenHelper(this);
- netData = deserialize(msg.getRecords()[0].getPayload());
- deviceData = deserialize(msg.getRecords()[1].getPayload());
- syncData = deserialize(msg.getRecords()[2].getPayload());
- ArrayList<NetworkRecord> remoteNetworkInformation = (ArrayList<NetworkRecord>) netData;
- HashMap<String, Long> devices_remote = (HashMap<String, Long>) deviceData;
- HashMap<String, Long> devices_local = dbh.getSyncDevices();
- ArrayList<SyncInfoRecord> syncInfo = (ArrayList<SyncInfoRecord>) syncData;
-
- long tracing_timestamp = 0;
- if(devices_local.containsKey(TracingSyncService.REMOTE_DEVICE))
- tracing_timestamp = devices_local.get(TracingSyncService.REMOTE_DEVICE);
-
- for(Iterator<String> i = devices_remote.keySet().iterator(); i.hasNext(); ){
- String key = i.next();
- if((devices_local.containsKey(key) && devices_local.get(key) >= devices_remote.get(key))
- || (tracing_timestamp > devices_remote.get(key))){
- i.remove();
- }
- }
-
- for ( Iterator<SyncInfoRecord> i = syncInfo.iterator(); i.hasNext(); ){
- SyncInfoRecord info = i.next();
- if(devices_remote.containsKey(info.getDeviceID())){
- i.remove();
- }
- }
-
- dbh.updateSyncDevices(devices_remote);
- dbh.updateSyncInfo(syncInfo);
- dbh.updateNetworkInformation(remoteNetworkInformation);
- mHandler.obtainMessage(SYNC_SUCCESSFUL).sendToTarget();
- } catch (ClassNotFoundException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
- private static Object deserialize(byte[] data) throws IOException, ClassNotFoundException {
- ByteArrayInputStream in = new ByteArrayInputStream(data);
- ObjectInputStream is = new ObjectInputStream(in);
- return is.readObject();
- }
- private static byte[] serialize(Object obj) throws IOException {
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- ObjectOutputStream os = new ObjectOutputStream(out);
- os.writeObject(obj);
- return out.toByteArray();
- }
- }
|