Using android nfc adaptor in android library - android

i wrote a sample code to sending APDU to contactless smartcard by phone nfc reader and it worked succesfully. Now i want to write a android library to perform some operations like verify PIN and etc. these functions must connect to contactless smartcard and send apdu to it and return the result. The problem is here :(
This is my sample code which works:
public class MainActivity extends Activity {
private NfcAdapter mAdapter = null;
static IsoDep myTag;
private TextView lblStatus;
private Button btnSelectApplet;
private PendingIntent mPendingIntent;
boolean mFirstDetected=false;
boolean mShowAtr=false;
private String[][] mTechLists;
private IntentFilter[] mFilters;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lblStatus = (TextView) findViewById(R.id.lblStatus);
btnSelectApplet = (Button) findViewById(R.id.btnSelect);
btnSelectApplet.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
byte[] select = new byte[] {0x00, (byte)0xa4, 0x04, 0x00, 0x09, (byte)0xa0, 0x00,
0x00, 0x03, 0x08, 0x00, 0x00, 0x10, 0x00, 0x1a};
byte[] res = transceives(select);
}
});
resolveIntent(getIntent());
mAdapter = NfcAdapter.getDefaultAdapter(this);
mPendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
IntentFilter ndef = new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED);
try
{
ndef.addDataType("*/*");
}
catch (IntentFilter.MalformedMimeTypeException e)
{
throw new RuntimeException("fail", e);
}
mFilters = new IntentFilter[] { ndef, };
mTechLists = new String[][] { new String[] { IsoDep.class.getName() } };
}
private static byte[] transceives (byte[] data)
{
byte[] ra = null;
try
{
ra = myTag.transceive(data);
}
catch (IOException e)
{
}
try
{
}
catch (Exception e1)
{
e1.printStackTrace();
}
return (ra);
}
private void resolveIntent(Intent intent)
{
String action = intent.getAction();
if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(action) || NfcAdapter.ACTION_TECH_DISCOVERED.equals(action) || NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) {
Parcelable tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
final Tag t = (Tag) tag;
myTag = IsoDep.get(t);
mFirstDetected = true;
if (myTag != null) {
if (!myTag.isConnected()) {
try {
myTag.connect();
myTag.setTimeout(5000);
} catch (IOException e) {
e.printStackTrace();
return;
}
}
if (myTag.isConnected()) {
String szATR = null;
try {
mShowAtr = true;
szATR = " 3B " + getATRLeString(myTag.getHistoricalBytes()) + "80 01 " + getHexString(myTag.getHistoricalBytes()) + "" + getATRXorString(myTag.getHistoricalBytes());
} catch (Exception e) {
mShowAtr = false;
szATR = "CARD DETECTED ";
}
lblStatus.setText(szATR);
} else {
lblStatus.setText("Not Connected!");
}
if (mFirstDetected == true && myTag.isConnected()) {
} else {
lblStatus.setText("Not Connected!");
}
}
}
}
private static String getATRLeString(byte[] data) throws Exception
{
return String.format("%02X ", data.length | 0x80);
}
private static String getATRXorString(byte[] b) throws Exception
{
int Lrc=0x00;
Lrc = b.length | 0x80;
Lrc = Lrc^0x81;
for (int i=0; i < b.length; i++)
{
Lrc = Lrc^(b[i] & 0xFF);
}
return String.format("%02X ", Lrc);
}
private static String getHexString(byte[] data) throws Exception
{
String szDataStr = "";
for (int ii=0; ii < data.length; ii++)
{
szDataStr += String.format("%02X ", data[ii] & 0xFF);
}
return szDataStr;
}
#Override
protected void onNewIntent(Intent intent)
{
setIntent(intent);
resolveIntent(intent);
}
#Override
public void onResume()
{
super.onResume();
if (mAdapter != null)
{
mAdapter.enableForegroundDispatch(this, mPendingIntent, mFilters, mTechLists);
}
}
}
Sample code used enableForegroundDispatch function to detect smartcard in NFC field. When smartcard detected, onNewIntent is called.
I want put all of the code in android library module X and use it in Activity Y like
Activity Y extend X
or
X x = new X()
and call it functions. how could i implement it?
I have a problem when i want to call
mAdapter = NfcAdapter.getDefaultAdapter(this);
if i use this code:
mAdapter = NfcAdapter.getDefaultAdapter(context);// context pass from Y Activity to X(Android library)
the function
mAdapter.enableForegroundDispatch(this , mPendingIntent, mFilters, mTechLists); // In X (Android library)
doesn't work correctly because it doesn't use Y activity (it used X axtivity).
How can i solve my problem such way all code will be in X(android library)?
Thanks.

as per my understanding, you are trying to access some of the methods from other activity,
here I suggest you to create third class for that NFC module methods,
create singleton method that returns a static instance of that model class.
you can access that instance from any of your Activity.
you also can set a callback in a class and another method call from another class of activity.
Hope this will help you. ask if anything not clear.
Happy Coding :)

Related

AndroidThings UsbToUart cannot Rx data when run long times [close]

Hello I use android thing on raspberry pi 3, I have a problem my app use UsbToSerial and then my app can Tx but cannot Rx data when app run longtime but in first period of work my app can Rx data and app can Tx alway times
How can I fix the problem?
And this is my code
MainActivity.java
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
UartService uart_api = new UartService();
uart_api.UartInit("USB1-1.2:1.0", 9600);
}
UartService.java
public class UartService extends Activity {
private static final String TAG = "LoopbackActivity";
// UART Configuration Parameters
private static final int DATA_BITS = 8;
private static final int STOP_BITS = 1;
private static final int CHUNK_SIZE = 512;
private UartDevice mLoopbackDevice;
private void openUart(String name, int baudRate) throws IOException {
mLoopbackDevice = PeripheralManager.getInstance().openUartDevice(name);
// Configure the UART
mLoopbackDevice.setBaudrate(baudRate);
mLoopbackDevice.setDataSize(DATA_BITS);
mLoopbackDevice.setParity(UartDevice.PARITY_NONE);
mLoopbackDevice.setStopBits(STOP_BITS);
}
public void UartInit(String UartName, int baudrate){
PeripheralManager manager = PeripheralManager.getInstance();
List<String> deviceList = manager.getUartDeviceList();
if (deviceList.isEmpty()) {
Log.i(TAG, "No UART port available on this device.");
} else {
Log.i(TAG, "List of available devices: " + deviceList);
}
// Attempt to access the UART device
try {
openUart(UartName, baudrate);
// Read any initially buffered data
Thread thread_read = new Thread(new ThreadUart(123));
thread_read.start();
} catch (IOException e) {
Log.e(TAG, "Unable to open UART device", e);
}
}
public class ThreadUart implements Runnable {
private int data_in;
public ThreadUart(int in) {
this.data_in = in;
}
#Override
public void run() {
while(true){
///////// Test Rx //////
if (mLoopbackDevice != null) {
// Loop until there is no more data in the RX buffer.
try {
byte[] buffer = new byte[CHUNK_SIZE];
int read;
while ((read = mLoopbackDevice.read(buffer, buffer.length)) > 0) { // <<<< when run long time this cannot Rx data
mLoopbackDevice.write(buffer, read);
}
} catch (IOException e) {
Log.w(TAG, "Unable to transfer data over UART", e);
}
}
// sleep 1 sec.
///////// Test Tx //////
String string = "Hello\r\n";
byte[] b = string.getBytes(StandardCharsets.UTF_8);
try {
mLoopbackDevice.write(b, b.length); // <<<< can Tx work!! always time
} catch (IOException e) {
e.printStackTrace();
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
finarly I follow Example example, It work !! in example use felHR85’s USBSerial library
however I don't know cause of Rx lost when use UART API and then run long time

Use NFC enabled android smartphone as NFC tag and receive it data using nfc reader

I am new to NFC i want to NFC enabled android phone as NFC tag and read its data using NFC reader . It would be really great if you could suggest me the already build NFC apps for sending data or which NFC reader hardware should i go with.
this is my NFC sending and Receiving code.
MainActivity sends files
public class MainActivity extends AppCompatActivity {
NfcAdapter nfcAdapter;
private PendingIntent mPendingIntent;
private IntentFilter[] mIntentFilters;
private String[][] mNFCTechLists;
private TextView mTextView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
nfcAdapter = NfcAdapter.getDefaultAdapter(this);
mTextView = (TextView)findViewById(R.id.recive_text);
PackageManager pm = this.getPackageManager();
// Check whether NFC is available on device
if (!pm.hasSystemFeature(PackageManager.FEATURE_NFC)) {
// NFC is not available on the device.
Toast.makeText(this, "The device does not has NFC hardware.",
Toast.LENGTH_SHORT).show();
}
// Check whether device is running Android 4.1 or higher
else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
// Android Beam feature is not supported.
Toast.makeText(this, "Android Beam is not supported.",
Toast.LENGTH_SHORT).show();
}
else {
// NFC and Android Beam file transfer is supported.
Toast.makeText(this, "Android Beam is supported on your device.",
Toast.LENGTH_SHORT).show();
}
// create an intent with tag data and deliver to this activity
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());
}
mNFCTechLists = new String[][] { new String[] { NfcF.class.getName() } };
}
public void sendFile(View view) {
// Check whether NFC is enabled on device
if(!nfcAdapter.isEnabled()){
// NFC is disabled, show the settings UI
// to enable NFC
Toast.makeText(this, "Please enable NFC.",
Toast.LENGTH_SHORT).show();
startActivity(new Intent(Settings.ACTION_NFC_SETTINGS));
}
// Check whether Android Beam feature is enabled on device
else if(!nfcAdapter.isNdefPushEnabled()) {
// Android Beam is disabled, show the settings UI
// to enable Android Beam
Toast.makeText(this, "Please enable Android Beam.",
Toast.LENGTH_SHORT).show();
startActivity(new Intent(Settings.ACTION_NFCSHARING_SETTINGS));
}
else {
Intent chooseFile = new Intent(Intent.ACTION_GET_CONTENT);
chooseFile.setType("*/*");
chooseFile = Intent.createChooser(chooseFile, "Choose a file");
startActivityForResult(chooseFile, 1);
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (data!=null) {
Uri uri = data.getData();
nfcAdapter.setBeamPushUris(new Uri[]{uri}, this);
} else {
Toast.makeText(this,"Please choose a file",Toast.LENGTH_SHORT).show();
}
}
public void nextScreen(View view){
startActivity(new Intent(MainActivity.this,SecondActivity.class));
}
public void reciveScreen(View view){
startActivity(new Intent(MainActivity.this,RecieveScreen.class));
}
#Override
public void onNewIntent(Intent intent) {
String action = intent.getAction();
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
String s = action + "\n\n" + tag.toString();
// parse through all NDEF messages and their records and pick text type only
Parcelable[] data = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
if (data != null) {
try {
for (int i = 0; i < data.length; i++) {
NdefRecord[] recs = ((NdefMessage)data[i]).getRecords();
for (int j = 0; j < recs.length; j++) {
if (recs[j].getTnf() == NdefRecord.TNF_WELL_KNOWN &&
Arrays.equals(recs[j].getType(), NdefRecord.RTD_TEXT)) {
byte[] payload = recs[j].getPayload();
String textEncoding = ((payload[0] & 0200) == 0) ? "UTF-8" : "UTF-16";
int langCodeLen = payload[0] & 0077;
s += ("\n\nNdefMessage[" + i + "], NdefRecord[" + j + "]:\n\"" +
new String(payload, langCodeLen + 1,
payload.length - langCodeLen - 1, textEncoding) +
"\"");
}
}
}
} catch (Exception e) {
Log.e("TagDispatch", e.toString());
}
}
mTextView.setText(s);
}
#Override
public void onResume() {
super.onResume();
if (nfcAdapter != null)
nfcAdapter.enableForegroundDispatch(this, mPendingIntent, mIntentFilters, mNFCTechLists);
}
#Override
public void onPause() {
super.onPause();
if (nfcAdapter != null)
nfcAdapter.disableForegroundDispatch(this);
}
}
This is my receiving screen, there may be some extra code but you can remove it
public class RecieveScreen extends AppCompatActivity {
private TextView mTextView;
private NfcAdapter mNfcAdapter;
private PendingIntent mPendingIntent;
private IntentFilter[] mIntentFilters;
private String[][] mNFCTechLists;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recieve_screen);
mTextView = (TextView)findViewById(R.id.recieve_tv);
mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
if (mNfcAdapter != null) {
mTextView.setText("Read an NFC tag");
} else {
mTextView.setText("This phone is not NFC enabled.");
}
// create an intent with tag data and deliver to this activity
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());
}
mNFCTechLists = new String[][] { new String[] { NfcF.class.getName() } };
}
#Override
public void onNewIntent(Intent intent) {
String action = intent.getAction();
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
String s = action + "\n\n" + tag.toString();
// parse through all NDEF messages and their records and pick text type only
Parcelable[] data = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
if (data != null) {
try {
for (int i = 0; i < data.length; i++) {
NdefRecord[] recs = ((NdefMessage)data[i]).getRecords();
for (int j = 0; j < recs.length; j++) {
if (recs[j].getTnf() == NdefRecord.TNF_WELL_KNOWN &&
Arrays.equals(recs[j].getType(), NdefRecord.RTD_TEXT)) {
byte[] payload = recs[j].getPayload();
String textEncoding = ((payload[0] & 0200) == 0) ? "UTF-8" : "UTF-16";
int langCodeLen = payload[0] & 0077;
s += ("\n\nNdefMessage[" + i + "], NdefRecord[" + j + "]:\n\"" +
new String(payload, langCodeLen + 1,
payload.length - langCodeLen - 1, textEncoding) +
"\"");
}
}
}
} catch (Exception e) {
Log.e("TagDispatch", e.toString());
}
}
mTextView.setText(s);
}
#Override
public void onResume() {
super.onResume();
if (mNfcAdapter != null)
mNfcAdapter.enableForegroundDispatch(this, mPendingIntent, mIntentFilters, mNFCTechLists);
}
#Override
public void onPause() {
super.onPause();
if (mNfcAdapter != null)
mNfcAdapter.disableForegroundDispatch(this);
}
}
Let me know if you face any errors.
Yes. You can use Android NFC Host-based card emulation(HCE).
https://developer.android.com/guide/topics/connectivity/nfc/hce
You can use your own HostApduService.
But NFC reader should send APDU command to select your application ID(AID) at the first time.
APDUs are defined in the ISO/IEC 7816-4 specification as well.
As mentioned previously, Android uses the AID to determine which HCE
service the reader wants to talk to. Typically, the first APDU an NFC
reader sends to your device is a "SELECT AID" APDU; this APDU contains
the AID that the reader wants to talk to. Android extracts that AID
from the APDU, resolves it to an HCE service, then forwards that APDU
to the resolved service.
I am using ACR 122 NFC reader, I can use Android device as NFC card.
Please refer this git repo.
https://github.com/darryldecode/card-emulation
Thanks.

How to communicate with card (Iso 14443 Type B, Tech: IsoDep & NfcB) with all mobiles support NFC

I'm making android app to communicated Ezlink card (Iso 14443 Type B, Tech: IsoDep & NfcB).
My problems are the app cannot get purse data(card no, balance), always got 6A82 after call isoDep.transceive(). I tested some devices with HTC One X (OS 4.2.2) it work successful, but Samsung S3 (OS 4.1.2) and some devices (OS 4.4.2) like Samsung s4, s5... they alway got 6A82.
public class NFCActivity extends Activity {
private NfcAdapter mNfcAdapter;
private QRCode qrCode;
private WebserviceConnection wsConnection;
private ConnectionDetector cd;
private boolean detectCard;
private SharedPreferences sharedpreferences;
private ProgressDialog dialog;
private TextView error_content;
private TextView error;
private IsoDepReaderTask isoDepReaderTask;
PendingIntent pendingIntent;
IntentFilter[] filters;
String[][] techList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tabcard);
Log.d("onCreate() NFCActivity","123456");
qrCode = new QRCode();
isoDepReaderTask = new IsoDepReaderTask(this);
wsConnection = new WebserviceConnection(this);
cd = new ConnectionDetector(this);
sharedpreferences = getSharedPreferences("MyPref", Context.MODE_PRIVATE);
error = (TextView) findViewById(R.id.error);
error_content = (TextView) findViewById(R.id.error_content);
pendingIntent = PendingIntent.getActivity(
this, 0, new Intent(this, getClass()).setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
filters = new IntentFilter[] { new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED) };
techList = new String[][] {new String[] { IsoDep.class.getName() } };
mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
// get the Intent that started this Activity
Intent in = getIntent();
// get the Bundle that stores the data of this Activity
Bundle b = in.getExtras();
// getting data from bundle
String contents = b.getString("Contents");
if(contents != null) {
qrCode.getQRCodeDetail(contents);
}
handleIntent(in);
}
#Override
protected void onResume() {
super.onResume();
cd.ensureSensorIsOn();
mNfcAdapter.enableForegroundDispatch(this, pendingIntent, filters, techList);
isoDepReaderTask.countDownTimeConnectToCard();
}
#Override
protected void onPause() {
mNfcAdapter.disableForegroundDispatch(this);
super.onPause();
}
#Override
protected void onNewIntent(Intent intent) {
handleIntent(intent);
}
private void handleIntent(Intent intent) {
String action = intent.getAction();
if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)) {
dialog = ProgressDialog.show(NFCActivity.this, "Please hold on to your card", "Scanning...", true);
detectCard = true;
// In case we would still use the Tech Discovered Intent
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
// new IsoDepReaderTask().execute(tag);
isoDepReaderTask = new IsoDepReaderTask(this, sharedpreferences, qrCode, dialog);
isoDepReaderTask.execute(tag);
//Log.d(" STEP1 NFC not connected", ""+ IsoDepReaderTask.isoDep.isConnected());
}
}
// if within 1 minute that device cannot communicate with card then showing a Toast
private void countDownTimeConnectToCard() {
final Toast toast = Toast.makeText(this, R.string.error_detect, Toast.LENGTH_LONG);
new CountDownTimer(60000, 15000) {
public void onTick(long millisUntilFinished) {
Log.d("detectCard", String.valueOf(detectCard));
if(!detectCard && millisUntilFinished < 50000) {
toast.show();
}
}
public void onFinish() {
if(!detectCard) {
error.setVisibility(View.VISIBLE);
error_content.setText(R.string.no_card_detected);
}
}
}.start();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
I always got 6A82 after call isoDep.transceive(purseByte) with some devices that I mention above.
//IsoDepReaderTask class
IsoDep isoDep = IsoDep.get(tag);
if (isoDep != null) {
try {
if (!isoDep.isConnected()) {
isoDep.connect();
}
isoDep.setTimeout(5000);
byte[] getChallengeByte = { (byte) 0x00, (byte) 0x84,
(byte) 0x00, (byte) 0x00, (byte) 0x08 };
byte[] challengeResult = isoDep.transceive(getChallengeByte);
String purseString = "903203000A1403CF549C2B7520389C");
byte[] purseByte = common.hexStringToByteArray(purseString.toString());
byte[] purseResult = isoDep.transceive(purseByte);
String purseData = common.hexString(purseResult);
Anyone has experience about my problem can help me. Thanks a lot.
PS: I can communicate with card using some android mobiles with OS 4.4.2 if I using EnableReaderMode, but when implements ReaderCallback, the app only work with API 19. I'd like my app work with every mobile can support NFC

NFC tag(for NfcA) scan works only from the second time

I wrote a custom plugin to read blocks of data from an NfcA(i.e.non-ndef) tag. It seems to work fine , but only after the second scan. I am using Activity intent to derive the "NfcAdapter.EXTRA_TAG" to later use it for reading the values. I am also updating the Intents in onNewIntent(). OnNewIntent gets called after the second scan and after that I get result all the time.But in the first scan onNewIntent does not gets called, hence I end up using the Activity tag that does not have "NfcAdapter.EXTRA_TAG", hence I get null. Please see the my code below.
SE_NfcA.java(my native code for plugin)
#Override
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
String Result = "";
String TypeOfTalking = "";
if (action.contains("TalkToNFC"))
{
JSONObject arg_object = args.getJSONObject(0);
TypeOfTalking = arg_object.getString("type");
if(TypeOfTalking != "")
{
if (TypeOfTalking.contains("readBlock"))
{
if(TypeOfTalking.contains("#"))
{
try
{
String[] parts = TypeOfTalking.split("#");
int index = Integer.parseInt(parts[1]);
Result = Readblock(cordova.getActivity().getIntent(),(byte)index);
callbackContext.success(Result);
}
catch(Exception e)
{
callbackContext.error("Exception Reading "+ TypeOfTalking + "due to "+ e.toString());
return false;
}
}
}
else
{
return false;
}
}
else
{
return false;
}
}
else
{
return false;
}
return true;
}
#Override
public void onNewIntent(Intent intent) {
ShowAlert("onNewIntent called");
Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
super.onNewIntent(intent);
getActivity().setIntent(intent);
savedTag = tagFromIntent;
savedIntent = intent;
}
#Override
public void onPause(boolean multitasking) {
Log.d(TAG, "onPause " + getActivity().getIntent());
super.onPause(multitasking);
if (multitasking) {
// nfc can't run in background
stopNfc();
}
}
#Override
public void onResume(boolean multitasking) {
Log.d(TAG, "onResume " + getActivity().getIntent());
super.onResume(multitasking);
startNfc();
}
public String Readblock(Intent Intent,byte block) throws IOException{
byte[] response = new byte[]{};
if(Intent != null)
{
Tag myTag = Intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
if(savedTag != null)
myTag = savedTag;
if(myTag != null)
{
try{
Reader nTagReader = new Reader(myTag);
nTagReader.close();
nTagReader.connect();
nTagReader.SectorSelect(Sector.Sector0);
response = nTagReader.fast_read(block, block);
nTagReader.close();
return ConvertH(response);
}catch(Exception e){
ShowAlert(e.toString());
}
}
else
ShowAlert("myTag is null.");
}
return null;
}
private void createPendingIntent() {
if (pendingIntent == null) {
Activity activity = getActivity();
Intent intent = new Intent(activity, activity.getClass());
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP| Intent.FLAG_ACTIVITY_CLEAR_TOP);
pendingIntent = PendingIntent.getActivity(activity, 0, intent, 0);
}
}
private void startNfc() {
createPendingIntent(); // onResume can call startNfc before execute
getActivity().runOnUiThread(new Runnable() {
public void run() {
NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(getActivity());
if (nfcAdapter != null && !getActivity().isFinishing()) {
try {
nfcAdapter.enableForegroundDispatch(getActivity(), getPendingIntent(), getIntentFilters(), getTechLists());
if (p2pMessage != null) {
nfcAdapter.setNdefPushMessage(p2pMessage, getActivity());
}
} catch (IllegalStateException e) {
// issue 110 - user exits app with home button while nfc is initializing
Log.w(TAG, "Illegal State Exception starting NFC. Assuming application is terminating.");
}
}
}
});
}
private void stopNfc() {
Log.d(TAG, "stopNfc");
getActivity().runOnUiThread(new Runnable() {
public void run() {
NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(getActivity());
if (nfcAdapter != null) {
try {
nfcAdapter.disableForegroundDispatch(getActivity());
} catch (IllegalStateException e) {
// issue 125 - user exits app with back button while nfc
Log.w(TAG, "Illegal State Exception stopping NFC. Assuming application is terminating.");
}
}
}
});
}
private Activity getActivity() {
return this.cordova.getActivity();
}
private PendingIntent getPendingIntent() {
return pendingIntent;
}
private IntentFilter[] getIntentFilters() {
return intentFilters.toArray(new IntentFilter[intentFilters.size()]);
}
private String[][] getTechLists() {
//noinspection ToArrayCallWithZeroLengthArrayArgument
return techLists.toArray(new String[0][0]);
}
}
My index.js file
nfc.addTagDiscoveredListener(
function(nfcEvent){
console.log(nfcEvent.tag.id);
alert(nfcEvent.tag.id);
window.echo("readBlock#88");//call to plugin
},
function() {
alert("Listening for NFC tags.");
},
function() {
alert("NFC activation failed.");
}
);
SE_NfcA.js(plugin interface for interaction b/w index.js and SE_NfcA.java)
window.echo = function(natureOfTalk)
{
alert("Inside JS Interface, arg =" + natureOfTalk);
cordova.exec(function(result){alert("Result is : "+result);},
function(error){alert("Some Error happened : "+ error);},
"SE_NfcA","TalkToNFC",[{"type": natureOfTalk}]);
};
I guess I have messed up with the Intents/Activity Life-Cycle, please help. TIA!
I found a tweak/hack and made it to work.
Before making any call to read or write, I made one dummy Initialize call.
window.echo("Initialize");
window.echo("readBlock#88");//call to plugin to read.
And in the native code of the plugin, on receiving the "Initialize" token I made a startNFC() call.
else if(TypeOfTalking.equalsIgnoreCase("Initialize"))
{
startNfc();
}

FTDI Android - create new activity

This code is able to make the android device as a USB host for the hardware model. It also can read data from the hardware correctly in Main Activity. However, as soon as I moved it to another activity, everything still works but the data reading is incorrect.
For instance, I'm trying to write the data read into file. First activity is to input filename and just a button to send to another activity. The code below is in the second activity
public class Temp extends Activity {
private FileOutputStream outputStream;
public static D2xxManager ftD2xx= null;
Handler mHandler = new Handler();
FT_Device ftDev = null;
int devCount = 0;
UsbDevice device = null;
TextView Text =null;
String temp = null;
_4DPoint P = null;
int rd = 0;
byte[] byt = null;
byte[] Fdata = null;
String outp = "";
String From_Serial = "";
int Min = -1;
String fileName;
Context c;
final Runnable updateResults = new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
Text.setText("" + Min + '\n' + temp);
}
};
public void getData(){
try {
outputStream = openFileOutput(fileName, Context.MODE_PRIVATE);
byt = new byte[256];//{(byte)'a','b','c','d',};
Toast.makeText(getBaseContext(), "start " + fileName , Toast.LENGTH_LONG).show();
Text = (TextView)findViewById(R.id.test2);
device = (UsbDevice) getIntent().getParcelableExtra("USB");
ftD2xx = D2xxManager.getInstance(c);
ftD2xx.addUsbDevice(device);
devCount = ftD2xx.createDeviceInfoList(c);
if (devCount > 0) {
ftDev = ftD2xx.openByUsbDevice(c, device);
}
if( ftDev.isOpen() == true ) {
ftDev.setBitMode((byte)0 , D2xxManager.FT_BITMODE_RESET);
ftDev.setBaudRate(38400);
ftDev.setDataCharacteristics(D2xxManager.FT_DATA_BITS_8, D2xxManager.FT_STOP_BITS_1, D2xxManager.FT_PARITY_NONE);
ftDev.setFlowControl(D2xxManager.FT_FLOW_NONE, (byte) 0x0b, (byte) 0x0d);
Thread t = new Thread() {
public void run() {
int i;
while(true){
rd=0;
while (rd==0){
rd = ftDev.read(byt, 14);
}
for(i=0; i<rd; i++)
outp += (char)byt[i];
From_Serial = new String(outp);
P = new _4DPoint(From_Serial);
temp = String.format("%s: %f %f %f %f %d\n", From_Serial, P.R, P.G, P.B, P.L, P.camera);
try {
outputStream.write(temp.getBytes());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
outp = "";
mHandler.post(updateResults);
}
}
};
t.start();
}
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (D2xxException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_color);
// Show the Up button in the action bar.
setupActionBar();
Intent intent = getIntent();
fileName = intent.getStringExtra("File Name");
c = this;
getData();
}
The set up should be fine since it's reading data from hardware, but the data read is incorrect.
Also, I'm wondering why we need to create new thread while reading data. I tried not creating new thread and it didn't work well, but still have no idea why? I tried to contact the person who wrote the code to read data but no reply.
Any help would be really appreciated :)
You state that you receive data, therefor I think you should look at your ftDev settings. Try for example to set ftDev.setBaudRate(115200) (this worked for me) or try playing with your other ftDev Settings a little bit.
The settings I use in my programm are:
int baudRate = 115200;
byte stopBit = 1; /*1:1stop bits, 2:2 stop bits*/
byte dataBit = 8; /*8:8bit, 7: 7bit*/
byte parity = 0; /* 0: none, 1: odd, 2: even, 3: mark, 4: space*/
byte flowControl = 1; /*0:none, 1: flow control(CTS,RTS)*/
If this won't work, it is wise to first check this data communication with a computer program e.g. or to analyse the incomming 'wrong' data.

Categories

Resources