Android NFC development using Fragment - android

The online source codes for NFC are done using Activity. I would like to ask if it is possible to develop using Fragment instead?
This is the error i hit when i run the codes
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.mobile.countmein/com.mobile.countmein.activities.NFCScanner}: java.lang.ClassCastException: com.mobile.countmein.activities.NFCScanner cannot be cast to android.app.Activity
public class TagViewer extends Fragment {
private static final SimpleDateFormat TIME_FORMAT = new SimpleDateFormat();
private LinearLayout mTagContent;
private NfcAdapter mAdapter;
private PendingIntent mPendingIntent;
private NdefMessage mNdefPushMessage;
private AlertDialog mDialog;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.tag_viewer, container, false);
}
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mTagContent = (LinearLayout)view.findViewById(R.id.list);
resolveIntent(getActivity().getIntent());
mDialog = new AlertDialog.Builder(getActivity()).setNeutralButton("Ok", null).create();
mAdapter = NfcAdapter.getDefaultAdapter(getActivity());
if (mAdapter == null) {
showMessage(R.string.error, R.string.no_nfc);
}
mPendingIntent = PendingIntent.getActivity(getActivity(), 0,
new Intent(getActivity(), getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
mNdefPushMessage = new NdefMessage(new NdefRecord[] { newTextRecord(
"Message from NFC Reader :-)", Locale.ENGLISH, true) });
}
private void showMessage(int title, int message) {
mDialog.setTitle(title);
mDialog.setMessage(getText(message));
mDialog.show();
}
private NdefRecord newTextRecord(String text, Locale locale, boolean encodeInUtf8) {
byte[] langBytes = locale.getLanguage().getBytes(Charset.forName("US-ASCII"));
Charset utfEncoding = encodeInUtf8 ? Charset.forName("UTF-8") : Charset.forName("UTF-16");
byte[] textBytes = text.getBytes(utfEncoding);
int utfBit = encodeInUtf8 ? 0 : (1 << 7);
char status = (char) (utfBit + langBytes.length);
byte[] data = new byte[1 + langBytes.length + textBytes.length];
data[0] = (byte) status;
System.arraycopy(langBytes, 0, data, 1, langBytes.length);
System.arraycopy(textBytes, 0, data, 1 + langBytes.length, textBytes.length);
return new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_TEXT, new byte[0], data);
}
#Override
public void onResume() {
super.onResume();
if (mAdapter != null) {
if (!mAdapter.isEnabled()) {
showMessage(R.string.error, R.string.nfc_disabled);
}
mAdapter.enableForegroundDispatch(getActivity(), mPendingIntent, null, null);
mAdapter.enableForegroundNdefPush(getActivity(), mNdefPushMessage);
}
}
#Override
public void onPause() {
super.onPause();
if (mAdapter != null) {
mAdapter.disableForegroundDispatch(getActivity());
mAdapter.disableForegroundNdefPush(getActivity());
}
}
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[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
NdefMessage[] msgs;
if (rawMsgs != null) {
msgs = new NdefMessage[rawMsgs.length];
for (int i = 0; i < rawMsgs.length; i++) {
msgs[i] = (NdefMessage) rawMsgs[i];
}
} else {
// Unknown tag type
byte[] empty = new byte[0];
byte[] id = intent.getByteArrayExtra(NfcAdapter.EXTRA_ID);
Parcelable tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
byte[] payload = dumpTagData(tag).getBytes();
NdefRecord record = new NdefRecord(NdefRecord.TNF_UNKNOWN, empty, id, payload);
NdefMessage msg = new NdefMessage(new NdefRecord[] { record });
msgs = new NdefMessage[] { msg };
}
// Setup the views
buildTagViews(msgs);
}
}
private String dumpTagData(Parcelable p) {
StringBuilder sb = new StringBuilder();
Tag tag = (Tag) p;
byte[] id = tag.getId();
sb.append("Tag ID (hex): ").append(getHex(id)).append("\n");
sb.append("Tag ID (dec): ").append(getDec(id)).append("\n");
String prefix = "android.nfc.tech.";
sb.append("Technologies: ");
for (String tech : tag.getTechList()) {
sb.append(tech.substring(prefix.length()));
sb.append(", ");
}
sb.delete(sb.length() - 2, sb.length());
for (String tech : tag.getTechList()) {
if (tech.equals(MifareClassic.class.getName())) {
sb.append('\n');
MifareClassic mifareTag = MifareClassic.get(tag);
String type = "Unknown";
switch (mifareTag.getType()) {
case MifareClassic.TYPE_CLASSIC:
type = "Classic";
break;
case MifareClassic.TYPE_PLUS:
type = "Plus";
break;
case MifareClassic.TYPE_PRO:
type = "Pro";
break;
}
sb.append("Mifare Classic type: ");
sb.append(type);
sb.append('\n');
sb.append("Mifare size: ");
sb.append(mifareTag.getSize() + " bytes");
sb.append('\n');
sb.append("Mifare sectors: ");
sb.append(mifareTag.getSectorCount());
sb.append('\n');
sb.append("Mifare blocks: ");
sb.append(mifareTag.getBlockCount());
}
if (tech.equals(MifareUltralight.class.getName())) {
sb.append('\n');
MifareUltralight mifareUlTag = MifareUltralight.get(tag);
String type = "Unknown";
switch (mifareUlTag.getType()) {
case MifareUltralight.TYPE_ULTRALIGHT:
type = "Ultralight";
break;
case MifareUltralight.TYPE_ULTRALIGHT_C:
type = "Ultralight C";
break;
}
sb.append("Mifare Ultralight type: ");
sb.append(type);
}
}
return sb.toString();
}
private String getHex(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (int i = bytes.length - 1; i >= 0; --i) {
int b = bytes[i] & 0xff;
if (b < 0x10)
sb.append('0');
sb.append(Integer.toHexString(b));
if (i > 0) {
sb.append(" ");
}
}
return sb.toString();
}
private long getDec(byte[] bytes) {
long result = 0;
long factor = 1;
for (int i = 0; i < bytes.length; ++i) {
long value = bytes[i] & 0xffl;
result += value * factor;
factor *= 256l;
}
return result;
}
void buildTagViews(NdefMessage[] msgs) {
if (msgs == null || msgs.length == 0) {
return;
}
LayoutInflater inflater = LayoutInflater.from(getActivity());
LinearLayout content = mTagContent;
// Parse the first message in the list
// Build views for all of the sub records
Date now = new Date();
List<ParsedNdefRecord> records = NdefMessageParser.parse(msgs[0]);
final int size = records.size();
for (int i = 0; i < size; i++) {
TextView timeView = new TextView(getActivity());
timeView.setText(TIME_FORMAT.format(now));
content.addView(timeView, 0);
ParsedNdefRecord record = records.get(i);
content.addView(record.getView(getActivity(), inflater, content, i), 1 + i);
content.addView(inflater.inflate(R.layout.tag_divider, content, false), 2 + i);
}
}
}
I removed the following because a fragment does not have the method:
#Override
public void onNewIntent(Intent intent) {
setIntent(intent);
resolveIntent(intent);
}

A fragment is to control a portion of the user interface in an Activity.
Why not put your NFC code in the activity?
If you really need the Intent in the fragment you can pass it in a Bundle because an Intent is Parceable.
See: Pass intent to my fragment

Related

Android Studio NFC reading data, removal of the prefix en [duplicate]

Hey guys im testing NFC and i have an issue with i think it is formating..
I added a string value in the tag with an app to write.
when i scan it with that same store app it shows ok...
when i scan with my app it shows the correct name in the app but adds a "en" before the message..
and a white space.. so if i add a name in the tag then scan and get a API it shows 404 cause there is an en and white space..
http://myapisite.com/API/getdevice.php?id= enTagString
before the = space and then en before the id or even name i put..
i tried a few ways..
public class MainActivity extends Activity {
// list of NFC technologies detected:
private final String[][] techList = new String[][]{
new String[]{
NfcA.class.getName (),
NfcB.class.getName (),
NfcF.class.getName (),
NfcV.class.getName (),
IsoDep.class.getName (),
MifareClassic.class.getName (),
MifareUltralight.class.getName (), Ndef.class.getName ()
}
};
private TextView mTextView;
private ImageView mImageView;
private String ID, machineName, MachineImg, MachinePart, level;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate (savedInstanceState);
setContentView (R.layout.activity_main);
mImageView = findViewById (R.id.imageView);
mTextView = findViewById (R.id.textView_explanation);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater ().inflate (R.menu.menu, menu);
return true;
}
#Override
protected void onResume() {
super.onResume ();
PendingIntent pendingIntent = PendingIntent.getActivity (this, 0, new Intent (this, getClass ()).addFlags (Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
// creating intent receiver for NFC events:
IntentFilter filter = new IntentFilter ();
filter.addAction (NfcAdapter.ACTION_TAG_DISCOVERED);
filter.addAction (NfcAdapter.ACTION_NDEF_DISCOVERED);
filter.addAction (NfcAdapter.ACTION_TECH_DISCOVERED);
// enabling foreground dispatch for getting intent from NFC event:
NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter (this);
nfcAdapter.enableForegroundDispatch (this, pendingIntent, new IntentFilter[]{filter}, this.techList);
}
#Override
protected void onPause() {
super.onPause ();
NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter (this);
nfcAdapter.disableForegroundDispatch (this);
}
void parseNdefMessage(Intent intent) {
Parcelable[] ndefMessageArray = intent.getParcelableArrayExtra (
NfcAdapter.EXTRA_NDEF_MESSAGES);
NdefMessage ndefMessage = (NdefMessage) ndefMessageArray[0];
String text = new String (ndefMessage.getRecords ()[0].getPayload ());
Log.d (TAG, "PAYLOAD MESS" + text);
ID = text;
getApiInfos ();
}
#Override
protected void onNewIntent(Intent intent) {
parseNdefMessage (intent);
if (intent.getAction ().equals (NfcAdapter.ACTION_TAG_DISCOVERED)) {
mTextView.setText ("NFC Tag\n" + ByteArrayToHexString (intent.getByteArrayExtra (NfcAdapter.EXTRA_ID)));
Parcelable tagN = intent.getParcelableExtra (NfcAdapter.EXTRA_TAG);
if (tagN != null) {
NdefMessage[] msgs;
byte[] empty = new byte[0];
byte[] id = intent.getByteArrayExtra (NfcAdapter.EXTRA_ID);
byte[] payload = dumpTagData (tagN).getBytes ();
NdefRecord record = new NdefRecord (NdefRecord.TNF_UNKNOWN, empty, id, payload);
NdefMessage msg = new NdefMessage (new NdefRecord[]{record});
msgs = new NdefMessage[]{msg};
Log.d (TAG, msgs[0].toString ());
} else {
Log.d (TAG, "Parcelable NULL");
}
Parcelable[] messages1 = intent.getParcelableArrayExtra (NfcAdapter.EXTRA_NDEF_MESSAGES);
if (messages1 != null) {
Log.d (TAG, "Found " + messages1.length + " NDEF messages");
for (int i = 0; i < messages1.length; ++i) {
Log.d (TAG, "Found M " + messages1[i].toString ());
}
} else {
Log.d (TAG, "Not EXTRA_NDEF_MESSAGES");
}
Tag tag = intent.getParcelableExtra (NfcAdapter.EXTRA_TAG);
Ndef ndef = Ndef.get (tag);
if (ndef != null) {
Parcelable[] messages = intent.getParcelableArrayExtra (NfcAdapter.EXTRA_NDEF_MESSAGES);
if (messages != null) {
Log.d (TAG, "Found " + messages.length + " NDEF messages");
}
} else {
Log.d (TAG, "Write to an unformatted tag not implemented");
}
}
}
private String dumpTagData(Parcelable p) {
StringBuilder sb = new StringBuilder ();
Tag tag = (Tag) p;
byte[] id = tag.getId ();
sb.append ("Tag ID (hex): ").append (getHex (id)).append ("\n");
sb.append ("Tag ID (dec): ").append (getDec (id)).append ("\n");
sb.append ("ID (reversed): ").append (getReversed (id)).append ("\n");
String prefix = "android.nfc.tech.";
sb.append ("Technologies: ");
for (String tech : tag.getTechList ()) {
sb.append (tech.substring (prefix.length ()));
sb.append (", ");
}
sb.delete (sb.length () - 2, sb.length ());
for (String tech : tag.getTechList ()) {
if (tech.equals (MifareClassic.class.getName ())) {
sb.append ('\n');
MifareClassic mifareTag = MifareClassic.get (tag);
String type = "Unknown";
switch (mifareTag.getType ()) {
case MifareClassic.TYPE_CLASSIC:
type = "Classic";
break;
case MifareClassic.TYPE_PLUS:
type = "Plus";
break;
case MifareClassic.TYPE_PRO:
type = "Pro";
break;
}
sb.append ("Mifare Classic type: ");
sb.append (type);
sb.append ('\n');
sb.append ("Mifare size: ");
sb.append (mifareTag.getSize () + " bytes");
sb.append ('\n');
sb.append ("Mifare sectors: ");
sb.append (mifareTag.getSectorCount ());
sb.append ('\n');
sb.append ("Mifare blocks: ");
sb.append (mifareTag.getBlockCount ());
}
if (tech.equals (MifareUltralight.class.getName ())) {
sb.append ('\n');
MifareUltralight mifareUlTag = MifareUltralight.get (tag);
String type = "Unknown";
switch (mifareUlTag.getType ()) {
case MifareUltralight.TYPE_ULTRALIGHT:
type = "Ultralight";
break;
case MifareUltralight.TYPE_ULTRALIGHT_C:
type = "Ultralight C";
break;
}
sb.append ("Mifare Ultralight type: ");
sb.append (type);
}
}
DateFormat TIME_FORMAT = SimpleDateFormat.getDateTimeInstance ();
Date now = new Date ();
mTextView.setText (TIME_FORMAT.format (now) + '\n' + sb.toString ());
return sb.toString ();
}
private String getHex(byte[] bytes) {
StringBuilder sb = new StringBuilder ();
for (int i = bytes.length - 1; i >= 0; --i) {
int b = bytes[i] & 0xff;
if (b < 0x10)
sb.append ('0');
sb.append (Integer.toHexString (b));
if (i > 0) {
sb.append (" ");
}
}
return sb.toString ();
}
private long getDec(byte[] bytes) {
long result = 0;
long factor = 1;
for (int i = 0; i < bytes.length; ++i) {
long value = bytes[i] & 0xffl;
result += value * factor;
factor *= 256l;
}
return result;
}
private long getReversed(byte[] bytes) {
long result = 0;
long factor = 1;
for (int i = bytes.length - 1; i >= 0; --i) {
long value = bytes[i] & 0xffl;
result += value * factor;
factor *= 256l;
}
return result;
}
private 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];
}
Log.d ("ByteArrayToHexString", String.format ("%0" + (inarray.length * 2) + "X", new BigInteger (1, inarray)));
return out;
}
enter code here
Most likely this is because the App writing is storing it as a "WELL_KNOWN" type of text/plain
The specs for NFC Text format can be found at NFCForum-TS-RTD_Text_1.0.pdf.
The extra characters in the payload are as below:
language length (1 byte) + language (n bytes) + Text
So the space is the actually a non printable size of the language.
The "en" is defining that the text is English.
https://developer.android.com/reference/android/nfc/NdefRecord#getPayload()
returns a byte array.
So below should work to trim it (tested) as there don't seem to be nice helper methods to decode it, only create this format.
// Create Test Record
NdefRecord record = NdefRecord.createTextRecord("en", "Hello");
//Get Bytes of payload
// byte[] payload = ndefMessage.getRecords ()[0].getPayload ();
// Get Bytes of test NDEF Record
byte[] payload = record.getPayload ();
// Read First Byte and then trim off the right length
byte[] textArray = Arrays.copyOfRange(payload, (int) payload[0] + 1 , payload.length);
// Convert to Text
String text = new String(textArray);
UPDATE:
As the code given in the question is a bit of a mess and you do things you don't need to do and don't do things you do need to do (e.g. you have asked to be sent data from cards that won't have NDef data in them and then you parse for Ndef data without checking there is some data to parse)
I've simplified the code just to read a text NDEF record (Note not tested, but based on how I used to read NDEF data, I now use a better method to read cards that is more reliable especially if you want to write to cards as well)
public class MainActivity extends Activity {
private TextView mTextView;
private ImageView mImageView;
private String ID, machineName, MachineImg, MachinePart, level;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mImageView = findViewById(R.id.imageView);
mTextView = findViewById(R.id.textView_explanation);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu, menu);
return true;
}
#Override
protected void onResume() {
super.onResume();
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
// creating intent receiver for NFC events:
IntentFilter filter = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
// enabling foreground dispatch for getting intent from NFC event:
NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
nfcAdapter.enableForegroundDispatch(this, pendingIntent, new IntentFilter[]{filter}, null);
}
#Override
protected void onPause() {
super.onPause();
NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
nfcAdapter.disableForegroundDispatch(this);
}
void parseNdefMessage(Intent intent) {
Parcelable[] ndefMessageArray = intent.getParcelableArrayExtra(
NfcAdapter.EXTRA_NDEF_MESSAGES);
// Test if there is actually a NDef message passed via the Intent
if (ndefMessageArray != null) {
NdefMessage ndefMessage = (NdefMessage) ndefMessageArray[0];
//Get Bytes of payload
byte[] payload = ndefMessage.getRecords()[0].getPayload();
// Read First Byte and then trim off the right length
byte[] textArray = Arrays.copyOfRange(payload, (int) payload[0] + 1, payload.length);
// Convert to Text
String text = new String(textArray);
ID = text;
getApiInfos();
}
}
#Override
protected void onNewIntent(Intent intent) {
if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction())) {
parseNdefMessage(intent);
}
}
}
Ok thx to #Andrew i used part of your code and adapted it to my tests.. it works great now i can clean it up and removed what is not used or needed.Thx happy holidays!:)
void parseNdefMessage(Intent intent) {
Parcelable[] ndefMessageArray = intent.getParcelableArrayExtra(
NfcAdapter.EXTRA_NDEF_MESSAGES);
// Test if there is actually a NDef message passed via the Intent
if (ndefMessageArray != null) {
NdefMessage ndefMessage = (NdefMessage) ndefMessageArray[0];
//Get Bytes of payload
byte[] payload = ndefMessage.getRecords()[0].getPayload();
// Read First Byte and then trim off the right length
byte[] textArray = Arrays.copyOfRange(payload, (int) payload[0] + 1, payload.length);
// Convert to Text
String text = new String(textArray);
ID = text;
getApiInfos();
}
}
If anyone is facing the same issue in React Native, here's my solution. Here, the react-native-nfc-manager package is used
// register for the NFC tag with NDEF in it
await NfcManager.requestTechnology(NfcTech.Ndef);
// the resolved tag object will contain `ndefMessage` property
const tag = await NfcManager.getTag();
// access the payload
const payload = tag?.ndefMessage[0].payload;
//remove the language code from payload
const subPayload = payload?.slice(3, payload.length);
const decoded = Ndef.util.bytesToString(subPayload);

How to turn off NFC sound

I have a problem with NFC. Is there any posible way to turn off the NFC sound in Android API 16 and higher?
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_traveller_read_tag);
context = this;
tvNFCContent = findViewById(R.id.nfc_contents);
nfcAdapter = NfcAdapter.getDefaultAdapter(this);
if (nfcAdapter == null) {
// Stop here, we definitely need NFC
Toast.makeText(this, "This device doesn't support NFC.", Toast.LENGTH_LONG).show();
finish();
}
readFromIntent(getIntent());
pendingIntent = PendingIntent.getActivity(context, 0, new Intent(context, 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};
findViewById(R.id.menu).setVisibility(View.GONE);
}
private void readFromIntent(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[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
NdefMessage[] msgs = null;
if (rawMsgs != null) {
msgs = new NdefMessage[rawMsgs.length];
for (int i = 0; i < rawMsgs.length; i++) {
msgs[i] = (NdefMessage) rawMsgs[i];
}
}
buildTagViews(msgs);
}
}
private void buildTagViews(NdefMessage[] msgs) {
if (msgs == null || msgs.length == 0) return;
String text = "";
//String tagId = new String(msgs[0].getRecords()[0].getType());
byte[] payload = msgs[0].getRecords()[0].getPayload();
String textEncoding = ((payload[0] & 128) == 0) ? "UTF-8" : "UTF-16"; // Get the Text Encoding
int languageCodeLength = payload[0] & 0063; // Get the Language Code, e.g. "en"
// String languageCode = new String(payload, 1, languageCodeLength, "US-ASCII");
try {
// Get the Text
text = new String(payload, languageCodeLength + 1, payload.length - languageCodeLength - 1, textEncoding);
} catch (UnsupportedEncodingException e) {
Log.e("UnsupportedEncoding", e.toString());
}
int tempCoin = Integer.parseInt( DB.getValue(context, UserValue.KEY_COIN) ) + Integer.parseInt( text );
DB.setValue(context,UserValue.KEY_COIN,String.valueOf(tempCoin));
tvNFCContent.setText("حساب شما " + text +" تومان شارژ شد.");
beep.playBeep(context, beep.TypeBeep.OK);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
finish();
}
},1000);
}
#Override
protected void onNewIntent(Intent intent) {
setIntent(intent);
readFromIntent(intent);
if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction())) {
myTag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
}
}
No, disabling the NFC discovery sound is not possible on Android API level 16. Only the reader-mode API introduced in Android API level 19 allows you to disable the platform sounds normally generated for NFC discovery events:. See NfcAdapter.enableReaderMode and the flag NfcAdapter.FLAG_READER_NO_PLATFORM_SOUNDS.

android studio app case insensitive search from sqlite

I am working on a android application with sqlite database that store lots of standard english texts that have uppercase and lowercase words and it shows on the app, we have a search that right now is case sensitive and scroll between them with cursor
How I can return search string case insensitive from sqlite
this is my code on database
public List<String> getSearchedParagraph(String p) {
String sectionId = "";
List<String> result = new ArrayList<String>();
String query = "SELECT Distinct(sectionId) FROM paragraph where txt Like '%"
+p+ "%'";
Cursor cursor = db.rawQuery(query, null);
if (cursor != null && cursor.getCount() > 0) {
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
result.add(cursor.getString(0));
cursor.moveToNext();
}
}
return result;
}
i tested String query = "SELECT Distinct(sectionId) FROM paragraph where txt Like '%" +p+ "%' COLLATE NOCASE"; but still no change
UPDATE1 this is setWordSearch function:
public void setWordSearch(String str) {
wordSearch = str;
for (FragmentPage page : fragments) {
page.wordSearch = str;
}
notifyDataSetChanged();
}
UPDATE2 This is the FragmentPage:
public class FragmentPage extends Fragment {
VasiatClass v;
public String SectionId;
public List<VasiatClass> paragraph;
public String wordSearch;
private ScrollView sv;
static MediaPlayer player = new MediaPlayer();
View view;
private List<RelativeLayout> jtxtvwList = new ArrayList<RelativeLayout>();
RelativeLayout rl = null;
float position_x = 0, position_y = 0;
private int playingParagraphPosition;
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
this.SectionId = String.valueOf(getArguments().getInt("sectionId"));
this.wordSearch = getArguments().getString("wordSearch");
Log.i("FRAGMENTPAGE",
"sectionId is :"
+ String.valueOf(getArguments().getInt("sectionId")));
DataBaseHelper myDbHelper = new DataBaseHelper(this.getActivity());
myDbHelper = new DataBaseHelper(this.getActivity());
wordSearch = getArguments().getString("wordSearch");
try {
myDbHelper.createDataBase();
myDbHelper.openDataBase();
this.paragraph = myDbHelper.getParagraph(SectionId);
myDbHelper.close();
} catch (IOException ioe) {
throw new Error("Unable to create database");
}
};
public String getSection() {
return SectionId;
}
public FragmentPage() {
// TODO Auto-generated constructor stub
}
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_vasiatpage, container,
false);
this.view = view;
LinearLayout ll = (LinearLayout) view.findViewById(R.id.llId);
ll.setPadding(20, 20, 20, 20);
LinearLayout.LayoutParams linLayoutParam = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.FILL_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
linLayoutParam.setMargins(20, 20, 20, 20);
sv = (ScrollView) view.findViewById(R.id.scrollView1);
for (int i = 0; i <= paragraph.size() - 1; i++) {
final int j = i;
final RelativeLayout rel = new RelativeLayout(getActivity());
// Button b = new Button(getActivity());
// b.setBackgroundColor(Color.TRANSPARENT);
// b.setTextColor(Color.TRANSPARENT);
JustifiedTextView textView = new JustifiedTextView(getActivity());
/************************************/
textView.setOnTouchListener(new OnTouchListener() {
public final static int FINGER_RELEASED = 0;
public final static int FINGER_TOUCHED = 1;
public final static int FINGER_DRAGGING = 2;
public final static int FINGER_UNDEFINED = 3;
private int fingerState = FINGER_RELEASED;
#Override
public boolean onTouch(View arg0, MotionEvent arg1) {
int action = arg1.getAction();
boolean check = true;
switch (action) {
case MotionEvent.ACTION_DOWN:
position_x = arg1.getX();
position_y = arg1.getY();
Log.i("ACTIONS", "Ation down -- position_x:"
+ position_x + " ,position_Y" + position_y);
check = true;
if (fingerState == FINGER_RELEASED)
fingerState = FINGER_TOUCHED;
else
fingerState = FINGER_UNDEFINED;
break;
case MotionEvent.ACTION_MOVE:
if (fingerState == FINGER_TOUCHED
|| fingerState == FINGER_DRAGGING)
fingerState = FINGER_DRAGGING;
else
fingerState = FINGER_UNDEFINED;
check = false;
break;
case MotionEvent.ACTION_UP:
Log.i("ACTIONS",
"Ation up -- position_x:" + arg1.getX()
+ " ,position_Y" + arg1.getY());
if (Math.abs((arg1.getX() - position_x)) < 10
&& Math.abs((arg1.getY() - position_y)) < 10) {
List<String> audioList = new ArrayList<String>();
playingParagraphPosition = j;
((VasiatText) getActivity())
.playParagraph(paragraph.get(j)
.getFilename() + "_MP3.mp3", j,
FragmentPage.this);
if (rl != null) {
rl.setBackgroundColor(Color.TRANSPARENT);
}
rel.setBackgroundColor(Color.LTGRAY);
rl = rel;
}
break;
default:
fingerState = FINGER_UNDEFINED;
break;
}
return false;
}
});
/********************************************/
// textView.getSettings().setFixedFontFamily("Swissra Light.otf");
String str = paragraph.get(i).getTxt().toString();
int subStringStart = 0;
int startIndex = 0;
StringBuilder sb = new StringBuilder();
if (wordSearch != null && !wordSearch.equals("")) {
startIndex = str.indexOf(wordSearch);
while (startIndex != -1) {
sb.append(str.substring(subStringStart, startIndex)
+ "<span style=\"background-color:#ffff00\">"
+ str.substring(startIndex,
startIndex + wordSearch.length())
+ "</span>");
subStringStart = startIndex + wordSearch.length();
startIndex = str.indexOf(wordSearch, subStringStart);
}
sb.append(str.substring(subStringStart));
}
if (!sb.toString().equals("")) {
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
textView.setText(sb.toString());
} else
textView.setTextNoJustify(sb.toString());
// b.setText(sb.toString());
} else {
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
textView.setText(str);
} else
textView.setTextNoJustify(str);
// b.setText(str);
}
textView.setId(i);
textView.setTag(Integer.valueOf(paragraph.get(i).getId()));
rel.addView(textView);
jtxtvwList.add(rel);
ll.addView(rel);
}
return view;
}
thanks
as #CL mentioned, you can use Patterns,
just replace this code:
if (wordSearch != null && !wordSearch.equals("")) {
startIndex = str.indexOf(wordSearch);
while (startIndex != -1) {
sb.append(str.substring(subStringStart, startIndex)
+ "<span style=\"background-color:#ffff00\">"
+ str.substring(startIndex,
startIndex + wordSearch.length())
+ "</span>");
subStringStart = startIndex + wordSearch.length();
startIndex = str.indexOf(wordSearch, subStringStart);
}
sb.append(str.substring(subStringStart));
}
whit this:
Boolean wasFound;
if (wordSearch != null && !wordSearch.equals("")) {
Matcher subMatcher = Pattern.compile(Pattern.quote(wordSearch), Pattern.CASE_INSENSITIVE).matcher(str);
wasFound = subMatcher.find();
while (wasFound) {
startIndex = subMatcher.start();
sb.append(str.substring(subStringStart, startIndex)
+ "<span style=\"background-color:#ffff00\">"
+ str.substring(startIndex,
startIndex + wordSearch.length())
+ "</span>");
subStringStart = startIndex + wordSearch.length();
wasFound = subMatcher.find();
}
sb.append(str.substring(subStringStart));
}
I hope that this help you #n3tg33k ;)
You are using String.indexOf for searching. This function is case sensitive.
You need to search for the substring while ignoring case.
you can achieve it in this way....
public List<String> getSearchedParagraph(String p) {
p=p.toLowerCase();
String sectionId = "";
List<String> result = new ArrayList<String>();
String query = "SELECT Distinct(sectionId) FROM paragraph where LOWER(txt) Like '%"
+p+ "%'";
Cursor cursor = db.rawQuery(query, null);
if (cursor != null && cursor.getCount() > 0) {
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
result.add(cursor.getString(0));
cursor.moveToNext();
}
}
return result;
}

How to use getExtras from an intent in Android?

I'm new Android and I don't know how to solve this problem: I'm using an intent in the onCreate in order to read NFC tags, and I'm trying to use the text read from the tag.
I manage for the moment to read the tag, and display this text, but only in the method "resolveIntent" (the TextView "tvResponse" shows correctly my data in "resolveIntent", but everywhere else is empty). My problem is I need to use this value in my onCreate method, and I don't know how to get it out from resolveIntent.
Can anybody help me? Thanks a lot!
Here is the corresponding section in my onCreate:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_nfcpositioning_main);
mTagContent = (LinearLayout) findViewById(R.id.list);
tvResponse = (TextView) findViewById(R.id.tvResponse);
//TAGS READING
resolveIntent(getIntent());
mDialog = new AlertDialog.Builder(this).setNeutralButton("Ok", null).create();
mAdapter = NfcAdapter.getDefaultAdapter(this);
if (mAdapter == null) {
showMessage(R.string.error, R.string.no_nfc);
finish();
return;
}
mPendingIntent = PendingIntent.getActivity(this, 0,
new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
mNdefPushMessage = new NdefMessage(new NdefRecord[] { newTextRecord(
"Message from NFC Reader :-)", Locale.ENGLISH, true) });
tvResponse.setText(getIntent().getStringExtra("MSG"));
and the void "resolveIntent" which is also in the main activity:
public void resolveIntent(Intent Xintent) {
String action = Xintent.getAction();
if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(action)
|| NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)
|| NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) {
Parcelable[] rawMsgs = Xintent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
NdefMessage[] msgs;
if (rawMsgs != null) {
msgs = new NdefMessage[rawMsgs.length];
for (int i = 0; i < rawMsgs.length; i++) {
msgs[i] = (NdefMessage) rawMsgs[i];
}
NdefMessage msg = msgs[0];
byte[] payload = msg.getRecords()[0].getPayload();
String result="";
for (int b = 3; b<payload.length; b++) {
result += (char) payload[b];
}
String StringNdefMessagePart = result;
//tvResponse.setText(StringNdefMessagePart);
Xintent.putExtra("MSG", StringNdefMessagePart);
} else {
Toast.makeText(this, "Empty NFC tag", Toast.LENGTH_LONG).show();
}
}
}
I leave an example of a personal code, I hope it helps you
Intent i = new Intent(this,DetalleEventoActivity.class);
Bundle b = new Bundle();
b.putLong("IDEV", e.getId());
b.putLong("FECHA", e.getFecha());
b.putString("NOMBRE_EVENTO", e.getNombreEvento());
b.putString("NUMERO_MAQUINA", e.getNroMaquinaDGC());
b.putString("SECTOR", e.getSector());
b.putString("SOCIO", e.getNroSocio());
b.putString("CATEGORIA", e.getCategoriaSocio());
i.putExtras(b);
startActivity(i);
---IN DetalleEventoActivity-------------------------------------------
Bundle bundle = this.getIntent().getExtras();
id = bundle.getLong("IDEV");
fechaLong = bundle.getLong("FECHA");
fecha = formatter.format(fechaLong);
nombreEvento = bundle.getString("NOMBRE_EVENTO");
nroMaquina = bundle.getString("NUMERO_MAQUINA");
sector = bundle.getString("SECTOR");
socio = bundle.getString("SOCIO");
categoria = bundle.getString("CATEGORIA");

Android Read/Write to Multiple Records NDEF NFC

I'm trying to write and read to/from multiple records in a NDEFMessage. Is my code here right? Also, my process terminates itself when I'm reading the tag. I'm not sure where I went wrong..
Writing part:
private NdefMessage getTagAsNdef() {
String text123="Hello";
//boolean addAAR = true;
String uniqueId = "starbucks.com";
byte[] uriField = uniqueId.getBytes(Charset.forName("US-ASCII"));
byte[] payload = new byte[uriField.length + 1]; //add 1 for the URI Prefix
payload[0] = 0x01; //prefixes http://www. to the URI
System.arraycopy(uriField, 0, payload, 1, uriField.length); //appends URI to payload
NdefRecord rtdUriRecord = new NdefRecord(
NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_URI, new byte[0], payload);
//Wi-FI test writing code
byte[] textbytes = text123.getBytes();
NdefRecord textRecord = new NdefRecord(NdefRecord.TNF_WELL_KNOWN,
text123.getBytes(), new byte[]{}, textbytes);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
// note: returns AAR for different app (couponmanager)
return new NdefMessage(new NdefRecord[] {
rtdUriRecord, textRecord, NdefRecord.createApplicationRecord("com.example.ponpon")
});
} else {
return new NdefMessage(new NdefRecord[] {
rtdUriRecord,textRecord});
}
}
Reading part:
#Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
SharedPreferences preferences = getSharedPreferences(PREF_FILE_NAME, MODE_PRIVATE);
int storedPreference = preferences.getInt("storedInt", 0);
if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction())) {
NdefMessage[] messages = null;
Parcelable[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
if (rawMsgs != null) {
messages = new NdefMessage[rawMsgs.length];
for (int i = 0; i < rawMsgs.length; i++) {
messages[i] = (NdefMessage) rawMsgs[i];
}
}
if(messages[0] != null) {
String result="";
byte[] payload = messages[0].getRecords()[0].getPayload();
// this assumes that we get back am SOH followed by host/code
for (int b = 1; b<payload.length; b++) { // skip SOH
result += (char) payload[b];
}
//grabbing 2nd payload
String result2="";
byte[] payload2 = messages[0].getRecords()[1].getPayload();
for (int test = 1; test<payload2.length; test++) { // skip SOH
result2 += (char) payload2[test];
Toast.makeText(this,result2,Toast.LENGTH_SHORT).show();
}
You're skipping the first byte i.e. the H.
In the first record you're pre-pending a byte which you correctly skip when reading.
As for speed I thats just the OS buffering the toasts

Categories

Resources