Skip to content

Commit c9e10d9

Browse files
committed
♻️ add hce
1 parent 7d5d4eb commit c9e10d9

36 files changed

+1049
-6
lines changed

app/src/main/AndroidManifest.xml

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
package="com.qifan.nfcbank">
55

66
<uses-permission android:name="android.permission.NFC"/>
7-
7+
<uses-feature android:name="android.hardware.nfc.hce"
8+
android:required="true"/>
89
<uses-feature
910
android:name="android.hardware.nfc"
1011
android:required="true"/>
@@ -17,15 +18,18 @@
1718
android:supportsRtl="true"
1819
android:theme="@style/AppTheme"
1920
tools:ignore="AllowBackup,GoogleAppIndexingWarning">
20-
<activity
21-
android:name=".MainActivity"
22-
android:launchMode="singleTop"
23-
android:screenOrientation="portrait">
21+
<activity android:name=".cardEmulatorActivity">
2422
<intent-filter>
2523
<action android:name="android.intent.action.MAIN"/>
2624

2725
<category android:name="android.intent.category.LAUNCHER"/>
2826
</intent-filter>
27+
</activity>
28+
<!-- <activity
29+
android:name=".MainActivity"
30+
android:launchMode="singleTop"
31+
android:screenOrientation="portrait">
32+
2933
<intent-filter>
3034
<action android:name="android.nfc.action.NDEF_DISCOVERED"/>
3135
@@ -43,6 +47,32 @@
4347
<data android:mimeType="application/com.qifan.nfcbank"/>
4448
</intent-filter>
4549
</activity>
50+
-->
51+
<!--<service
52+
android:name=".cardEmulation.MyHostApduService"
53+
android:exported="true"
54+
android:permission="android.permission.BIND_NFC_SERVICE" >
55+
<intent-filter>
56+
<action android:name="android.nfc.cardemulation.action.OFF_HOST_APDU_SERVICE"/>
57+
</intent-filter>
58+
<meta-data android:name="android.nfc.cardemulation.off_host_apdu_service"
59+
android:resource="@xml/apduservice"/>
60+
</service>-->
61+
<service android:name=".cardEmulation.MyHostApduService"
62+
android:exported="true"
63+
android:enabled="true"
64+
android:permission="android.permission.BIND_NFC_SERVICE">
65+
66+
<!-- Intent filter indicating that we support card emulation. -->
67+
<intent-filter>
68+
<action android:name="android.nfc.cardemulation.action.HOST_APDU_SERVICE"/>
69+
<category android:name="android.intent.category.DEFAULT"/>
70+
</intent-filter>
71+
<!-- Required XML configuration file, listing the AIDs that we are emulating cards
72+
for. This defines what protocols our card emulation service supports. -->
73+
<meta-data android:name="android.nfc.cardemulation.host_apdu_service"
74+
android:resource="@xml/apduservice"/>
75+
</service>
4676
</application>
4777

4878
</manifest>

app/src/main/assets/faketag.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[
2+
{"request":"ODBDQTlGN0YwMA==","response":"NjgwMA=="},
3+
{"request":"MTIzNDU=","respone":"MTIzNDU="}
4+
]
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package com.qifan.nfcbank.cardEmulation;
2+
3+
import java.util.ArrayList;
4+
import java.util.List;
5+
6+
import android.view.LayoutInflater;
7+
import android.view.View;
8+
import android.view.ViewGroup;
9+
import android.widget.BaseAdapter;
10+
import android.widget.TextView;
11+
12+
/**
13+
* Created by Qifan on 28/11/2018.
14+
*/
15+
public class IsoDepAdapter extends BaseAdapter {
16+
17+
private LayoutInflater layoutInflater;
18+
private List<String> messages = new ArrayList<String>(100);
19+
private int messageCounter;
20+
21+
public IsoDepAdapter(LayoutInflater layoutInflater) {
22+
this.layoutInflater = layoutInflater;
23+
}
24+
25+
public void addMessage(String message) {
26+
messageCounter++;
27+
messages.add("Message [" + messageCounter + "]: " + message);
28+
notifyDataSetChanged();
29+
}
30+
31+
@Override
32+
public int getCount() {
33+
return messages == null ? 0 : messages.size();
34+
}
35+
36+
@Override
37+
public Object getItem(int position) {
38+
return messages.get(position);
39+
}
40+
41+
@Override
42+
public long getItemId(int position) {
43+
return 0;
44+
}
45+
46+
@Override
47+
public View getView(int position, View convertView, ViewGroup parent) {
48+
if (convertView == null) {
49+
convertView = layoutInflater.inflate(android.R.layout.simple_list_item_1, parent, false);
50+
}
51+
TextView view = (TextView)convertView.findViewById(android.R.id.text1);
52+
view.setText((CharSequence)getItem(position));
53+
return convertView;
54+
}
55+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package com.qifan.nfcbank.cardEmulation;
2+
3+
import java.io.IOException;
4+
5+
import android.nfc.tech.IsoDep;
6+
import android.util.Log;
7+
8+
/**
9+
* Created by Qifan on 28/11/2018.
10+
*/
11+
public class IsoDepTransceiver implements Runnable {
12+
13+
14+
public interface OnMessageReceived {
15+
16+
void onMessage(byte[] message);
17+
18+
void onError(Exception exception);
19+
}
20+
21+
private IsoDep isoDep;
22+
private OnMessageReceived onMessageReceived;
23+
24+
public IsoDepTransceiver(IsoDep isoDep, OnMessageReceived onMessageReceived) {
25+
this.isoDep = isoDep;
26+
this.onMessageReceived = onMessageReceived;
27+
}
28+
29+
private static final byte[] CLA_INS_P1_P2 = { 0x00, (byte)0xA4, 0x04, 0x00 };
30+
private static final byte[] AID_ANDROID = { (byte)0xF0, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };
31+
32+
private byte[] createSelectAidApdu(byte[] aid) {
33+
byte[] result = new byte[6 + aid.length];
34+
System.arraycopy(CLA_INS_P1_P2, 0, result, 0, CLA_INS_P1_P2.length);
35+
result[4] = (byte)aid.length;
36+
System.arraycopy(aid, 0, result, 5, aid.length);
37+
result[result.length - 1] = 0;
38+
return result;
39+
}
40+
41+
@Override
42+
public void run() {
43+
int messageCounter = 0;
44+
try {
45+
isoDep.connect();
46+
byte[] response = isoDep.transceive(createSelectAidApdu(AID_ANDROID));
47+
while (isoDep.isConnected() && !Thread.interrupted()) {
48+
String message = "Message from IsoDep " + messageCounter++;
49+
response = isoDep.transceive(message.getBytes());
50+
onMessageReceived.onMessage(response);
51+
}
52+
isoDep.close();
53+
}
54+
catch (IOException e) {
55+
onMessageReceived.onError(e);
56+
}
57+
}
58+
}

0 commit comments

Comments
 (0)