Android.How to send SMS without SIM card? - android

I have a device with Android 4.4 in a board but it doesn't have a SIM card module.
Please, tell me , how i can emulate incoming SMS from my application?
I just wanna see standart notification aboute incoming sms.
I tried this example:
enter code here
private static void createFakeSms(Context context, String sender,
String body) {
byte[] pdu = null;
byte[] scBytes =PhoneNumberUtils.networkPortionToCalledPartyBCD("0000000000");
byte[] senderBytes = PhoneNumberUtils.networkPortionToCalledPartyBCD(sender);
int lsmcs = scBytes.length;
byte[] dateBytes = new byte[7];
Calendar calendar = new GregorianCalendar();
dateBytes[0] = reverseByte((byte) (calendar.get(Calendar.YEAR)));
dateBytes[1] = reverseByte((byte) (calendar.get(Calendar.MONTH) + 1));
dateBytes[2] = reverseByte((byte) (calendar.get(Calendar.DAY_OF_MONTH)));
dateBytes[3] = reverseByte((byte) (calendar.get(Calendar.HOUR_OF_DAY)));
dateBytes[4] = reverseByte((byte) (calendar.get(Calendar.MINUTE)));
dateBytes[5] = reverseByte((byte) (calendar.get(Calendar.SECOND)));
dateBytes[6] = reverseByte((byte) ((calendar.get(Calendar.ZONE_OFFSET) + calendar
.get(Calendar.DST_OFFSET)) / (60 * 1000 * 15)));
try {
ByteArrayOutputStream bo = new ByteArrayOutputStream();
bo.write(lsmcs);
bo.write(scBytes,0,scBytes.length);
bo.write(0x04);
bo.write((byte) sender.length());
bo.write(senderBytes,0,senderBytes.length);
bo.write(0x00);
bo.write(0x00); // encoding: 0 for default 7bit
bo.write(dateBytes,0,dateBytes.length);
try {
String sReflectedClassName = "com.android.internal.telephony.GsmAlphabet";
Class cReflectedNFCExtras = Class.forName(sReflectedClassName);
Method stringToGsm7BitPacked = cReflectedNFCExtras.getMethod(
"stringToGsm7BitPacked", new Class[] { String.class });
stringToGsm7BitPacked.setAccessible(true);
byte[] bodybytes = (byte[]) stringToGsm7BitPacked.invoke(null,
body);
bo.write(bodybytes);
} catch (Exception e) {
}
pdu = bo.toByteArray();
}finally {
}
Intent intent = new Intent();
intent.setClassName("com.android.mms",
"com.android.mms.transaction.SmsReceiverService");
intent.setAction("android.provider.Telephony.SMS_RECEIVED");
intent.putExtra("pdus", new Object[] { pdu });
intent.putExtra("format", "3gpp");
context.startService(intent);
}
private static byte reverseByte(byte b) {
return (byte) ((b & 0xF0) >> 4 | (b & 0x0F) << 4);
}
But when i call this function my application is crashed.
Please help me.

Related

Start VPN Connection

I want to develop an App for some internal Company stuff. However this needs VPN connection with a .p12 certificate.
Is there a way, that I can open a VPN connection in the App with this certificate? Or maybe an easier possibility automatically open the VPN App and connect to the chosen VPN.
Yes you can do by following:
Intent intent = VpnService.prepare(StatePermissionActivity.this);
if (intent != null) {
startActivityForResult(intent, 0);
}
Make a VPN Service:
public class UtilityVpnService extends VpnService {
//https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/net/VpnService.java
// http://stackoverflow.com/questions/32173374/packet-sent-but-cannot-received-packets
Builder builder;
private ParcelFileDescriptor mInterface;
private Thread mThread;
private IBinder mBinder = new MyBinder();
public static String VPN_STATE = "VPN_STATE";
public static int VPN_SERVICE_STOPPED = 1;
public static int VPN_SERVICE_STARTED = 2;
public static int VPN_SERVICE_RESUMED = 3;
public static int BLOCK_SINGLE_APP = 4;
public static int ALLOW_SINGLE_APP = 5;
public static int PACKAGE_NAME = 6;
public UtilityVpnService() {
}
#Override
public void onCreate() {
Context context = this;
Notification notification;
Intent notificationIntent = new Intent();
notificationIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
notificationIntent, 0);
NotificationCompat.Builder bBuilder = new NotificationCompat.Builder(context);
Intent vpnIntent = new Intent(context, UtilityVpnService.class);
context.startService(vpnIntent);
notification = bBuilder.build();
notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
notification.flags |= Notification.FLAG_NO_CLEAR;
notification.flags |= Notification.FLAG_ONGOING_EVENT;
startForeground(54312, notification);
super.onCreate();
}
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
#Override
public void onRebind(Intent intent) {
super.onRebind(intent);
}
#Override
public boolean onUnbind(Intent intent) {
return true;
}
public class MyBinder extends Binder {
public UtilityVpnService getService() {
return UtilityVpnService.this;
}
}
public void closeVpnInterface() {
try {
if (mInterface != null) {
mInterface.close();
}
} catch (Exception ex) {
ex.printStackTrace();
}
stopSelf();
}
#Override
public void onTaskRemoved(Intent rootIntent) {
Intent restartService = new Intent(getApplicationContext(), this.getClass());
restartService.setPackage(getPackageName());
PendingIntent restartServicePI = PendingIntent.getService(getApplicationContext(), 1, restartService,
PendingIntent.FLAG_ONE_SHOT);
//Restart the service once it has been killed android
AlarmManager alarmService = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
alarmService.set(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + 100, restartServicePI);
alarmService.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 1000, restartServicePI);
}
#Override
public void onTrimMemory(int level) {
super.onTrimMemory(level);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Context context = this;
initilizeVpnBuilder();
if (!CheckServiceIsRunning.isMyServiceRunning(RunningAppsIdentify.class, this)) {
Intent vpnIntent = new Intent(context, RunningAppsIdentify.class);
context.startService(vpnIntent);
}
return START_STICKY;
}
private void initilizeVpnBuilder() {
mThread = new Thread(new Thread() {
#Override
public void run() {
try {
// try {
// if (builder != null) {
// mInterface.close();
// }
// } catch (Exception ex) {
// ex.printStackTrace();
// }
// Configure the tunnel and get the interface.
// Build VPN service
builder = new Builder();
builder.setSession(getString(R.string.app_name));
// VPN address
builder.addAddress("10.1.10.1", 32);
builder.addAddress("fd00:1:fd00:1:fd00:1:fd00:1", 128);
// DNS address
builder.addDnsServer("8.8.8.8");
// Add Route
builder.addRoute("0.0.0.0", 0);
builder.addRoute("0:0:0:0:0:0:0:0", 0);
//Setting Applications which are allowed Internet
// and isInternetAllowed = True
List<AppsModel> list = AppsModel.getAppsAllowedForInternet();
for (int i = 0; i < list.size(); i++) {
builder.addDisallowedApplication(list.get(i).getAppPackage());
}
//Establish interface
mInterface = builder.establish();
// Add list of allowed applications
// Packets to be sent are queued in this input stream.
FileInputStream inputStream = new FileInputStream(mInterface.getFileDescriptor());
// Packets recieved need to be written to this output stream.
FileOutputStream outputStream = new FileOutputStream(mInterface.getFileDescriptor());
DatagramChannel tunnel = DatagramChannel.open();
tunnel.connect(new InetSocketAddress("127.0.0.1", 8087));
protect(tunnel.socket());
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
reader.mark(123);
reader.markSupported();
ByteBuffer packet = ByteBuffer.allocate(32767);
//byte[] bytes = extract(inputStream);
//byteBuffer.put(bytes,0,bytes.length);
// We keep forwarding packets till something goes wrong.
while (true) {
// Assume that we did not make any progress in this iteration.
try {
//Utils.getWifiSpeed(UtilityVpnService.this);
// Read the outgoing packet from the input stream.
int length = inputStream.read(packet.array());
if (length > 0) {
//Log.d("packet received", "" + length);
packet.limit(length);
tunnel.write(packet);
// Getting info about the packet..
//debugPacket(packet);
packet.clear();
// reading incoming packet from tunnel.
length = tunnel.read(packet);
if (length > 0) {
outputStream.write(packet.array());
packet.clear();
}
}
} catch (IOException ex) {
ex.printStackTrace();
}
// String line = reader.readLine();
// if (line != null)
// Log.d("line", "" + line);
// Instructions
//get packet with in
//put packet to tunnel
//get packet from tunnel
// return packet with out
Thread.sleep(100);
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
});
mThread.start();
}
#Override
public void onRevoke() {
super.onRevoke();
stopSelf();
}
private void debugPacket(ByteBuffer packet) {
int buffer = packet.get();
int version;
int headerlength;
version = buffer >> 4;
headerlength = buffer & 0x0F;
headerlength *= 4;
Log.d("Tag", "IP Version:" + version);
Log.d("Tag", "Header Length:" + headerlength);
String status = "";
status += "Header Length:" + headerlength;
buffer = packet.get(); //DSCP + EN
buffer = packet.getChar(); //Total Length
Log.d("Tag", "Total Length:" + buffer);
buffer = packet.getChar(); //Identification
buffer = packet.getChar(); //Flags + Fragment Offset
buffer = packet.get(); //Time to Live
buffer = packet.get(); //Protocol
Log.d("Tag", "Protocol:" + buffer);
status += " Protocol:" + buffer;
buffer = packet.getChar(); //Header checksum
String sourceIP = "";
buffer = packet.get(); //Source IP 1st Octet
sourceIP += ((int) buffer) & 0xFF;
sourceIP += ".";
buffer = packet.get(); //Source IP 2nd Octet
sourceIP += ((int) buffer) & 0xFF;
sourceIP += ".";
buffer = packet.get(); //Source IP 3rd Octet
sourceIP += ((int) buffer) & 0xFF;
sourceIP += ".";
buffer = packet.get(); //Source IP 4th Octet
sourceIP += ((int) buffer) & 0xFF;
Log.d("Tag", "Source IP:" + sourceIP);
status += " Source IP:" + sourceIP;
String destIP = "";
buffer = packet.get(); //Destination IP 1st Octet
destIP += ((int) buffer) & 0xFF;
destIP += ".";
buffer = packet.get(); //Destination IP 2nd Octet
destIP += ((int) buffer) & 0xFF;
destIP += ".";
buffer = packet.get(); //Destination IP 3rd Octet
destIP += ((int) buffer) & 0xFF;
destIP += ".";
buffer = packet.get(); //Destination IP 4th Octet
destIP += ((int) buffer) & 0xFF;
Log.d("Tag", "Destination IP:" + destIP);
status += " Destination IP:" + destIP;
try {
InetAddress addr = InetAddress.getByName(destIP);
String host = addr.getHostName();
Log.d("Tag", "Hostname:" + host);
} catch (UnknownHostException e) {
Log.d("Tag", "Unknown host");
}
}
#Override
public void onDestroy() {
if (mThread != null) {
mThread.interrupt();
}
super.onDestroy();
}
}
startService on onActivityResult()

I'm getting a tag lost exception when I try writing to an NFC tag

I hope someone can tell me what I'm missing here. Maybe it's my approach to connecting. My Tag, is in fact a Mifare Ultralight so I'm not getting things wrong there. I debugged, connecting to the tag was successful - everything seemed fine. But the log keeps on saying:
android.nfc.TagLostException: Tag was lost.
public class MainActivity extends Activity {
NfcAdapter mNfcAdapter;
TextView displayInfo;
Tag mNfcTag;
NdefMessage mNdefMessage;
IntentFilter [] intentFiltersArray;
String [] [] techListsArray;
PendingIntent pendingIntent;
String TAG = "MainActivity";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
displayInfo = (TextView) findViewById(R.id.displayInfo);
NdefRecord application = NdefRecord.createApplicationRecord("com.studios.nfcdemo");
Locale locale = new Locale("en");
NdefRecord textText = createTextRecord("pleaseWork", locale, true);
mNdefMessage = new NdefMessage(textText);
pendingIntent = PendingIntent.getActivity(
this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
IntentFilter ndef = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
try {
ndef.addDataType("*/*"); /* Handles all MIME based dispatches.
You should specify only the ones that you need. */
}
catch (IntentFilter.MalformedMimeTypeException e) {
throw new RuntimeException("fail", e);
}
intentFiltersArray = new IntentFilter[] {ndef};
techListsArray = new String[][] { new String[] { MifareUltralight.class.getName() } };
}
public NdefRecord createTextRecord(String payload, 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 = payload.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);
NdefRecord record = new NdefRecord(NdefRecord.TNF_WELL_KNOWN,
NdefRecord.RTD_TEXT, new byte[0], data);
return record;
}
#Override
public void onNewIntent(Intent intent) {
Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
MifareUltralight ultralight = MifareUltralight.get(tagFromIntent);
write(ultralight);
}
private void write(MifareUltralight lol) {
try{
lol.connect();
lol.writePage(0, "please work".getBytes(Charset.forName("US-ASCII")));
Toast.makeText(this, "Tag written", Toast.LENGTH_LONG).show();
}
catch (Exception e){
Log.d(TAG, "no " + e.toString());
}
finally{
try{
lol.close();
}
catch (Exception e){
Log.d(TAG, e.toString());
}
}
}
public void onPause() {
super.onPause();
mNfcAdapter.disableForegroundDispatch(this);
}
public void onResume() {
super.onResume();
mNfcAdapter.enableForegroundDispatch(this, pendingIntent, intentFiltersArray, techListsArray);
}
}
I found my error. I wanted to write Ndef messages and using the tag as MifareUltralight was a little silly as it just complicates everything. Instead, I cast the tag as an Ndef. Here's me code:
private void write(Tag tag) {
Ndef ndef = Ndef.get(tag);
Locale locale = Locale.ENGLISH;
NdefRecord hi = createTextRecord("hello world", locale, true);
mNdefMessage = new NdefMessage(hi);
try{
ndef.connect();
ndef.writeNdefMessage(mNdefMessage);
Toast.makeText(this, "Message Written", Toast.LENGTH_LONG).show();
}
catch (Exception e){
Log.d(TAG, "Exception: " + e.toString());
}
finally {
try{
ndef.close();
}
catch(Exception e){
Log.d(TAG, ":( no " + e.toString());
}
}
}
In case anyone needs to figure out how to create text records (encoded in UTF 8) and read from Ndef supported tags, I have added my methods for those as well:
Creating text records:
public NdefRecord createTextRecord(String payload, 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 = payload.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);
NdefRecord record = new NdefRecord(NdefRecord.TNF_WELL_KNOWN,
NdefRecord.RTD_TEXT, new byte[0], data);
return record;
}
Reading NDEF tags:
private void read(Tag tagFromIntent) {
Ndef ndef = Ndef.get(tagFromIntent);
try{
ndef.connect();
mNdefMessage = ndef.getNdefMessage();
NdefRecord [] records = mNdefMessage.getRecords();
byte [] payload = records[0].getPayload();
String displayString = getTextFromNdefRecord(records[0]);
displayInfo.setText(displayString);
Toast.makeText(this, "String read", Toast.LENGTH_LONG).show();
}
catch (Exception e){
Log.d(TAG, e.toString());
}
finally {
try{
ndef.close();
}
catch (Exception e){
Log.d(TAG, e.toString());
}
}
reading text from NdefRecords:
public String getTextFromNdefRecord(NdefRecord ndefRecord)
{
String tagContent = null;
try {
byte[] payload = ndefRecord.getPayload();
String textEncoding = "UTF-8";
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;
}
I hope this helps anyone else working with NFC. These simple methods should give you all the functionality you need within Android.
There are two problems with your call to the writePage() method:
Page 0 of MIFARE Ultralight tags is read-only. You cannot write to that page. The same applies to page 1 and parts of page 2 (though write commands for page two should succeed and will set the lock bits).
The write command takes 4 bytes (exactly 4 bytes, not more and not less) but you try to pass 11 bytes ("please work" in US-ASCII).

How solve "android.nfc.TagLostException: Tag was lost." ?(Select PICC app)

I am facing an issue with a Mifare DESFire card.
I usetransceive() method to send apdu for selection the PICC app, The flow of the application is:
1) Tech Discovered
2) Create MifareDESFire object using
intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
3) Called connect();
4) Send the select PICC app apdu command using transceive();
5) Received a "android.nfc.TagLostException: Tag was lost." when I send
apdu. I specify the line maked above error by an '****'
Here is my onNewIntent event:
public void onNewIntent(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)) {
Toast.makeText(this, "discovered", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "Falied", Toast.LENGTH_SHORT).show();
}
byte cmdSelect_PICCapp=(byte) 0x5A ; //select my app
byte[] PICCAPPID = new byte[]{(byte)0x00 ,(byte)0x00 , (byte)0x00};
byte[] tagResponse_cmdSelect_PICC_app = new byte[]{(byte)0x12 ,(byte)0x12};
Tag desfire = (Tag) intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
isodep = IsoDep.get(desfire);
try
{
isodep.connect();
} catch (IOException e)
{
e.printStackTrace();
}
**** tagResponse_cmdSelect_PICC_app = isodep.transceive(Utils.wrapMessage(cmdSelect_PICCapp, PICCAPPID));
Log.d("picc app selected", "111 "+Utils.bytesToHex(tagResponse_cmdSelect_PICC_app));
try
{
isodep.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
And
Class Utils is here:
public class Utils {
final protected static char[] hexArray = "0123456789ABCDEF".toCharArray();
public static byte[] wrapMessage (byte command, byte[] parameters) throws Exception {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
stream.write((byte) 0x90);
stream.write(command);
stream.write((byte) 0x00);
stream.write((byte) 0x00);
if (parameters != null) {
stream.write((byte) parameters.length);
stream.write(parameters);
}
stream.write((byte) 0x00);
byte[] b = stream.toByteArray();
return b;
}
//**************************************
public static String bytesToHex(byte[] bytes)
{
char[] hexChars = new char[bytes.length * 2];
for ( int j = 0; j < bytes.length; j++ )
{
int v = bytes[j] & 0xFF;
hexChars[j * 2] = hexArray[v >>> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
}
return new String(hexChars);
}
}//end class Utils
Appreciate it anyone can help me.
Thank you.

can I send “SMS received intent” in android 4.1.2?

This code doesn't work with android version 4.1.2,
private static void createFakeSms(Context context, String sender,String body)
{
byte[] pdu = null;
byte[] scBytes = PhoneNumberUtils.networkPortionToCalledPartyBCD("0000000000");
byte[] senderBytes = PhoneNumberUtils.networkPortionToCalledPartyBCD(sender);
int lsmcs = scBytes.length;
byte[] dateBytes = new byte[7];
Calendar calendar = new GregorianCalendar();
dateBytes[0] = reverseByte((byte) (calendar.get(Calendar.YEAR)));
dateBytes[1] = reverseByte((byte) (calendar.get(Calendar.MONTH) + 1));
dateBytes[2] = reverseByte((byte) (calendar.get(Calendar.DAY_OF_MONTH)));
dateBytes[3] = reverseByte((byte) (calendar.get(Calendar.HOUR_OF_DAY)));
dateBytes[4] = reverseByte((byte) (calendar.get(Calendar.MINUTE)));
dateBytes[5] = reverseByte((byte) (calendar.get(Calendar.SECOND)));
dateBytes[6] = reverseByte((byte) ((calendar.get(Calendar.ZONE_OFFSET) + calendar
.get(Calendar.DST_OFFSET)) / (60 * 1000 * 15)));
try
{
ByteArrayOutputStream bo = new ByteArrayOutputStream();
bo.write(lsmcs);
bo.write(scBytes);
bo.write(0x04);
bo.write((byte) sender.length());
bo.write(senderBytes);
bo.write(0x00);
bo.write(0x00); // encoding: 0 for default 7bit
bo.write(dateBytes);
try
{
String sReflectedClassName = "com.android.internal.telephony.GsmAlphabet";
Class cReflectedNFCExtras = Class.forName(sReflectedClassName);
Method stringToGsm7BitPacked = cReflectedNFCExtras.getMethod(
"stringToGsm7BitPacked", new Class[] { String.class });
stringToGsm7BitPacked.setAccessible(true);
byte[] bodybytes = (byte[]) stringToGsm7BitPacked.invoke(null,body);
bo.write(bodybytes);
}
catch (Exception e)
{
}
pdu = bo.toByteArray();
}
catch (IOException e)
{
}
Intent intent = new Intent();
intent.setClassName("com.android.mms",
"com.android.mms.transaction.SmsReceiverService");
intent.setAction("android.provider.Telephony.SMS_RECEIVED");
intent.putExtra("pdus", new Object[] { pdu });
intent.putExtra("format", "3gpp");
context.startService(intent);
}
private static byte reverseByte(byte b) {
return (byte) ((b & 0xF0) >> 4 | (b & 0x0F) << 4);
}
When I call context.startService(intent) I am getting this exception
java.lang.SecurityException: Not allowed to start service Intent { act=android.provider.Telephony.SMS_RECEIVED cmp=com.android.mms/.transaction.SmsReceiverService (has extras) } without permission not exported from uid 10046**
on virtual device 4.1.2 it works perfectly but not in my GS2 device.
Can anyone help me?
In newer versions of Android this is a protected broadcast which can only be sent by system apps for security reasons.
The only way to get your app to send it is to convince the OEM to make it a system app on their ROM

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