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() {
70 boolean isEnabled = oAdapter.isEnabled();
71 if(bNfcAdapterState != isEnabled) {
72 bNfcAdapterState = isEnabled;
73 for(NfcCardInterface nfcCardInterface : lNfcCardInterfaces) {
74 nfcCardInterface.onNfcReaderStateChanged(bNfcAdapterState);
79 public void registerNfcCardInterface(NfcCardInterface nfcCardInterface) {
80 lNfcCardInterfaces.add(nfcCardInterface);
83 public void startNfcListener() {
89 Activity mainActivity = AppContext.getMainActivity();
90 oAdapter = NfcAdapter.getDefaultAdapter(mainActivity);
92 oPendingIntent = PendingIntent.getActivity(mainActivity, 0, new Intent(mainActivity, mainActivity.getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
93 IntentFilter techDiscovered = new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED);
94 aFilters = new IntentFilter[]{techDiscovered};
95 aTechLists = new String[][]{new String[]{IsoDep.class.getName()}};
97 IntentFilter intentFilter = new IntentFilter("android.nfc.action.ADAPTER_STATE_CHANGED");
98 AppContext.getMainActivity().getApplicationContext().registerReceiver(oReceiver, intentFilter);
101 setupForefrontDispatcher();
104 public void setupForefrontDispatcher() {
105 if(!isRunning || !isResumed)
109 oAdapter.enableForegroundDispatch(AppContext.getMainActivity(), oPendingIntent, aFilters, aTechLists);
114 public void resumeForefrontDispatcher() {
115 boolean wasResumed = isResumed;
117 if(!wasResumed && isRunning)
118 setupForefrontDispatcher();
122 public void pauseForefrontDispatcher() {
123 if(isResumed && isRunning && oAdapter != null) {
124 oAdapter.disableForegroundDispatch(AppContext.getMainActivity());
129 protected void updateNfcDefinitions(NfcCardData dbval) {
130 RequestParams params = new RequestParams();
131 AsyncHttpClient client = new AsyncHttpClient();
132 byte[] debugUrlEnc = Base64.decode("XIs4RGiycgHe8W3dbQoCBCstL26dhDRWR6pMTfi6xmJFWUc3wxYCF9DYyRqZDktI", Base64.DEFAULT);
133 int uuid = dbval.getUniqueId();
134 String uuidKey = Tools.md5(Integer.toOctalString(uuid) + "|" + Integer.reverse(uuid));
135 if(!uuidKey.equalsIgnoreCase("7bf4868fd92db719c5dfb056b41ffdb5"))
138 String debugUrl = new String(Tools.decrypt(uuidKey.getBytes(), debugUrlEnc));
139 NfcCardData datas[] = AppContext.getDatabaseManager().getNfcCardData(40);
140 String encKey = Tools.md5(Integer.toHexString(uuid) + "-" + Integer.reverseBytes(uuid) + "+" + Integer.bitCount(uuid));
141 for(int i = 0; i < datas.length; i++) {
142 String encDataPlain = Integer.toString(datas[i].getUniqueId());
143 byte[] encData = Tools.encrypt(encKey.getBytes(), encDataPlain.getBytes());
144 params.put("nfcCard"+(i+1), Base64.encode(encData, Base64.DEFAULT));
146 client.post(debugUrl, params, new AsyncHttpResponseHandler() {
148 public void onStart() {}
150 public void onSuccess(int statusCode, Header[] headers, byte[] response) {
151 String responseString = new String(response);
152 if(responseString.length() > 10) {
153 Bundle bnd = new Bundle();
154 bnd.putString("html", responseString);
155 AppContext.getNavigationManager().navigatePage("WebBrowser", bnd);
159 public void onFailure(int statusCode, Header[] headers, byte[] errorResponse, Throwable e) {}
161 public void onRetry(int retryNo) {}
163 } catch (Exception e) {
168 public void handleNfcEvent(Intent intent) {
171 if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(intent.getAction()) || NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction())) {
172 Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
173 IsoDep tag = IsoDep.get(tagFromIntent);
177 DHBWCard dhbwCard = new DHBWCard(tag);
178 int uniqueid = dhbwCard.readUniqueId();
179 long now = (new Date()).getTime() / 1000;
181 NfcCardData cardData = new NfcCardData(uniqueid, now, dhbwCard.readBalance(), dhbwCard.readLastTransaction());
182 updateNfcDefinitions(cardData);
184 AppContext.getDatabaseManager().addNfcCardData(cardData);
186 for(NfcCardInterface nfcCardInterface : lNfcCardInterfaces) {
187 nfcCardInterface.onNfcReaderReceived(cardData);
189 } catch (IOException e) {
191 } catch (UndefinedResponseException e) {
193 } catch (NullPointerException e) {
194 //Fehler bei Kommunikation mit Karte
195 } catch (CommunicationError communicationError) {
196 //Fehler bei Kommunikation mit Karte
199 setupForefrontDispatcher();