I am trying to use NFC to send a URL from an Android app to other phone,
both have enabled NFC and working fine.
when i tried to test the app nothing happen,
i have tried the following app from store and it work perfectly:
https://play.google.com/store/apps/details?id=com.maxsoft.ndeftagemulator
this is my code:
NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
if (nfcAdapter == null) {
Toast.makeText(this, "NFC not supported on this device.", Toast.LENGTH_LONG).show();
finish();
return;
}
nfcAdapter.setNdefPushMessageCallback(event -> {
String url = "https://www.example.com";
NdefRecord ndefRecord = NdefRecord.createUri(url);
NdefMessage ndefMessage = new NdefMessage(ndefRecord);
return ndefMessage;
}, this);
nfcAdapter.setOnNdefPushCompleteCallback(event -> Toast.makeText(MainActivity.this, "URL sent via NFC.", Toast.LENGTH_LONG).show(), this);
i also added permission in Manifest
<uses-permission android:name="android.permission.NFC" />
i searched for answers here and checked the following with no success ( android API +29 )
Ho do I send a URL via NFC?
Sending URL from Android to Windows Phone via NFC gives Play Store link
Sending URL via NFC to be opened by browser
Related
I want to create a mini app just to read an NFC tag and later send to another device on Android. That part is done already and I can read the tag and I can print the string on a EditText. But I also want to send the text that I have read from that tag to another device with NFC. How can I do that?
//I have this code here when a tag is discovered...
#Override
protected void onNewIntent(Intent intent) {
if (intent.getAction().equals(NfcAdapter.ACTION_TAG_DISCOVERED)) {
String result = "";
result = ByteArrayToHexString(intent.getByteArrayExtra(NfcAdapter.EXTRA_ID));
myTag = result;
txtTag.setText(myTag);
}
}
How can I send the text string to another device via NFC?
What you want to do is simply not possible with Android right no (and probably won't be in future).
You currently read the anti-collision identifier (UID, PUPI, or whatever it is called for that specific tag platform that you read):
result = ByteArrayToHexString(intent.getByteArrayExtra(NfcAdapter.EXTRA_ID));
The anti-collision identifier is part of a very low protocol layer. While Android does support host-based card emulation (see Android HCE), the Android API has no means to control such low-level parameters as the UID. Typically, its also not possible to change that information on NFC tags.
Note that if your tag also contains some high-level data in NDEF format you could obtain that using:
Parcelable[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
NdefMessage msg = null;
if ((rawMsgs != null) && (rawMsgs.length > 0)) {
msg = (NdefMessage)rawMsgs[0];
}
if (msg != null) {
// do something with the received message
}
Android does support storing these NDEF messages on (writable) NFC tags and it also supports sending NDEF messages to other NFC devices (see Beaming NDEF Messages to Other Devices).
E.g. to store an NDEF message on an NFC tag you could use:
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
Ndef ndef = Ndef.get(tag);
if (ndef != null) {
try {
ndef.connect();
ndef.writeNdefMessage(msg);
} finally {
ndef.close();
}
} else {
NdefFormatable ndefFormatable = NdefFormatable.get(tag);
if (ndefFormatable != null) {
try {
ndefFormatable.connect();
ndefFormatable.format(message);
} finally {
ndefFormatable.close();
}
}
}
Or in order to send the message to another NFC device through peer-to-peer mode (Android Beam), you could use:
NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
nfcAdapter.setNdefPushMessage(msg, this);
I am having an issue with NFC in a project I am currently making for school.
It is the first time I try to use NFC in an application and might therefore not have a proper understanding of how it works.
The issue is that we have been testing the application on a HTC One M8 for the past week, where our application had no problems reading the string on our chip.
However when I'm now trying with a family member's LG Nexus 5, the string does not get passed to the application.
Here is the code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_app);
//NFC Adapter
nfcAdapter = NfcAdapter.getDefaultAdapter(this);
}
#Override
protected void onResume() {
super.onResume();
enableForegroundDispatchSystem();
}
#Override
protected void onPause() {
super.onPause();
disableForegroundDispatchSystem();
}
#Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
if (intent.hasExtra(NfcAdapter.EXTRA_TAG)) {
Toast.makeText(this, "NfcIntent!", Toast.LENGTH_SHORT).show();
Parcelable[] parcelables = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
if (parcelables != null && parcelables.length > 0) {
// this part gets executed on the HTC Once m8
readTextFromMessage((NdefMessage) parcelables[0]);
} else {
// this part gets executed on the LG Nexus 5
Toast.makeText(this, "No NDEF messages found!", Toast.LENGTH_SHORT).show();
}
}
}
private void readTextFromMessage(NdefMessage ndefMessage) {
NdefRecord[] ndefRecords = ndefMessage.getRecords();
if (ndefRecords != null && ndefRecords.length>0) {
NdefRecord ndefRecord = ndefRecords[0];
String tagContent = getTextFromNdefRecord(ndefRecord);
if (tagContent.toString().equals("Kasse")) {
//scanBtn.setVisibility(View.VISIBLE);
} else {
//addItem(tagContent);
//cartArrayDisplay.addView(nameList.get(cartAmount));
//priceArrayDisplay.addView(priceList.get(cartAmount));
//cartAmount++;
}
} else {
Toast.makeText(this, "No NDEF records found!", Toast.LENGTH_SHORT).show();
}
}
private void enableForegroundDispatchSystem() {
Intent intent = new Intent(this, AppActivity.class).addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
IntentFilter[] intentFilters = new IntentFilter[]{};
nfcAdapter.enableForegroundDispatch(this, pendingIntent, intentFilters, null);
}
private void disableForegroundDispatchSystem() {
nfcAdapter.disableForegroundDispatch(this);
}
public String getTextFromNdefRecord(NdefRecord ndefRecord) {
String tagContent = null;
try {
byte[] payload = ndefRecord.getPayload();
String textEncoding = ((payload[0] & 128) == 0) ? "UTF-8" : "UTF-16";
int languageSize = payload[0] & 0063;
tagContent = new String(payload, languageSize + 1,
payload.length - languageSize - 1, textEncoding);
} catch (UnsupportedEncodingException e) {
Log.e("getTextFromNdefRecord", e.getMessage(), e);
}
return tagContent;
}
When run the app on the HTC One m8 it would always run this part:
if (parcelables != null && parcelables.length > 0) {
readTextFromMessage((NdefMessage) parcelables[0]);
However, when run the app on the LG Nexus 5 it runs this part:
} else {
Toast.makeText(this, "No NDEF messages found!", Toast.LENGTH_SHORT).show();
I have been told that it is most likely due to the tags we're using not being compatible with all devices. However, I thought it could also be something programmatically, since I am not experienced working with Android and NFC.
The tags are student IDs. A tag reader app identified one of them as
Tag Type: Mifare Classic 1k
NUID[4]: dbc3f12d
ATQA: 0004
SAK: 08
Target technology: android.nfc.tech.NfcA
The problem you are experiencing is a result of the NFC chipset in your device not being compatible with MIFARE Classic. Typically, only devices with an NFC chipset from NXP are capable of reading MIFARE Classic (NXP is the owner of the MIFARE technology).
MIFARE Classic uses the anti-collision and activation mechanism defined in ISO/IEC 14443 Type A (and also ISO/IEC 18092). Therefore, that part matches the way other contactless smartcards and NFC tags work. As a result, all (most!) Android NFC devices will detect such cards/tags. However, the communication protocol and framing deviates from that defined for other NFC tags and contactless smartcards. This non-standard protocol is not available on other chipsets than those by NXP and therefore, no data can be read from MIFARE Classic cards on devices with non-NXP NFC controllers.
The HTC One m8 contains NXP's PN544 NFC controller and can therefore discover your tag and read data from it. The LG Nexus 5 contains Broadcom's BCM20793 NFC controller and can therefore discover your tag but is unable to read data from it.
On top of what Michael said, you can check whether your device supports Mifare Classic with
PackageManager.hasSystemFeature("com.nxp.mifare");
As the title suggests, I am developing an app, which can connect and pair with another Android phone. I can successfully scan, connect, pair and transmit String data over bluetooth. I tested by sending String data and received it in another android smartphone and showed it in the toast.
The actual scenario
This application will be installed in both android phones. Once another android phone scans and connect to the phone over bluetooth, then I want to launch this app. I know we can accomplish this using BroadcastReceiver. But how can I implement this in terms of Bluetooth connection. Any code snippet or idea or suggestions are welcomed..
After you get the BT msg,Hope you followed this link ,Here after "// Send the obtained bytes to the UI activity"
Send a broadcast to start your app.
Loop with the list of apps installed and know which app to be launched and use the below to launch a app.
public String getPreInstalledPocPkgName(){
String pkgName = null;
try {
List<PackageInfo> pkgInfoList = mContext.getPackageManager().getInstalledPackages(0);
for(PackageInfo pkgInfo:pkgInfoList){
pkgName = pkgInfo.packageName;
if(pkgName==null || pkgName.equals("")){
continue;
}
for(String name:pttPkgList){
if(pkgName.equals(name)){
Log.d(TAG, "------------ app with package name ["+pkgName+"] already installed----------");
return pkgName;
}
}
}
} catch (Exception e) {
Log.e(TAG, "-------Error! while fetching previously installed app------", e);
clearConfigFromSharedPath();
}
Log.d(TAG, "------------No previously installed app----------");
return null;
}
}
String pttAppPkgName = getPreInstalledPocPkgName();
Or
pttAppPkgName = your app package.
PackageManager pm = getPackageManager();
Intent intent = pm.getLaunchIntentForPackage(pttAppPkgName);
startActivity(intent);
The idea is simple:
Attach a USB pendrive with music (mp3) files and let android 4.0 access it.
For example to stream the music.
First of all:
Using eclipse android File Explorer I see the mounted /mnt/USB0/ with all the files
Using the x86 emulator ALT+F1 df command I can see /mnt/USB0
Using the x86 emulator ALT+F1 ls /mnt/USB0 give me a list of the files
The app has the correct permissions to access the devices
<uses-permission android:name="android.permission.MEDIA_CONTENT_CONTROL"/>
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
When I attach the pendrive the app ask for the permission and I give it.
if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)){
Log.d("USB","permission OKE");
if(device instanceof UsbDevice){
test(mUsbManager,device);
}
}
void test(UsbManager mUsbManager, UsbDevice device){
UsbInterface intf = device.getInterface(0);
UsbDeviceConnection connection = mUsbManager.openDevice(device);
if(connection.claimInterface(intf, true)){
Log.d("open","YES OPENS WORKS");
// TRYING THINGS AT THIS PLACE
try {
// String line;
// Process p = Runtime.getRuntime().exec("ls /mnt/USB0");
// BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()) );
// while((line = in.readLine()) != null){
// Log.d("read",line);
// }
// in.close();
}
catch (Exception e) {
Log.d("command error:",e.getMessage());
}
connection.releaseInterface(intf);
}else{
Log.d("open","cannot claim interface");
}
connection.close();
}
Solutions that don't work with the facts above
Using the app Process p = Runtime.getRuntime().exec("ls /mnt/USB0"); gives me nothing
Using Mtp don't work
Using new File("/mnt/USB0") gives me nothing
I have an android application with a webview in it.
When the webview is getting to url with certain text, e.g. ticket, then I would like to send the url to another NFC device through NFC.
I was able to send the url to the type 4 NFC tag, but I am not able to find out how to send it to other NFC device so that it will launch the browser with the url.
I was just using the following to create the NDEF
NdefRecord uriRecord = NdefRecord.createUri(url);
NdefMessage message = new NdefMessage(new NdefRecord[] {
uriRecord
});
and then use this to write
ndef.writeNdefMessage(message);
I am writing the app in ICS (on galaxy nexus) and trying to send to the galaxy s2 with 2.3.6.
Any help and pointer will be appreciated.
When sending an NDEF message to another phone, you don't use a tag read/write API such as Ndef. Instead, your NDEF message is delivered via NFC peer-to-peer. One way to do that is to use setNdefPushMessageCallback in your Activity's onCreate():
NfcAdapter nfc = NfcAdapter.getDefaultAdapter(this);
nfc.setNdefPushMessageCallback(new NfcAdapter.CreateNdefMessageCallback()
{
/*
* (non-Javadoc)
* #see android.nfc.NfcAdapter.CreateNdefMessageCallback#createNdefMessage(android.nfc.NfcEvent)
*/
#Override
public NdefMessage createNdefMessage(NfcEvent event)
{
NdefRecord uriRecord = NdefRecord.createUri(Uri.encode("http://www.google.com/"));
return new NdefMessage(new NdefRecord[] { uriRecord });
}
}, this, this);
The callback will be called when another NFC device comes near and a peer-to-peer connection is established. The callback then creates the NDEF message to be sent (in your case: the URL displayed in the webview).