123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239 |
- /*
- * 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.app.PendingIntent;
- import android.content.Intent;
- import android.content.IntentFilter;
- 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.nfc.tech.NfcF;
- 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 NFCSyncActivity extends Activity implements CreateNdefMessageCallback, OnNdefPushCompleteCallback {
- NfcAdapter mNfcAdapter;
- TextView mInfoText;
- private static final int MESSAGE_SENT = 0x1;
- private static final int MESSAGE_RECEIVED = 0x3;
-
- private final Handler mHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case MESSAGE_SENT:
- runOnUiThread(new Runnable() {
- public void run() {
- Toast.makeText(NFCSyncActivity.this, "Data sent!", Toast.LENGTH_LONG).show();
- }
- });
- break;
- case MESSAGE_RECEIVED:
- runOnUiThread(new Runnable() {
- public void run() {
- Toast.makeText(NFCSyncActivity.this, "Data recieved!", Toast.LENGTH_LONG).show();
- }
- });
- 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 send or recieve data.");
- // 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();
-
- 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();
- IntentFilter[] mIntentFilters = null;
-
- PendingIntent mPendingIntent = PendingIntent.getActivity(this, 0,
- new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
-
- // set an intent filter for all MIME data
- IntentFilter ndefIntent = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
- try {
- ndefIntent.addDataType("*/*");
- mIntentFilters = new IntentFilter[] { ndefIntent };
- } catch (Exception e) {
- Log.e("TagDispatch", e.toString());
- }
-
- String[][] mNFCTechLists = new String[][] { new String[] { NfcF.class.getName() } };
-
- if (mNfcAdapter != null)
- mNfcAdapter.enableForegroundDispatch(this, mPendingIntent, mIntentFilters, mNFCTechLists);
-
- // 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 onPause() {
- super.onPause();
- mNfcAdapter.disableForegroundDispatch(this);
- }
- /**
- * 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];
- try {
- HostageDBOpenHelper dbh = new HostageDBOpenHelper(this);
- ArrayList<NetworkRecord> remoteNetworkInformation = (ArrayList<NetworkRecord>) deserialize(msg.getRecords()[0].getPayload());
- HashMap<String, Long> devices_remote = (HashMap<String, Long>) deserialize(msg.getRecords()[1].getPayload());
- HashMap<String, Long> devices_local = dbh.getSyncDevices();
- ArrayList<SyncInfoRecord> syncInfo = (ArrayList<SyncInfoRecord>) deserialize(msg.getRecords()[2].getPayload());
-
- 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(MESSAGE_RECEIVED).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();
- }
- }
|