I would like to send data (string) via USB communication from my Android application to a device. I am beginner in Android development, so I followed this tutorial: http://developer.android.com/guide/topics/connectivity/usb/host.html
Somehow the part Communicating with a device doesn't work, doesn't send any text to the device. I tried to send data also with
connection.controlTransfer(0x40, 0x03, 0x2580, 0, null, 0, 0);
or with
ByteBuffer buffer = ByteBuffer.allocate(bytes.length+1);
UsbRequest request = new UsbRequest();
buffer.put(bytes);
request.initialize(connection, epOut);
request.queue(buffer, bytes.length);
but nothing worked.
I don't really understand, how could I send a short text for example "#V" to the device from my android app.
Could you please help me find the problem in my code? Thanks in advance.
Here is my MainActivity class:
public class MainActivity extends AppCompatActivity {
UsbDevice device;
Button bShow;
private static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";
UsbManager mUsbManager;
PendingIntent mPermissionIntent;
Boolean isDevice = true;
TextView tvTest;
String sendText = "#V";
private byte[] bytes;
private static int TIMEOUT = 0;
private boolean forceClaim = true;
int controlTransferResult;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvTest = (TextView) findViewById(R.id.textView);
showData();
}
public void showData(){
bShow= (Button)findViewById(R.id.button);
UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE);
HashMap<String, UsbDevice> deviceList = manager.getDeviceList();
Log.e("MainActivity", "DeviceList:" + deviceList.toString());
if(deviceList.toString().equals("{}")){
Toast.makeText(MainActivity.this,"No USB device found!", Toast.LENGTH_SHORT).show();
return;
}else{
tvTest.setText(deviceList.toString());
}
Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
//while(deviceIterator.hasNext()) {
device = deviceIterator.next();
//}
mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
registerReceiver(mUsbReceiver, filter);
mUsbManager.requestPermission(device, mPermissionIntent);
bShow.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(MainActivity.this, device.getDeviceName() + "\n"
+ device.getManufacturerName() + "\n"
+ device.getProductName() + "\n"
+ device.getVendorId() + "\n"
+ device.getDeviceId() + "\n"
+ "i=" + controlTransferResult, Toast.LENGTH_SHORT).show();
}
});
}
private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (ACTION_USB_PERMISSION.equals(action)) {
synchronized (this) {
UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
if(device != null){
//call method to set up device communication
UsbInterface intf = device.getInterface(0);
UsbEndpoint epOut = null;
UsbEndpoint epIn = null;
// look for our bulk endpoints
for (int i = 0; i < intf.getEndpointCount(); i++) {
UsbEndpoint ep = intf.getEndpoint(i);
//Log.d(TAG, "EP " + i + ": " + ep.getType());
if (ep.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) {
if (ep.getDirection() == UsbConstants.USB_DIR_OUT) {
epOut = ep;
} else if (ep.getDirection() == UsbConstants.USB_DIR_IN) {
epIn = ep;
}
}
}
if (epOut == null || epIn == null) {
throw new IllegalArgumentException("Not all endpoints found.");
}
//UsbEndpoint endpoint = intf.getEndpoint(1);
UsbDeviceConnection connection = mUsbManager.openDevice(device);
connection.claimInterface(intf, forceClaim);
bytes = sendText.getBytes();
controlTransferResult = connection.controlTransfer(0x40, 0x03, 0x2580, 0, null, 0, 0);//baudrate 9600
//int res = connection.bulkTransfer(epOut, bytes, bytes.length, TIMEOUT); //do in another thread
ByteBuffer buffer = ByteBuffer.allocate(bytes.length+1);
UsbRequest request = new UsbRequest();
buffer.put(bytes);
request.initialize(connection, epOut);
request.queue(buffer, bytes.length);
}
}
else {
Log.d("MyActivity", "permission denied for device " + device);
}
}
}
}
};
}
You need to prepare drivers for your Android device first, for example, if your device is using CP210X chipset for USB support you should follow these steps: https://www.silabs.com/documents/public/application-notes/AN809.pdf
Related
I am doing an application that can read nfc and then treat the content message but I only want certain people to be able to read the tag. So in a way I would like the user to scan the tag and be prompted for a password before being able to read the tag. Is this possible ?
Open to any ideas. It is also possible to keep only the read mode and change the write mode to kind of writing password on the tag to secure it.
btnWrite.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v) {
try {
if(myTag ==null) {
Toast.makeText(context, ERROR_DETECTED, Toast.LENGTH_LONG).show();
} else {
write(message.getText().toString(), myTag);
Toast.makeText(context, WRITE_SUCCESS, Toast.LENGTH_LONG ).show();
}
} catch (IOException e) {
Toast.makeText(context, WRITE_ERROR, Toast.LENGTH_LONG ).show();
e.printStackTrace();
} catch (FormatException e) {
Toast.makeText(context, WRITE_ERROR, Toast.LENGTH_LONG ).show();
e.printStackTrace();
}
}
});
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(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 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());
}
tvNFCContent.setText(text+"\n( taille de la trame: " + text.length () +")");
}
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) {
setIntent(intent);
readFromIntent(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;
nfcAdapter.enableForegroundDispatch(this, pendingIntent, writeTagFilters, null);
}
private void WriteModeOff(){
writeMode = false;
nfcAdapter.disableForegroundDispatch(this);
}
}
You can have the password implementation either in the readFromIntent replacing the buildTagViews(msgs); with checkPasswordDialog(msgs)
private void readFromIntent(Intent intent) {
.....
.... checkPasswordDialog(msgs)
...
In the checkPasswordDialog(NdefMessage[] msgs), you check the password, if it is correct,then continue with buildTagViews(msgs); else, show error.
Or in the buildTagViews(msgs); itself, right before you display the message, the password then determines what you will display, the NFC message or an error( non-authorized user).
Assume I write a function called checkForPasswordDailog() thats asks a user for a password. If the password entered by user is correct then continue to display the messege otherwise display and unauthorised user messege. i.e
protected void checkForPasswordDialog(NdefMessage[] msgs){
/*create a dialog view with either both usename
and password or just a password if every user uses the same
password*/
MaterialDialog(this).show{
// add a title
View passwordDialogView = customView(R.layout.password_dialog_view)
//when the user submits their inputs
Textview userNameView = passwordDialogView.findViewById(R.id.username)
Textview passwordView = passwordDialogView.findViewById(R.id.password)
Button submitButton = passwordDialogView.findViewById(R.id.submit_button)
submitButton.setOnClickListener{
if(verifyUser(username.text, password.text)){
buildTagViews(msgs)
cancel()
}else{
showUnauthorizedUserError()
cancel()
}
}
}
protected boolean verifyUser(String username, String password){
//Verify user input
}
protected void showUnauthorizedUseError(){
//Display your message here Snackbar/Dialog e.t.c
}
And your xml file should include
<TextView id = "#+id/username"/>
<TextView id = "#+id/password"/>
<Button id = "#+id/submit_button"/>
Hopefully this helps
I have an simple sender/receiver android app based on bluetooth. Connection between two phone is succesfully created. But data is not sending and receiving.
Code what I tried :
public class MainActivity extends Activity
{
TextView myLabel;
EditText myTextbox;
BluetoothAdapter mBluetoothAdapter;
BluetoothSocket mmSocket;
BluetoothDevice mmDevice;
OutputStream mmOutputStream;
InputStream mmInputStream;
Thread workerThread;
byte[] readBuffer;
int readBufferPosition;
volatile boolean stopWorker;
void findBT()
{
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if(mBluetoothAdapter == null)
{
myLabel.setText("No bluetooth adapter available");
}
if(!mBluetoothAdapter.isEnabled())
{
Intent enableBluetooth = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBluetooth, 0);
}
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
if(pairedDevices.size() > 0)
{
for(BluetoothDevice device : pairedDevices)
{
String deviceName = device.getName();
deviceName=deviceName.replaceAll("[^A-Za-z]+", "");
//String deviceHardwareAddress = device.getAddress(); // MAC address
Log.i("## name : ",deviceName+" ");
if(deviceName.equals("GalaxyTabAwithSPen")) {
mmDevice = device;
break;
}
}
}
// tel GalaxyTabAwithSPen
// tablet GhhBbbGalaxyS
}
void openBT()
{
if(mmDevice==null)
Log.i("test","notnull");
ParcelUuid list[] = mmDevice.getUuids();
for(ParcelUuid x: list){
System.out.println(x.toString());
}
Log.i("size :"+list.length," "+list[1].toString());
UUID uuid = UUID.fromString(list[1].toString()); //Standard SerialPortService ID
//UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
try {
mmSocket = mmDevice.createRfcommSocketToServiceRecord(uuid);
mmSocket.connect();
mmOutputStream = mmSocket.getOutputStream();
mmInputStream = mmSocket.getInputStream();
beginListenForData();
myLabel.setText("Bluetooth Opened");
}
catch (Exception ex){
Log.i("IO ex : ", ex.getMessage());
}
}
void beginListenForData()
{
final Handler handler = new Handler();
final byte delimiter = 10; //This is the ASCII code for a newline character
stopWorker = false;
readBufferPosition = 0;
readBuffer = new byte[1024];
workerThread = new Thread(new Runnable()
{
public void run()
{
while(!Thread.currentThread().isInterrupted() && !stopWorker)
{
try
{
int bytesAvailable = mmInputStream.available();
if(bytesAvailable > 0)
{
byte[] packetBytes = new byte[bytesAvailable];
mmInputStream.read(packetBytes);
for(int i=0;i<bytesAvailable;i++)
{
byte b = packetBytes[i];
if(b == delimiter)
{
byte[] encodedBytes = new byte[readBufferPosition];
System.arraycopy(readBuffer, 0, encodedBytes, 0, encodedBytes.length);
final String data = new String(encodedBytes, "US-ASCII");
readBufferPosition = 0;
handler.post(new Runnable()
{
public void run()
{
myLabel.setText(data);
}
});
}
else
{
readBuffer[readBufferPosition++] = b;
}
}
}
}
catch (IOException ex)
{
Log.i("IO ex read " ,ex.getMessage());
stopWorker = true;
}
}
}
});
workerThread.start();
}
void sendData() throws IOException
{
String msg = myTextbox.getText().toString();
msg += "\n";
mmOutputStream.write(msg.getBytes());
myLabel.setText("Data Sent");
}
When I click open both tablet and mobile phone, myLabel text changed to "Blueetooth Opened" succesfully.
But when I try to send text to phone from tablet or to table from phone, nothing sended. Data listener is working. mmInputStream.available() always returns 0.
Some log details :
D/BluetoothUtils: isSocketAllowedBySecurityPolicy start : device null
W/BluetoothAdapter: getBluetoothService() called with no BluetoothManagerCallback
D/BluetoothSocket: connect(), SocketState: INIT, mPfd: {ParcelFileDescriptor: FileDescriptor[49]}
So the logic is:
User connects a USB to Android device.
User press "Find Update" button.
The App connects to the USB and finds in the main folder any .apk file.
The App opens the .apk file found in the USB.
The .apk runs and update the current App.
What I have so far:
findUpdate.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
boolean foundUsb = false;
usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
deviceList = usbManager.getDeviceList();
deviceIterator = deviceList.values().iterator();
Log.d("UPDATER", "Pressed");
while(deviceIterator.hasNext()){
UsbDevice device = deviceIterator.next();
Log.d("UPDATER", "Device Attached: " + device.getManufacturerName());
if (!Objects.equals(device.getManufacturerName(), gv.getManufacturerIDPlaca())) {
Log.d("UPDATER", device.getManufacturerName());
foundUsb = true;
PendingIntent mPermissionIntent = PendingIntent.getBroadcast(SetupActivity.this, 0, new Intent(ACTION_USB_PERMISSION), 0);
if (!usbManager.hasPermission(device)) {
Log.d("UPDATER", "No access");
usbManager.requestPermission(device, mPermissionIntent);
IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
}
Log.d("UPDATER", "Has access");
usbDevice = device;
usbInterface = usbDevice.getInterface(0);
usbEndpoint = usbInterface.getEndpoint(0);
usbDeviceConnection = usbManager.openDevice(usbDevice);
packetSize = usbEndpoint.getMaxPacketSize();
new Thread(new Runnable() {
public void run() {
final byte[] buffer = new byte[packetSize];
usbDeviceConnection.claimInterface(usbInterface, forceClaim);
usbDeviceConnection.bulkTransfer(usbEndpoint, buffer, packetSize, TIMEOUT);
Log.d("UPDATER", String.valueOf(buffer));
}
}).start();
}
}
if (!foundUsb) {
Toast.makeText(context, "No USB detected", Toast.LENGTH_SHORT).show();
}
}
});
What this code returns me in console is a buffer (of bytes) converted to a String.
I'm wondering how could I find a file let's say app.apk and open it to actually update the current app (where the button is pressed from).
I finally came up with a solution:
findUpdate.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
boolean foundUsb = false;
usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
deviceList = usbManager.getDeviceList();
deviceIterator = deviceList.values().iterator();
while(deviceIterator.hasNext()){
UsbDevice device = deviceIterator.next();
Log.d("UPDATER", "Device Attached: " + device.getManufacturerName());
if (!Objects.equals(device.getManufacturerName(), gv.getManufacturerIDPlaca())) {
foundUsb = true;
PendingIntent mPermissionIntent = PendingIntent.getBroadcast(SetupActivity.this, 0, new Intent(ACTION_USB_PERMISSION), 0);
if (!usbManager.hasPermission(device)) {
usbManager.requestPermission(device, mPermissionIntent);
IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
}
try {
File file = new File("/storage/usbhost/update-binary.apk");
if (file.exists()) {
Intent newIntent = new Intent(Intent.ACTION_VIEW);
newIntent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
newIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(newIntent);
}
else {
Toast.makeText(getApplicationContext(), R.string.UPDATE_APK_NO_ENCONTRADA, Toast.LENGTH_LONG).show();
}
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(), e.toString(), Toast.LENGTH_LONG).show();
}
}
}
if (!foundUsb) {
Toast.makeText(context, R.string.USB_NO_CONECTADO, Toast.LENGTH_SHORT).show();
}
}
});
I do not have much experience with USB connection in Android, so I followed the tutorial on the Android developer page. I tried to put together a code, which when I send a command to a USB device, for example
send("M?");
then the device sends me back some rows of string which my app processes and displays it to me. But unfortunately I do not get what I want. Sometimes I get just a part of that string, sometimes some strange characters, or nothing. Could you please help me, how to fix my code? This code should be able to read small strings(for example 20-25 characters) but also long strings.
I have the following code:
UsbReadWrite.java
public class UsbReadWrite extends AppCompatActivity {
static UsbDevice device;
private static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";
static UsbManager mUsbManager;
static PendingIntent mPermissionIntent;
private static byte[] bytes;
private static boolean forceClaim = true;
static int controlTransferResult;
static byte[] readBytes = new byte[4096];
static UsbEndpoint epOut = null, epIn = null;
static UsbDeviceConnection connection;
static int recvBytes;
static String readString = "";
static Thread thread;
static Runnable r;
static UsbInterface intf;
static UsbRequest request;
Handler handler;
static UsbManager manager;
static HashMap<String, UsbDevice> deviceList;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
public UsbReadWrite(Handler handler){
this.handler = handler;
}
public static boolean connectDevice(Context context){
manager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
deviceList = manager.getDeviceList();
if (deviceList.toString().equals("{}")) {
return false;
}
Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
device = deviceIterator.next();
mUsbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
mPermissionIntent = PendingIntent.getBroadcast(context, 0, new Intent(ACTION_USB_PERMISSION), 0);
IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
try {
context.registerReceiver(mUsbReceiver, filter);
}catch (Exception e){
e.printStackTrace();
}
mUsbManager.requestPermission(device, mPermissionIntent);
intf = device.getInterface(0);
// look for our bulk endpoints
for (int i = 0; i < intf.getEndpointCount(); i++) {
UsbEndpoint ep = intf.getEndpoint(i);
if (ep.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) {
if (ep.getDirection() == UsbConstants.USB_DIR_OUT) {
epOut = ep;
} else if (ep.getDirection() == UsbConstants.USB_DIR_IN) {
epIn = ep;
}
}
}
if (epOut == null || epIn == null) {
throw new IllegalArgumentException("Not all endpoints found.");
}
Thread t = new Thread(new Runnable() {
#Override
public void run() {
while (!mUsbManager.hasPermission(device)){
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
connection = mUsbManager.openDevice(device);
connection.claimInterface(intf, forceClaim);
connection.controlTransfer(0x40, 0, 0, 0, null, 0, 0);// reset
connection.controlTransfer(0x40, 0, 1, 0, null, 0, 0);// clear Rx
connection.controlTransfer(0x40, 0, 2, 0, null, 0, 0);// clear Tx
controlTransferResult = connection.controlTransfer(0x40, 0x03, 0x4138, 0, null, 0, 0);
connection.controlTransfer(0x40, 0x04, 0x0008, 0, null, 0, 0);
request = new UsbRequest();
request.initialize(connection, epOut);
}
});
t.start();
return true;
}
public static final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (ACTION_USB_PERMISSION.equals(action)) {
synchronized (this) {
UsbDevice device = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
if (device != null) {
//call method to set up device communication
intf = device.getInterface(0);
// look for our bulk endpoints
for (int i = 0; i < intf.getEndpointCount(); i++) {
UsbEndpoint ep = intf.getEndpoint(i);
if (ep.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) {
if (ep.getDirection() == UsbConstants.USB_DIR_OUT) {
epOut = ep;
} else if (ep.getDirection() == UsbConstants.USB_DIR_IN) {
epIn = ep;
}
}
}
if (epOut == null || epIn == null) {
throw new IllegalArgumentException("Not all endpoints found.");
}
connection = mUsbManager.openDevice(device);
connection.claimInterface(intf, forceClaim);
connection.controlTransfer(0x40, 0, 0, 0, null, 0, 0);// reset
connection.controlTransfer(0x40, 0, 1, 0, null, 0, 0);// clear Rx
connection.controlTransfer(0x40, 0, 2, 0, null, 0, 0);// clear Tx
controlTransferResult = connection.controlTransfer(0x40, 0x03, 0x4138, 0, null, 0, 0);
connection.controlTransfer(0x40, 0x04, 0x0008, 0, null, 0, 0);
request = new UsbRequest();
request.initialize(connection, epOut);
}
} else {
Log.d("MyActivity", "permission denied for device " + device);
}
}
}
}
};
public static void read2(){
r = new Runnable() {
#Override
public void run() {
synchronized (this) {
readString="";
send("M?");
while (true) {
try {
Thread.sleep(400);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (mUsbManager.hasPermission(device)){
recvBytes = connection.bulkTransfer(epIn, readBytes, readBytes.length, 100);
Log.e("Database","M?="+readBytes);
if (recvBytes != 0) {
readString += new String(readBytes);
readString = readString.replace("\u0001`","");
readString = readString.replace("\u0000","");
Log.e("Database","M?="+readString);
}
}
}
}
}
};
thread = new Thread(r);
thread.start();
}
public static void send(String command){
String fullCommand = "#" + command + "\r\n"; /*+ "\r\n"*/
bytes = fullCommand.getBytes();
while (connection==null){
continue;
}
connection.bulkTransfer(epOut, bytes, bytes.length, 100); //0
}
}
Thanks in advance.
I've managed to make a NFC application in which when the specific tag is scanned, the phone will automatically establish connection with one particular Wi-Fi. (even if Wi-Fi is off) I've already included the SSID and password in the code(tag) so the users can just scan the tag to connect. However, I notice that on my first tap, Wi-Fi is enabled(if disabled) but it will not connect to the Wi-Fi. Only on the second tap, it connects to the specified Wi-Fi. Why is it so?
My code:
#Override
protected void onNewIntent(Intent intent) {
String result2="";
String resultid="";
String resultpw="";
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 = 0; b<payload.length; b++) { // skip SOH
result += (char) payload[b];
}
*/
try{
//grabbing 2nd payload
byte[] payload2 = messages[0].getRecords()[1].getPayload();
for (int test = 0; test<payload2.length; test++) { // skip SOH
result2 += (char) payload2[test];
//Toast.makeText(this,result2,Toast.LENGTH_SHORT).show();
}
}
catch(ArrayIndexOutOfBoundsException e){
Toast.makeText(getApplicationContext(), "Wrong tag detected. Try again!", Toast.LENGTH_SHORT).show();
}
//grab ssid
try{
byte[] payload3 = messages[0].getRecords()[2].getPayload();
for (int test = 0; test<payload3.length; test++) { // skip SOH
resultid += (char) payload3[test];
//Toast.makeText(this,result2,Toast.LENGTH_SHORT).show();
}
}
catch(ArrayIndexOutOfBoundsException e){
}
//grab ssid_pw
try{
byte[] payload4 = messages[0].getRecords()[3].getPayload();
for (int test = 0; test<payload4.length; test++) { // skip SOH
resultpw += (char) payload4[test];
//Toast.makeText(this,result2,Toast.LENGTH_SHORT).show();
}
}
catch(ArrayIndexOutOfBoundsException e){
}
if (result2.contains("StarbucksBestCoffee"))
{
final ImageView img = (ImageView)findViewById(R.id.imageView1);
/* Call to convert bytes to hex .
*
String uid = toHex(intent.getByteArrayExtra(NfcAdapter.EXTRA_ID));
Toast.makeText(this, uid, Toast.LENGTH_LONG).show();*/
/*if (storedPreference!=10)
{
Toast.makeText(getApplicationContext(), "Coupon collected!", Toast.LENGTH_SHORT).show();
storedPreference++;
SharedPreferences.Editor editor = preferences.edit();
editor.putInt("storedInt", storedPreference);
img.setImageResource(images[storedPreference]);
img.invalidate();
}*/
if (storedPreference==10)
{
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setCancelable(false);
builder.setTitle("Redeem Your Coupon?");
builder.setInverseBackgroundForced(true);
builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which)
{
dialog.dismiss();
SharedPreferences preferences = getSharedPreferences(PREF_FILE_NAME, MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.putInt("storedInt", 0); // value to store
editor.commit();
img.setImageResource(images[0]);
img.invalidate();
}
});
builder.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
img.setImageResource(images[10]);
img.invalidate();
}
});
builder.show();
}
else
{
Toast.makeText(getApplicationContext(), "Coupon collected!", Toast.LENGTH_SHORT).show();
storedPreference++;
SharedPreferences.Editor editor = preferences.edit();
editor.putInt("storedInt", storedPreference);
editor.commit();
img.setImageResource(images[storedPreference]);
img.invalidate();
}
if (resultid!=null&&resultpw!=null)
{
//Wi-Fi Manager auto-connect
WifiManager wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
WifiConfiguration wc = new WifiConfiguration();
wc.SSID = "\"" + resultid + "\"";
wc.preSharedKey = "\"" + resultpw + "\"";
wc.hiddenSSID = true;
wc.status = WifiConfiguration.Status.ENABLED;
wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
wc.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
int res = wifi.addNetwork(wc);
Log.d("WifiPreference", "add Network returned " + res );
boolean b = wifi.enableNetwork(res, true);
Log.d("WifiPreference", "enableNetwork returned " + b );
wifi.setWifiEnabled(true);
}
}
else
{
Toast.makeText(getApplicationContext(), "Wrong tag detected!", Toast.LENGTH_SHORT).show();
}
Try this:
Process the NDEF message in 'onResume', and
Add the Wifi when wifi is enabled
In other words, if wifi is not enabled,
Store the wifi credentials,
Listen for Wifi broadcasts untill enabled, then
Add the network
Also, your NDEF parsing is a real hack. Try if parsing using this works instead.