diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 75a70e82..87dc49fe 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -27,6 +27,7 @@ tools:ignore="ProtectedPermissions" /> + @@ -57,6 +58,15 @@ tools:ignore="GoogleAppIndexingWarning"> + + + + + + + + + 0) + out.name("error").value(error); + out.name("nfcPresent").value(null != adapter); + if(null!=adapter) + out.name("nfcActive").value(adapter.isEnabled()); + out.endObject(); + } + }); + } + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + Intent intent = this.getIntent(); + if (intent != null) { + mode = intent.getStringExtra("mode"); + if (null == mode) + mode = "noData"; + param =intent.getStringExtra("param"); + if (null == param) + param = "noData"; + value=intent.getStringExtra("value"); + if (null == socket_input) socket_input = intent.getStringExtra("socket_input"); + if (null == socket_output) socket_output = intent.getStringExtra("socket_output"); + if (mode == "noData") { + errorNfc(this, intent,""); + finish(); + } + } + + NfcAdapter adapter = NfcAdapter.getDefaultAdapter(this); + if((null==adapter)||(!adapter.isEnabled())){ + errorNfc(this,intent,""); + finish(); + } + } + + @Override + protected void onResume() { + super.onResume(); + adapter = NfcAdapter.getDefaultAdapter(this); + Intent intentNew = new Intent(this, NfcActivity.class).addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); + PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intentNew, 0); + IntentFilter[] intentFilter = new IntentFilter[]{ + new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED), + new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED), + new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED)}; + adapter.enableForegroundDispatch(this, pendingIntent, intentFilter, null); + } + + @Override + protected void onNewIntent(Intent intent) { + intent.putExtra("socket_input", socket_input); + intent.putExtra("socket_output", socket_output); + + if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction())) { + try { + postResult(this, intent); + } + catch (Exception e) + { + Log.e("Termix-api.NfcAction",e.getMessage()); + } + finish(); + } + super.onNewIntent(intent); + } + + @Override + protected void onPause() { + adapter.disableForegroundDispatch(this); + super.onPause(); + } + + @Override + protected void onDestroy() { + socket_input = null; + socket_output = null; + super.onDestroy(); + } + + protected void postResult(final Context context, Intent intent) { + ResultReturner.returnData(context, intent, new ResultReturner.ResultJsonWriter() { + @Override + public void writeJson(JsonWriter out) throws Exception { + Log.e("NFC","postResult"); + try + { + switch (mode) { + case "write": + switch (param) { + case "text": + Log.e("NFC","-->write"); + onReceiveNfcWrite(context, intent); + Log.e("NFC","<--write"); + break; + default: + onUnexpectedAction(out, "Wrong Params", "Should be text for TAG"); + break; + } + break; + case "read": + switch (param){ + case "short": + readNDEFTag(intent,out); + break; + case "full": + readFullNDEFTag(intent,out); + break; + case "noData": + readNDEFTag(intent,out); + break; + default: + onUnexpectedAction(out, "Wrong Params", "Should be correct param value"); + break; + } + break; + default: + onUnexpectedAction(out, "Wrong Params", "Should be correct mode value "); + break; + } + } + catch (Exception e){ + onUnexpectedAction(out, "exception", e.getMessage()); + } + } + }); + } + public void onReceiveNfcWrite( final Context context, Intent intent) throws Exception { + { + Log.e("NFC","---->onReceiveNfcWrite"); + NfcAdapter adapter = NfcAdapter.getDefaultAdapter(context); + Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); + NdefRecord record = NdefRecord.createTextRecord("en", value); + NdefMessage msg = new NdefMessage(new NdefRecord[]{record}); + Ndef ndef = Ndef.get(tag); + ndef.connect(); + ndef.writeNdefMessage(msg); + ndef.close(); + } + } + + + public void readNDEFTag(Intent intent, JsonWriter out) throws Exception { + NfcAdapter adapter = NfcAdapter.getDefaultAdapter(this); + Parcelable[] msgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES); + Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); + Ndef ndefTag = Ndef.get(tag); + boolean bNdefPresent = false; + String strs[] = tag.getTechList(); + for (String s: strs){ + if (s.equals("android.nfc.tech.Ndef")) + bNdefPresent = true; + } + if (!bNdefPresent){ + onUnexpectedAction(out, "Wrong Technology","termux API support only NFEF Tag"); + return; + } + NdefMessage[] nmsgs = new NdefMessage[msgs.length]; + if (msgs.length == 1) { + nmsgs[0] = (NdefMessage) msgs[0]; + NdefRecord records[] = nmsgs[0].getRecords(); + out.beginObject(); + if (records.length >0 ) { + { + out.name("Record"); + if (records.length > 1) + out.beginArray(); + for (NdefRecord record: records){ + out.beginObject(); + int pos = 1 + record.getPayload()[0]; + pos = (NdefRecord.TNF_WELL_KNOWN==record.getTnf())?(int)record.getPayload()[0]+1:0; + int len = record.getPayload().length - pos; + byte msg[] = new byte[len]; + System.arraycopy(record.getPayload(), pos, msg, 0, len); + out.name("Payload").value(new String(msg)); + out.endObject(); + } + if (records.length > 1) + out.endArray(); + } + } + out.endObject(); + } + } + + public void readFullNDEFTag(Intent intent, JsonWriter out) throws Exception { + NfcAdapter adapter = NfcAdapter.getDefaultAdapter(this); + Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); + Ndef ndefTag = Ndef.get(tag); + Parcelable[] msgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES); + + String strs[] = tag.getTechList(); + boolean bNdefPresent = false; + for (String s: strs){ + if (s.equals("android.nfc.tech.Ndef")) + bNdefPresent = true; + } + if (!bNdefPresent){ + onUnexpectedAction(out, "Wrong Technology","termux API support only NFEF Tag"); + return; + } + NdefMessage[] nmsgs = new NdefMessage[msgs.length]; + out.beginObject(); + { + byte[] tagID = tag.getId(); + StringBuilder sp = new StringBuilder(); + for (byte tagIDpart : tagID) { sp.append(String.format("%02x", tagIDpart)); } + out.name("id").value(sp.toString()); + out.name("typeTag").value(ndefTag.getType()); + out.name("maxSize").value(ndefTag.getMaxSize()); + out.name("techList"); + { + out.beginArray(); + String[] tlist = tag.getTechList(); + for (String str : tlist) { + out.value(str); + } + out.endArray(); + } + if (msgs.length == 1) { + Log.e("NFC", "-->> readFullNDEFTag - 06"); + nmsgs[0] = (NdefMessage) msgs[0]; + NdefRecord records[] = nmsgs[0].getRecords(); + { + out.name("record"); + if (records.length > 1) + out.beginArray(); + for (NdefRecord record : records) { + out.beginObject(); + out.name("type").value(new String(record.getType())); + out.name("tnf").value(record.getTnf()); + if (records[0].toUri() != null) out.name("URI").value(record.toUri().toString()); + out.name("mime").value(record.toMimeType()); + int pos = 1 + record.getPayload()[0]; + pos = (NdefRecord.TNF_WELL_KNOWN==record.getTnf())?(int)record.getPayload()[0]+1:0; + int len = record.getPayload().length - pos; + byte msg[] = new byte[len]; + System.arraycopy(record.getPayload(), pos, msg, 0, len); + out.name("payload").value(new String(msg)); + out.endObject(); + } + if (records.length > 1) out.endArray(); + } + } + + } + out.endObject(); + } + + protected void onUnexpectedAction(JsonWriter out,String error, String description) throws Exception { + out.beginObject(); + out.name("error").value(error); + out.name("description").value(description); + out.endObject(); + out.flush(); + } +} diff --git a/app/src/main/java/com/termux/api/TermuxApiReceiver.java b/app/src/main/java/com/termux/api/TermuxApiReceiver.java index 5addbd3f..a1fc917b 100644 --- a/app/src/main/java/com/termux/api/TermuxApiReceiver.java +++ b/app/src/main/java/com/termux/api/TermuxApiReceiver.java @@ -5,6 +5,7 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; +import android.nfc.NfcAdapter; import android.os.Build; import android.provider.Settings; import android.widget.Toast; @@ -115,6 +116,9 @@ private void doWork(Context context, Intent intent) { MicRecorderAPI.onReceive(context, intent); } break; + case "Nfc": + context.startActivity(new Intent(context, NfcActivity.class).putExtras(intent.getExtras()).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); + break; case "NotificationList": ComponentName cn = new ComponentName(context, NotificationService.class); String flat = Settings.Secure.getString(context.getContentResolver(), "enabled_notification_listeners");