PC SOFT

FORUMS PROFESSIONNELS
WINDEVWEBDEV et WINDEV Mobile

Accueil → WINDEV Mobile 22 → Java et NFC sur android
Java et NFC sur android
Débuté par William, 04 avr. 2014 15:05 - 8 réponses
//hostimage.webdev.info/avatars/default.gif
Posté le 04 avril 2014 - 15:05
Bonjour,

J'aimerais utiliser les fonctionnalité d'android pour utilise le nfc, car les fonctionnalité de windev dans se domaine sont trop pauvre. Donc dans un premier temps j'aimerais simple savoir quand un tag est présent non pas par la fonction windev mais par des procédure Java.

Je me suis pas mal renseigner et j'ai pu voir que cela etaits possible, mais je bloque comment avoir le retour du "intent" que génére android lors d'une action. Je me suis notament aider de ce post http://forum.pcsoft.fr/fr-FR/pcsoft.fr.windevmobile/9605-wm17-service-android/read.awp.

Mais rien à faire, j'arrive à savoir si le capteur nfc est présent etc en java mais ne comprend pas comment avoir l'information si un tag est lu.


Le code pur java pour faire ceci :
import java.io.IOException;
import java.io.UnsupportedEncodingException;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.nfc.FormatException;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.nfc.tech.Ndef;
import android.nfc.tech.NdefFormatable;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;


@SuppressLint({ "ParserError", "ParserError" })
PUBLIC class MainActivity extends Activity{

NfcAdapter adapter;
PendingIntent pendingIntent;
IntentFilter writeTagFilters[];
boolean writeMode;
Tag mytag;
Context ctx;

@Override
PUBLIC void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

ctx=this;

adapter = NfcAdapter.getDefaultAdapter(this);
pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
IntentFilter tagDetected = new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED);
tagDetected.addCategory(Intent.CATEGORY_DEFAULT);
writeTagFilters = new IntentFilter[] { tagDetected };

}



PRIVATE void write(string text, Tag tag) throws IOException, FormatException {

NdefRecord[] records = { createRecord(text) };
NdefMessage Message = new NdefMessage(records);
// Get an instance of Ndef for the tag.
Ndef ndef = Ndef.get(tag);
// Enable I/O
ndef.connect();
// Write the message
ndef.writeNdefMessage(Message);
// Close the connection
ndef.close();
}



PRIVATE NdefRecord createRecord(string text) throws UnsupportedEncodingException {
string lang = "en";
byte[] textBytes = text.getBytes();
byte[] langBytes = lang.getBytes("US-ASCII");
int langLength = langBytes.length;
int textLength = textBytes.length;
byte[] payload = new byte[1 + langLength + textLength];

// set status byte (see NDEF spec for actual bits)
payload[0] = (byte) langLength;

// copy langbytes and textbytes into payload
System.arraycopy(langBytes, 0, payload, 1, langLength);
System.arraycopy(textBytes, 0, payload, 1 + langLength, textLength);

NdefRecord recordNFC = new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_TEXT, new byte[0], payload);

RETURN recordNFC;
}


@Override
PROTECTED void onNewIntent(Intent intent){
IF(NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction())){
mytag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
}
}

@Override
PUBLIC void onPause(){
super.onPause();
WriteModeOff();
}

@Override
PUBLIC void onResume(){
super.onResume();
WriteModeOn();
}

PRIVATE void WriteModeOn(){
writeMode = True;
adapter.enableForegroundDispatch(this, pendingIntent, writeTagFilters, null);
}

PRIVATE void WriteModeOff(){
writeMode = False;
adapter.disableForegroundDispatch(this);
}


}


Faut-il créer un service , ou peut-on directement faire tout sa dans windev mobile ?
//hostimage.webdev.info/avatars/default.gif
Posté le 08 avril 2014 - 17:30
Aprés quelques échanges avec "floman321", j'ai un piste à suivre mais toujours aucun retour sur mon application nous informant qu'un Tag NFC à etait lu.

Le code java de ma procédure :
PUBLIC static void Tag_NFC() {

final string Tag_NFC = "android.nfc.action.NDEF_DISCOVERED"
// Création de l'intervention sur chaque tag trouvé ?
getActiviteEnCours().registerReceiver(mTag_NFCReceiver, new IntentFilter(Tag_NFC));
}

static BroadcastReceiver mTag_NFCReceiver = new BroadcastReceiver(){

PUBLIC void onReceive(Context arg0, Intent intent) {

// Simple info() qui s'affiche à l'écran si tag lu
appelProcedureWL("ok","Test3");

}

PUBLIC void onDestroy() {
getActiviteEnCours().unregisterReceiver(mTag_NFCReceiver);
}

};
//hostimage.webdev.info/avatars/default.gif
Posté le 14 octobre 2014 - 15:30
Bonjour,

je relance car je suis aussi intéresser par d'autre fonctionnalité NFC que n'offre pas Windev mobile.

Merci
//hostimage.webdev.info/avatars/default.gif
Posté le 10 février 2017 - 12:00
Bonjour,
Je suis confronté au même problème que les personne ci-dessus.
Je ne suis pas expert Java.
Le poste étant assez ancien, avez-vous trouvé des solutions?
En vous remerciant.
Cordialement.
//hostimage.webdev.info/avatars/default.gif
Posté le 24 février 2017 - 09:28
Bonjour,

Oui j'ai enfin trouvé une solution sans faire une usine à gaz en passant par des fenêtres générées avec Eclipse ...
Ce qu'il faut savoir pour commencer, c'est que cette méthode ne fonctionne qu'avec les appareils Android avec au minimum la version 4.4, car depuis cette version il y a la possibilité d'utilisé les callback pour le NFC.

Ci-dessous le code simple pour détecté un tag avec un fonction Java dans le code Windev mobile :
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.nfc.NfcAdapter.ReaderCallback;
import android.os.Bundle;

public static void NFC_TEST()
{
final String TAG = "TEST";

class NFC{
public void start(){
NfcAdapter adapter = NfcAdapter.getDefaultAdapter(getApplicationContext());
enableReaderMode(adapter);
}

private void enableReaderMode(NfcAdapter adapter) {
Bundle options = new Bundle();
options.putInt("presence", 5000);
ReaderCallback callback = new ReaderCallback() {
public void onTagDiscovered(Tag tag) {
Log.d(TAG, "Détection d'un tag");
}
};
adapter.enableReaderMode(getActiviteEnCours(), callback, adapter.FLAG_READER_NFC_V,, options);
}
}

NFC myNFC = new NFC();
myNFC.start();

}


A noter que ici je filtre avec les tags de type NFC-V.

En espérant que cela aide du monde.

William
//hostimage.webdev.info/avatars/default.gif
Posté le 17 mai 2017 - 16:13
Bonjour William,

Ton code est censé fonctionné directement via une fonction java dans Windev Mobile ?
Si oui, qu'est censé faire la ligne "Log.d(...)" ?
Pour ma part, j'ai essayé de remplacer cette ligne par diverses autres comme "appelProcedureWL(...)" ou "Toast.makeText(...)" mais rien ne fonctionne lorsque je passe un Tag.

Merci d'avance

Cordialement,

Clad07
//hostimage.webdev.info/avatars/default.gif
Posté le 18 mai 2017 - 11:08
Clad07,

Log.d inscrit dans dans les logs Android la ligne(https://developer.android.com/studio/debug/am-logcat.html). Deuxièmement, je fais un filtre sur un type de tag bien particulier qui est le type NFC V(https://developer.android.com/reference/android/nfc/tech/NfcV.html). La fonction doit être appeler une seule foi par exemple au lancement d'une fenêtre.

Il faut aussi penser si cela n'est pas déjà fait à ajouter les autorisations NFC, manuellement dans le manifeste.

Cordialement,

William
//hostimage.webdev.info/avatars/default.gif
Posté le 18 mai 2017 - 14:17
William,

C'est bien ce que je pensais pour le Log.d. Bon, je n'arrive pas à l'utiliser (je ne trouve pas ou cela s'inscrit :D) mais ce n'est pas grave du tout.
J'ai trouvé ce qu'il fallait pour le bon fonctionnement d'une lecture (me concernant), à savoir éxécuter une fonction qui touche à l'IHM. Voici mon code :

import android.nfc.NfcAdapter;
import android.nfc.NfcAdapter.ReaderCallback;
import android.nfc.Tag;
import android.widget.Toast;

public static void NfcNatif()
{
NfcAdapter adapter = NfcAdapter.getDefaultAdapter(getApplicationContext());
ReaderCallback callback = new ReaderCallback() {
@Override
public void onTagDiscovered(final Tag tag) {
getActiviteEnCours().runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(), "lol", Toast.LENGTH_SHORT).show();
//appelProcedureWL("Popup",tag.getId(),"Numero","passez.png", false);
//appelProcedureWL("LectureTagNfc",tag.getId());
}
});
}
};
adapter.enableReaderMode(getActiviteEnCours(), callback, NfcAdapter.FLAG_READER_NFC_A | NfcAdapter.FLAG_READER_NO_PLATFORM_SOUNDS, null);
}


Il fallait donc simplement faire que mes traitements reviennent sur le thread principal (enfin je crois que c'est ce que signifie runOnUiThread).
Que ce soit un toast, un Info() ou lune fonction perso Windev, tout fonctionne désormais.

Désormais, il ne me reste plus qu'a trouver l'ID unique du TAG !
Avec une variable de type nfcTag de Windev Mobile, il suffisait de faire :
tag est un nfcTag
id est une chaîne = tag.Identifiant

Et pour l'instant, j'ai testé le "tag.getId()" d'android mais cela ne correspond vraiment pas. Mais je ne fais que commencer à chercher !

Encore un grand merci pour ton code ! C'est très bref et parfaitement fonctionnel !
Pour ma part, j'en ai besoin (comparé à la fonction NFC Windev) car je ne désire pas entendre le son Natif Android lors d'une lecture. Et pour info à tous, j'obtiens cela grace au paramètre "NfcAdapter.FLAG_READER_NO_PLATFORM_SOUNDS" dans la fonction "enableReaderMode".

Bien cordialement,

Clad07
//hostimage.webdev.info/avatars/default.gif
Posté le 18 mai 2017 - 16:19
Toutes mes excuses pour le double post !

J'ai trouvé comment obtenir le Serial Number unique d'un badge / tag :
Il faut remplacer le "tag.getId()" de mon code précédent par "ByteArrayToHexString(tag.getId())"
Et voici la fonction "ByteArrayToHexString" :

public static String ByteArrayToHexString(byte [] inarray) 
{
int i, j, in;
String [] hex = {"0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F"};
String out= "";

for(j = 0 ; j < inarray.length ; ++j) 
{
in = (int) inarray[j] & 0xff;
i = (in >> 4) & 0x0f;
out += hex[i];
i = in & 0x0f;
out += hex[i];
}
return out;
}


Bon dev à tous !

Cordialement,

Clad07