Android read string via USB communication - java

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.

Related

Cannot send and receive any data from bluetooth

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]}

Sending string from AndroidLauncher to MyGdxGame

I am trying to create a chess app, I get move information from Bluetooth, then I need to send it to method located in the core class. Also, I need to start a function that is in AndroidLauncher when a button from core class has been clicked.
AndroidLauncher:
public class AndroidLauncher extends AndroidApplication {
public static final int CONNECTION_TIMEOUT=10000;
public static final int READ_TIMEOUT=15000;
BluetoothSocket mmSocket;
BluetoothDevice mmDevice = null;
final byte delimiter = 33;
int readBufferPosition = 0;
public void sendBtMsg(String msg2send){
//UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb"); //Standard SerialPortService ID
UUID uuid = UUID.fromString("94f39d29-7d6d-437d-973b-fba39e49d4ee"); //Standard SerialPortService ID
try {
mmSocket = mmDevice.createRfcommSocketToServiceRecord(uuid);
if (!mmSocket.isConnected()){
mmSocket.connect();
}
String msg = msg2send;
//msg += "\n";
OutputStream mmOutputStream = mmSocket.getOutputStream();
mmOutputStream.write(msg.getBytes());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();
MyGdxGame game = new MyGdxGame();
View gameView = initializeForView(game, config);
initialize(new MyGdxGame(), config);
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
final class workerThread implements Runnable {
private String btMsg;
public workerThread(String msg) {
btMsg = msg;
}
public void run()
{
sendBtMsg(btMsg);
while(1 == 1) {
while (!Thread.currentThread().isInterrupted()) {
int bytesAvailable;
boolean workDone = false;
try {
final InputStream mmInputStream;
mmInputStream = mmSocket.getInputStream();
bytesAvailable = mmInputStream.available();
if (bytesAvailable > 0) {
byte[] packetBytes = new byte[bytesAvailable];
byte[] readBuffer = new byte[1024];
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;
//The variable data now contains our full command
handler.post(new Runnable() {
public void run() {
char first = data.charAt(0);
if( first == 'm'){
new AsyncLogin().execute(data.substring(1),"-", "0");
} else {
new AsyncLogin().execute("-",data, "0");
}
//myLabel.setText(data);
}
});
workDone = true;
break;
} else {
readBuffer[readBufferPosition++] = b;
}
}
if (workDone == true){
break;
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
};
// end light off button handler
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)
{
if(device.getName().equals("raspberrypi")) //Note, you will need to change this to match the name of your device
{
Log.e("Aquarium",device.getName());
mmDevice = device;
break;
}
}
}
}
MyGdxGame
public class MyGdxGame extends ApplicationAdapter {
public static int V_WIDTH = 720;//720
public static int V_HEIGHT = 1280;//1280
private String slogin = "Prisijungimas",sreg= "Registracija",sai =
"Kompiuteris",shuman = "Ieškoti oponento",sboard;
SpriteBatch batch;
Texture bdt,blt,kdt,klt,ndt,nlt,pdt,plt,qdt,qlt,rdt,rlt;
OrthographicCamera camera;
public Viewport viewport;
private ShowScreen screen = ShowScreen.login;
BitmapFont font,font2;
float rh, rw;
float startpos[][][] = new float[9][9][2];//cia grido pozicijos [eile]
[stulpelis][x/y]
float fig_pos[][]= new float[32][6];// [figuros id]
[x/y/newx/newy/movingx/movingy]
int fig_laukelis[][] = new int[32][2];//[figuros id][eile/stulpelis]
//figuru movinimui
int oldRow;
int newRow;
int oldCol;
int newCol;
ShapeRenderer shape;//renderina shapus as buttons
GlyphLayout layout;
//test string
String test = "move example 1";
#Override
public void create() {
//kai kuriuos var'us reikia initialaizint dar karta kad sukurti ale tuscia array
batch = new SpriteBatch();
shape = new ShapeRenderer();
font = new BitmapFont();//cia kad spausdinti texta
font2 = new BitmapFont();//cia kad spausdinti texta lentoj
camera = new OrthographicCamera(); //nustatom cameros dydi
viewport = new FitViewport(Gdx.graphics.getWidth(), Gdx.graphics.getHeight(),camera);//fitinam i screena
viewport.apply();//reikia apply kitaip viewporto dydis nebus issaugotas
//gaunam ratio
rw = (float) Gdx.graphics.getWidth() / (float) V_WIDTH;
rh = (float) Gdx.graphics.getHeight() / (float) V_HEIGHT;
camera.position.set(camera.viewportWidth / 2, camera.viewportHeight / 2, 0);//nustatom cameros pozicija per viduti cameros view
//uzrkaunam img
//prima uzkraunam i manageri
bdt = new Texture("chess_fig/chess_bdt60.png");
blt = new Texture("chess_fig/chess_blt60.png");
kdt = new Texture("chess_fig/chess_kdt60.png");
klt = new Texture("chess_fig/chess_klt60.png");
ndt = new Texture("chess_fig/chess_ndt60.png");
nlt = new Texture("chess_fig/chess_nlt60.png");
pdt = new Texture("chess_fig/chess_pdt60.png");
plt = new Texture("chess_fig/chess_plt60.png");
qdt = new Texture("chess_fig/chess_qdt60.png");
qlt = new Texture("chess_fig/chess_qlt60.png");
rdt = new Texture("chess_fig/chess_rdt60.png");
rlt = new Texture("chess_fig/chess_rlt60.png");
//font
FreeTypeFontGenerator generator = new FreeTypeFontGenerator(Gdx.files.internal("comics_bold.ttf"));//gali pasikeisti i bet koki kita fonta jei nori
FreeTypeFontGenerator.FreeTypeFontParameter parameter = new FreeTypeFontGenerator.FreeTypeFontParameter();
parameter.size = (int) (50*(rw/rh));//dydis
font = generator.generateFont(parameter);///issaugom sugeneratinta fonta
font.setColor(255 / 255f, 255 / 255f, 255 / 255f, 1);
parameter.size = (int)(150*(rw/rh));
font2 = generator.generateFont(parameter);
font2.setColor(Color.BLACK);
//gaunam grida
for(int stulpeis = 0;stulpeis<9;stulpeis++){
for(int eile = 0;eile<9;eile++){
startpos[eile][stulpeis][0]=0+(camera.viewportWidth/9*stulpeis);//x
startpos[eile][stulpeis][1]=0+(camera.viewportWidth/9*eile);//y
}
}
private void movefig(String coord) {
//nuskaitom stringa ir priskiriam teisingas reiksmes
for (int index = 0; index < 4;
index++) {
char aChar = coord.charAt(index);
if(index==0){
if(aChar=='A'){
oldCol=1;
}else if(aChar=='B'){
oldCol=2;
}else if(aChar=='C'){
oldCol=3;
}else if(aChar=='D'){
oldCol=4;
}else if(aChar=='E'){
oldCol=5;
}else if(aChar=='F'){
oldCol=6;
}else if(aChar== 'G'){
oldCol=7;
}else if(aChar == 'H'){
oldCol=8;
}
}else if(index==1){
if(aChar=='1'){
oldRow=1;
}else if(aChar=='2'){
oldRow=2;
}else if(aChar=='3'){
oldRow=3;
}else if(aChar=='4'){
oldRow=4;
}else if(aChar=='5'){
oldRow=5;
}else if(aChar=='6'){
oldRow=6;
}else if(aChar== '7'){
oldRow=7;
}else if(aChar == '8'){
oldRow=8;
}
}else if(index==2){
if(aChar=='A'){
newCol=1;
}else if(aChar=='B'){
newCol=2;
}else if(aChar=='C'){
newCol=3;
}else if(aChar=='D'){
newCol=4;
}else if(aChar=='E'){
newCol=5;
}else if(aChar=='F'){
newCol=6;
}else if(aChar== 'G'){
newCol=7;
}else if(aChar == 'H'){
newCol=8;
}
}else if(index==3){
if(aChar=='1'){
newRow=1;
}else if(aChar=='2'){
newRow=2;
}else if(aChar=='3'){
newRow=3;
}else if(aChar=='4'){
newRow=4;
}else if(aChar=='5'){
newRow=5;
}else if(aChar=='6'){
newRow=6;
}else if(aChar== '7'){
newRow=7;
}else if(aChar == '8'){
newRow=8;
}
}
}
//ieskom figureles kuri butu senoj pozicioj
for(int f = 0;f<32;f++){
if(fig_laukelis[f][0]==oldRow && fig_laukelis[f][1]==oldCol){
//nzn kas cia nutiko bet cia susimaiso row ir collumai ;/
fig_pos[f][2]=(camera.viewportWidth/9)*(newCol);
fig_pos[f][3]=(camera.viewportWidth/9)*(newRow);
//atnaujinam figuros laukeli
fig_laukelis[f][0]=newRow;
fig_laukelis[f][1]=newCol;
//radom tad baigiam cikla
f=33;
}
}
}
}
What I need to do is call movefig method when I get data from Bluetooth in AndroidLauncher handler.post(new Runnable() { part of the code.
Make movefig() of MyGdxGame public so that you can access from any package.
MyGdxGame gdxGame;
#Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();
gdxGame = new MyGdxGame();
View gameView = initializeForView(gdxGame, config);
setContentView(gameView);
}
Now you've reference of MyGdxGame, You can call movefig() inside AndroidLauncher class.
You need interfacing by which you make call core module to android module
Create an interface inside your core module
public interface Service {
void doSomeThing();
}
Implement this interface in AndroidLauncher class
public class AndroidLauncher extends AndroidApplication implements Service {
MyGdxGame gdxGame;
#Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();
gdxGame = new MyGdxGame(this);
View gameView = initializeForView(gdxGame, config);
setContentView(gameView);
}
#Override
public void doSomething() {
//do what you want
}
...
}
Keep reference of Service that comes from platform so create parameterised constructor of MyGdxGame
public class MyGdxGame extends ApplicationAdapter {
Service service;
public MyGdxGame(Service service){
this.service=service;
}
...
}

Android Studio communicating with HID USB device with controlTransfer

I'm having issues communicating with a HID USB device in Android Studio.
I have code in Python which works perfectly, so the device is fine.
Also note, that I've used this java class for another device where I receive data only and it works wonderfully.
But this new device, I need to send and receive data. So I am using controlTransfer to send data on endpouint 0.
Here's the code (snippets) in Python:
import hid
DEVICEMODE = 0x0B
GBLINK = 0x02
self.dongle = hid.device()
self.dongle.open(self.idVendor, self.idProduct)
self.sendCommand(0, DEVICEMODE, 0x00, 0x01)
self.sendCommand(0, GBLINK, 0x40, 0xFF)
def sendCommand(self, pucknum, cmd, msb, lsb):
command = (0b11000000 & (devicenum << 6)) | cmd
self.dongle.set_nonblocking(1)
self.dongle.write([0x00, command, msb, lsb]) # first byte is report id
self.dongle.set_nonblocking(0)
The code then goes on to send various commands via the sendCommand method.
In Java, I have the following
public class DongleDevice implements Runnable {
protected final String TAG = "DongleDevice";
public UsbDevice usbDevice;
public UsbManager usbManager;
public UsbDeviceConnection usbDeviceConnection;
private UsbInterface intf;
private UsbEndpoint endpoint;
public int version = -1;
public Thread thread;
public volatile boolean threadRunning = false;
private boolean status = false;
private boolean firstTime = true;
private UsbRequest request = null;
public DongleDevice() {
thread = new Thread(this);
}
public void requestPermission() {
usbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
HashMap<String, UsbDevice> deviceList = usbManager.getDeviceList();
Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
deviceFound = false;
deviceReady = false;
while (deviceIterator.hasNext()) {
usbDevice = deviceIterator.next();
if (usbDevice.getVendorId() == Constants.VENDOR_ID) {
deviceFound = true;
break;
}
}
if (deviceFound == true) {
PendingIntent pi = PendingIntent.getBroadcast(context, 0, new Intent("PERMISSION_GRANTED"), 0);
usbManager.requestPermission(usbDevice, pi);
}
}
public void openDevice () {
final Handler handler = new Handler();
boolean handlePlaced = handler.postDelayed(new Runnable() {
public void run() {
usbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
HashMap<String, UsbDevice> deviceList = usbManager.getDeviceList();
Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
deviceFound = false;
deviceReady = false;
while (deviceIterator.hasNext()) {
usbDevice = deviceIterator.next();
if (usbDevice.getVendorId() == Constants.VENDOR_ID) {
deviceFound = true;
break;
}
}
if (deviceFound == true) {
if (usbManager.hasPermission(usbDevice)) open();
else closeDevice();
}
}
}, 2000);
}
private void open() {
endpoint = intf.getEndpoint(0);
usbDeviceConnection = usbManager.openDevice(usbDevice);
status = usbDeviceConnection.claimInterface(intf, true);
if (status) {
getVersion();
thread.start();
} else {
closeDevice();
}
}
private void getVersion() {
byte[] rawDescriptors;
rawDescriptors = usbDeviceConnection.getRawDescriptors();
version = (int)(rawDescriptors[12] & 0x01);
}
public void closeDevice() {
deviceReady = false;
deviceFound = false;
if (threadRunning == true) {
if (request != null) {
request.cancel();
}
}
}
public void onDestroy() {
closeDevice();
}
public boolean isOpen() {
return deviceFound;
}
#Override
public void run() {
threadRunning = true;
deviceReady = true;
ByteBuffer buffer = ByteBuffer.allocate(60);
if (request != null) request.cancel();
request = new UsbRequest();
status = request.initialize(usbDeviceConnection, endpoint);
P_Device pd1 = new P_Device(0); //a class for parsing the 60 byte data packet received
byte[] command;
int response;
int requestType = 0x21;
int requestId = 0x9;
int value = 0x200; // 0x300 also works
int index = 0;
int timeout = 5000;
byte DEVICEMODE = 0x0B;
byte GBLINK = 0x02;
while (deviceFound == true) {
command = new byte[] {DEVICEMODE, 0x00, 0x01}; // send command followed by two bytes
response = usbDeviceConnection.controlTransfer(requestType, requestId, value, index, command, command.length, timeout);
Logger.d(TAG,"controlTransfer response = " + response); // I get 3 as a response
try { thread.sleep(100); } catch (Exception e) { }
for (int i=0; i<20; i++) {
command = new byte[]{GBLINK, (byte) 64, (byte) 255}; // should blink for ~300 ms at full intensity
response = usbDeviceConnection.controlTransfer(requestType, requestId, value, index, command, command.length, timeout);
Logger.d(TAG, "controlTransfer response = " + response); // I get 3 as a response
try { thread.sleep(500); } catch (Exception e) { }
}
for (int i=0; i<20; i++) {
request.queue(buffer, 60);
if (usbDeviceConnection.requestWait().equals(request)) {
//buffer.flip();
buffer.position(0);
pd1.parse(buffer) // all results are 0, and they shouldn't be.
}
try { thread.sleep(100); } catch (Exception e) { }
}
command = new byte[] {DEVICEMODE , 0x00, 0x00};
response = usbDeviceConnection.controlTransfer(requestType, requestId, value, index, command, command.length, timeout);
Logger.d(TAG,"controlTransfer response = " + response); // I get 3 as a response
try { thread.sleep(100); } catch (Exception e) { }
deviceFound = false;
}
threadRunning = false;
deviceReady = false;
}
}
When I run my code I get the confirmation that the bytes sent are 3 (a -1 would indicate an error). But the device isn't blinking as it should, and I get all 0's from the read.
Any help would be appreciated.

How to send data via USB communication from Android device?

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

UI not showing up after switching to AsyncTask

I have recently switched over to AsyncTask after reading how efficent it is. It took some time porting my code, but I did it in the end. I have 1 AsyncTask that gets run first, setting up the background image/color that it gets off a json object. After that, it sets up TableRows for all the other fields in the JSON file. The background changes, but the UI does not show up. I placed System.out.println's inside my AsyncTask and I see that the code has been executed (the onPostExecute method), but none of the UI shows up. I have no idea what the problem is, hence me posting this question.
Here is my AsyncTask:
class GetImageAsync extends AsyncTask<String, Void, Drawable> {
private final WeakReference<View> ViewReference;
private String data;
private Context context;
private boolean isImageView;
private boolean scale;
private int id = -1;
private int color = -1;
private int height = -1;
public GetImageAsync(TableLayout tr, String data, Context context) {
isImageView = false;
this.context = context;
this.data = data;
ViewReference = new WeakReference<View>(tr);
System.out.println("inside async");
}
public GetImageAsync(ImageView iv, int id, Context context) {
isImageView = true;
this.context = context;
this.id = id;
ViewReference = new WeakReference<View>(iv);
}
public GetImageAsync(ImageView imageView,String data, Context context, int height) {
System.out.println("profile async");
this.height = height;
isImageView = true;
this.context = context;
this.data = data;
ViewReference = new WeakReference<View>(imageView);
}
// Decode image in background.
#Override
protected Drawable doInBackground(String... params) {
System.out.println(id + " : " + isImageView);
if(isImageView && id != -1) {
return getImageFromResource();
} else {
if(data.startsWith("#")) {
color = Color.parseColor(data);
return null;
}
try {
return getImageFromWeb(data, scale);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
private Drawable getImageFromResource() {
return context.getResources().getDrawable(id);
}
private Drawable getImageFromWeb(String data, boolean b) throws MalformedURLException, IOException {
Bitmap img = BitmapFactory.decodeStream(new URL(data).openConnection().getInputStream());
if(height != -1) {
return new BitmapDrawable(context.getResources(), getCroppedBitmap(Bitmap.createScaledBitmap(
Bitmap.createScaledBitmap(img,
img.getWidth(),
img.getWidth(), true),
height * 2,
height * 2, true)));
}
return new BitmapDrawable(context.getResources(), img);
}
// Once complete, see if ImageView is still around and set bitmap.
#Override
protected void onPostExecute(Drawable bitmap) {
if(isImageView) { //this block does not {
System.out.println("post "+isImageView);
System.out.println("iv");
if (ViewReference != null && bitmap != null) {
final ImageView imageView = (ImageView) ViewReference.get();
if (imageView != null) {
imageView.setImageDrawable(bitmap);
}
} // }
} else { //this block runs {
System.out.println("post "+isImageView);
if (ViewReference != null) {
final TableLayout tr = (TableLayout) ViewReference.get();
if (tr != null) {
if(color != -1) {
tr.setBackgroundColor(color);
} else {
tr.setBackground(bitmap);
}
}
}
} // }
}
public static Bitmap getCroppedBitmap(Bitmap bitmap) {
int w = bitmap.getWidth();
int h = bitmap.getHeight();
int radius = Math.min(h / 2, w / 2);
Bitmap output = Bitmap.createBitmap(w + 8, h + 8, Config.ARGB_8888);
Paint p = new Paint();
p.setAntiAlias(true);
Canvas c = new Canvas(output);
c.drawARGB(0, 0, 0, 0);
p.setStyle(Style.FILL);
c.drawCircle((w / 2) + 4, (h / 2) + 4, radius, p);
p.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
c.drawBitmap(bitmap, 4, 4, p);
p.setXfermode(null);
p.setStyle(Style.STROKE);
p.setColor(Color.BLACK);
p.setStrokeWidth(1);
c.drawCircle((w / 2) + 4, (h / 2) + 4, radius, p);
return output;
}
}
and here is how I create the UI:
private void createUI(JSONObject jObject) throws JSONException {
int absIndex = 0;
if (android.os.Build.VERSION.SDK_INT >= 16) {
new GetImageAsync(tr, jObject.getString(("bg")), getApplicationContext()).execute("");
System.out.println("after async");
/*if (bgcolor != -1) {
System.out.println("color: " + bgcolor);
tr.setBackgroundColor(bgcolor);
} else if (bgpic != null) {
tr.setBackground(bgpic);
}*/
}
for (int i = 0; i < keys.length; i++) {
values.add(i, new ArrayList<String>());
values.get(i).add(0, keys[i]);
values.get(i).add(1, jObject.getString(keys[i]));
}
String lastString = WhoIsLast(jObject);
trcard.setBackground(getResources()
.getDrawable(R.drawable.bg_card/* abc_menu_dropdown_panel_holo_light */));
trcard.addView(tlcard);
tr.setPadding(0, 0, 0, 0);
TableLayout.LayoutParams tableRowParams = new TableLayout.LayoutParams(
TableLayout.LayoutParams.MATCH_PARENT,
TableLayout.LayoutParams.WRAP_CONTENT);
int[] attrs = { android.R.attr.dividerVertical };
TypedArray typedArray = getApplicationContext().obtainStyledAttributes(
attrs);
Drawable divider = typedArray.getDrawable(0);
typedArray.recycle();
tableRowParams.setMargins(20, 20, 20, 0);
trcard.setLayoutParams(tableRowParams);
tlcard.setDividerDrawable(divider);
tlcard.setDividerPadding(4);
tableScrollView.addView(trcard);
for (int i = 0; i < keys.length; i++) {
String value = values.get(i).get(1);
if (value != "") {
String key = values.get(i).get(0);
boolean last = false;
if (i == keys.length || value.equals(lastString) || i == 0) {
last = true;
System.out.println(value +" = "+lastString);
}
insertElement(value, key, absIndex++, last, drawables[i]);
if (!last) {
absIndex++;
}
}
}
}
private String WhoIsLast(JSONObject j) throws JSONException {
if (j.getString("facebook").equals("")) {
return "";
}
if (j.getString("twitter").equals("")) {
return "facebook";
}
if (j.getString("email").equals("")) {
return "twitter";
}
if (j.getString("phone").equals("")) {
return "email";
}
return "";
}
int absIndex = 0;
private void insertElement(String data, String key, int i,
boolean b, Integer id) throws JSONException {
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View newRow = inflater.inflate(R.layout.row, null, false);
newRow.setLayoutParams(new TableRow.LayoutParams(
TableRow.LayoutParams.MATCH_PARENT,
TableRow.LayoutParams.WRAP_CONTENT));
TextView dataTextView = (TextView) newRow
.findViewById(R.id.rowTextView);
dataTextView.setText("\t " + data);
ImageView iv = (ImageView) newRow.findViewById(R.id.rowImageView);
newRow.setId(absIndex++);
newRow.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
//omitted
});
View v = new View(this);
v.setLayoutParams(new TableRow.LayoutParams(
TableRow.LayoutParams.MATCH_PARENT, 1));
v.setBackgroundColor(Color.argb(25, 111, 111, 111));
dataTextView.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
if (i == 0) {
System.out.println("before async iv");
new GetImageAsync(iv, jObject.getString("profilepic"), getApplicationContext(), dataTextView.getMeasuredHeight()).execute("");
System.out.println("after async iv");
//async.execute("");
dataTextView.setShadowLayer(3, 0, 0, Color.BLACK);
dataTextView.setTextColor(getResources().getColor(R.color.white));
} else {
new GetImageAsync(iv, id, getApplicationContext()).execute("");
}
if (i == 0) {
dataTextView.setTextSize(30);
tableScrollView.addView(newRow, i);
System.out.println("adding i=0null");
} else {
System.out.println("adding i = "+i +tlcard);
tlcard.addView(newRow, i - 1);
if (!b) {
tlcard.addView(v, i);
}
}
}
Edit: where I call createUi method:
final Thread thread = new Thread(new Runnable() {
#Override
public void run() {
jObject = getJson("http://www.tabcards.com/req/androidapi/L2o30H8JlFMtFYHW3KLxkts20ztc5Be6Z6m6v315/json/"
+ value);
System.out.println(value);
if (jObject != null) {
runOnUiThread(new Runnable() {
#Override
public void run() {
try {
createUI(jObject);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
});
thread.start();

Categories