I have an application that communicates over Bluetooth Serial Port with another terminal. It can send and receive data, more specifically text.
I can send and receive data successfully when the app is on foreground, however, I would like to know how I can make it so the app can receive data when in background and show it in the activity once it comes to foreground.
I'm currently using a service with the doInBackground(). However, I don't know what else I'm missing. Please assist me.
This is my service class
package com.boson.BTComms;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import android.app.Service;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;
public class BtService extends Service
{
Bluetooth bt = new Bluetooth();
static ConnectTask cTask;
Bundle bndl;
int action;
public class rxBluetooth
{
public String rxdMsg;
public boolean newData;
public boolean workerStatus;
OutputStream mmOutputStream; // Stream de salida de la conexión
InputStream mmInputStream; // Stream de entrada de la conexión
Thread workerThread; // Thread de escucha
BluetoothSocket mmSocket; // Socket que se utiliza para comunicacion entre los dispositivos Bluetooth
int readBufferPosition = 0; // Variable para bufer de lectura
}
rxBluetooth rxBT = new rxBluetooth();
#Override
public IBinder onBind(Intent intent)
{
return null;
}
public int onStartCommand(Intent intent, int flags, int startId)
{
bndl = intent.getExtras();
action = bndl.getInt("act");
//MAIN SERVICE STATE-MACHINE
switch (action)
{
case 0://Conexión
try
{
String remDev = bndl.getString("_remDev");
cTask = (ConnectTask) new ConnectTask().execute(remDev);
}
catch(Exception e)
{
Toast.makeText(this, "Could not open connection!", Toast.LENGTH_LONG).show();
Intent i = new Intent(getApplicationContext(), HomeActivity.class);
startActivity(i);
}
break;
case 1://Enviar Datos
try
{
if(rxBT.mmSocket != null && rxBT.mmSocket.isConnected() == true)
{
String msg = bndl.getString("_message");
rxBT.mmOutputStream.write(msg.getBytes());
rxBT.mmOutputStream.flush();
}
}
catch(Exception e)
{
Toast.makeText(this, "Could not send data!", Toast.LENGTH_LONG).show();
}
break;
case 2://Cerrar Conexión
rxBT.workerStatus = false;
if (rxBT.mmInputStream != null)
{
try
{
rxBT.mmInputStream.close();
}
catch (Exception e) {Log.e("BOSON", e.getMessage());}
rxBT.mmInputStream = null;
}
if (rxBT.mmOutputStream != null)
{
try
{
rxBT.mmOutputStream.close();
}
catch (Exception e) {Log.e("BOSON", e.getMessage());}
rxBT.mmOutputStream = null;
}
if (rxBT.mmSocket != null)
{
try
{
rxBT.mmSocket.close();
}
catch (Exception e) {Log.e("BOSON", e.getMessage());}
rxBT.mmSocket = null;
}
if (cTask != null)
{
cTask.cancel(true);
cTask = null;
}
break;
}
return startId;
}
private class ConnectTask extends AsyncTask<String, Void, Void>
{
protected Void doInBackground(String... params)
{
try
{
BluetoothDevice mmDevice = bt.btAdpt.getRemoteDevice(params[0]);
try
{
rxBT.mmSocket = mmDevice.createInsecureRfcommSocketToServiceRecord(mmDevice.getUuids()[0].getUuid());
rxBT.mmSocket.connect();
rxBT.mmOutputStream = rxBT.mmSocket.getOutputStream();
rxBT.mmInputStream = rxBT.mmSocket.getInputStream();
Log.e("BOSON", rxBT.mmSocket.getRemoteDevice().toString());
Log.e("BOSON", rxBT.mmOutputStream.toString());
}
catch (IOException e)
{
Log.e("BOSON", "COULD NOT OPEN SOCKET CONNECTION");
}
rxBT.workerStatus = true;
Runnable rbleReceiver = new Runnable()
{
public void run()
{
final byte delimiter = '\r';
final byte[] readBuffer = new byte[1024];
int bytesAvailable;
String rxdMsgT = "";
while(rxBT.workerStatus == true)
{
try
{
if(rxBT.mmInputStream.available() > 0)
{
bytesAvailable = rxBT.mmInputStream.available();
byte[] packetBytes = new byte[bytesAvailable];
rxBT.mmInputStream.read(packetBytes);
for(int i=0;i<bytesAvailable;i++)
{
byte b = packetBytes[i];
if(b == delimiter)
{
byte[] encodedBytes = new byte[rxBT.readBufferPosition];
System.arraycopy(readBuffer, 0, encodedBytes, 0, encodedBytes.length);
final String data = new String(encodedBytes, "US-ASCII");
rxBT.readBufferPosition = 0;
rxdMsgT = "Tu: " + data + "\n";
rxBT.newData = true;
if (rxBT.newData == true)
{
Intent intent = new Intent("com.boson.BTComms.MainActivity");
intent.putExtra("Mensaje", rxdMsgT);
sendBroadcast(intent);
rxBT.newData = false;
}
}
else
{
readBuffer[rxBT.readBufferPosition++] = b;
}
}
}
else
{
//Log.e("BOSON", "INACTIVE");
}
}
catch (IOException ex)
{
rxBT.workerStatus = false;
}
}
}
};
rxBT.workerThread = new Thread(rbleReceiver);
rxBT.workerThread.start();
}
catch(Exception e)
{
Toast.makeText(BtService.this, "Could not open connection!", Toast.LENGTH_LONG).show();
Intent i = new Intent(getApplicationContext(), HomeActivity.class);
startActivity(i);
}
return null;
}
}
public void onDestroy()
{
super.onDestroy();
}
Related
I set a program to send data from the android app to a microcontroller through bluetooth using SPP. mentioned microcontroller device sends a response back after 150 milisec as processing time. My app receives an appropriate response by bluetooth response handler as RecieveBuffer.And application must send data again for the case when the microcontroller doesn't send an appropriate. I used a while conditional statement like below to send data alternatively until getting a response (send flag is true after app gets an appropriate response by bluetooth response handler class).
while(!SendFlag) SendData( SendBuffer+"\r" );
there is a program that my program sends data consecutively and Bluetooth response handler never gets any response since while statement that checks send flag(send flag is true after app gets an appropriate response).
How can I set a delay that makes my app waiting for the response? I mean I have to send data and wait for the response and if response is inacceptable I have to send data again.
without while statement, I can send data and get a response. but I have to check whether received data are acceptable too.
package com.np.schoolbell;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.icu.text.SimpleDateFormat;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.ref.WeakReference;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Timer;
import java.util.TimerTask;
import java.util.UUID;
import ir.mirrajabi.persiancalendar.PersianCalendarView;
import ir.mirrajabi.persiancalendar.core.PersianCalendarHandler;
import ir.mirrajabi.persiancalendar.core.models.PersianDate;
public class ledControl extends AppCompatActivity {
EditText et_SendData;
static TextView tv_DataReaded;
PersianCalendarView persianCalendarView;
PersianCalendarHandler calendar;
PersianDate today;
PersianDate sampleday;
List days;
String address = null;
static String TransmiterCode="999";
static String SendBuffer=null;
static String RecieveBuffer=null;
static int Counter=0;
static boolean SendFlag=false;
BluetoothAdapter bAdapter = null;
BluetoothDevice bDevice = null;
BluetoothSocket bSocket = null;
static final UUID myUUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); //SPP UUID. Look for it
ConnectedThread cThread;
private static BluetoothResponseHandler brHandler;
private final static int DataIsReady = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_led_control);
persianCalendarView = (PersianCalendarView)findViewById(R.id.persian_calendar2);
calendar = persianCalendarView.getCalendar();
today = calendar.getToday();
//days=calendar.getDays(1);
//Toast.makeText(this, days.toString(), Toast.LENGTH_LONG).show();
//today.setDate(1398,05,01);
//Toast.makeText(this, today.toString(), Toast.LENGTH_LONG).show();
et_SendData = (EditText) findViewById(R.id.et_SendData);
tv_DataReaded = (TextView) findViewById(R.id.tv_DataReaded);
address = getIntent().getStringExtra( "device_address" );
bAdapter = BluetoothAdapter.getDefaultAdapter();
try {
Toast.makeText(getApplicationContext(), "Connecting...", Toast.LENGTH_SHORT).show();
if( bSocket == null ) {
bDevice = bAdapter.getRemoteDevice(address);
bSocket = bDevice.createInsecureRfcommSocketToServiceRecord(myUUID);
bAdapter.cancelDiscovery();
bSocket.connect();
}
Toast.makeText(getApplicationContext(), "Connected", Toast.LENGTH_SHORT).show();
}
catch (Exception e) {
Toast.makeText(getApplicationContext(), "Connection Failed. Is it a SPP Bluetooth? Try again.", Toast.LENGTH_SHORT).show();
finish();
}
cThread = new ConnectedThread(bSocket);
cThread.start();
if (brHandler == null) brHandler = new BluetoothResponseHandler(this);
else brHandler.setTarget(this);
}
public void onClick_btn_SendData( View v ) {
SendBuffer=LoadDateTimeBuffer();
while(!SendFlag) SendData( SendBuffer+"\r" );
SendBuffer=LoadAZanSetting();
while(!SendFlag) SendData( SendBuffer+"\r" );
et_SendData.setText("");
}
public String LoadDateTimeBuffer(){
SendFlag=false;
TransmiterCode="420";
SimpleDateFormat sdf = new SimpleDateFormat("HHmmss", Locale.getDefault());
String currentTime = sdf.format(new Date());
String currentDate=ParseFaDigits.convert(calendar.formatNumber(today.getYear()))+ParseFaDigits.convert(calendar.formatNumber(today.getMonth()))+ParseFaDigits.convert(calendar.formatNumber(today.getDayOfMonth()));
return TransmiterCode+currentTime+currentDate;
}
public String LoadAZanSetting(){
SendFlag=false;
TransmiterCode="421";
boolean fajrflag=true;boolean tolueflag=true;boolean zuhrflag=true;boolean maghribflag=true;boolean ishaflag=true;
String FajrFlagString = (fajrflag) ? "1" : "0";
String TolueFlagString = (tolueflag) ? "1" : "0";
String ZuhrFlagString = (zuhrflag) ? "1" : "0";
String MaghribFlagString = (maghribflag) ? "1" : "0";
String IshaFlagString = (ishaflag) ? "1" : "0";
return TransmiterCode+FajrFlagString+TolueFlagString+ZuhrFlagString+MaghribFlagString+IshaFlagString;
}
public void SendData(String Data) {
if( bSocket != null ) {
try {
bSocket.getOutputStream().write(Data.getBytes());
}
catch (Exception e) {
Toast.makeText(getApplicationContext(), "Error in Send Data", Toast.LENGTH_LONG).show();
}
}
else {
Toast.makeText(getApplicationContext(), "Bluetooth is Not Connected", Toast.LENGTH_LONG).show();
}
}
#Override
protected void onDestroy() {
super.onDestroy();
if( bSocket == null ) return;
if( bSocket.isConnected() ) {
Disconnect();
}
}
public void onClick_Bluetooth_btn_Disconnect( View v ) {
Disconnect();
}
public void Disconnect() {
if ( bSocket != null && bSocket.isConnected() ) {
try {
bSocket.close();
Toast.makeText(getApplicationContext(), "Disconnected", Toast.LENGTH_SHORT).show();
}
catch( IOException e ) {
Toast.makeText(getApplicationContext(), "Error in Disconnecting ", Toast.LENGTH_SHORT).show();
}
}
finish();
}
public static class ConnectedThread extends Thread {
private BluetoothSocket mmSocket;
private InputStream mmInStream;
private OutputStream mmOutStream;
public ConnectedThread(BluetoothSocket socket) {
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
// Get the input and output streams, using temp objects because member streams are final
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
//Tell other phone that we have connected
write("connected".getBytes());
}
public void run() {
byte[] buffer = new byte[512];
int bytes;
StringBuilder readMessage = new StringBuilder();
while( !this.isInterrupted() ) {
try {
bytes = mmInStream.read(buffer);
String readed = new String(buffer, 0, bytes);
readMessage.append(readed);
if (readed.contains("\r")) {
brHandler.obtainMessage(ledControl.DataIsReady, bytes, -1, readMessage.toString()).sendToTarget();
readMessage.setLength(0);
}
} catch (Exception e) {
break;
}
}
}
// Call this from the main activity to send data to the remote device
public void write(byte[] bytes) {
try {
mmOutStream.write(bytes);
} catch (IOException e) {
e.printStackTrace();
}
}
// Call this from the main activity to shutdown the connection
public void cancel() {
if (mmInStream != null) {
try {mmInStream.close();} catch (Exception e) {}
mmInStream = null;
}
if (mmOutStream != null) {
try {mmOutStream.close();} catch (Exception e) {}
mmOutStream = null;
}
if (mmSocket != null) {
try {mmSocket.close();} catch (Exception e) {}
mmSocket = null;
}
this.interrupt();
}
}
private static class BluetoothResponseHandler extends Handler {
private WeakReference<ledControl> mActivity;
public BluetoothResponseHandler(ledControl activity) {
mActivity = new WeakReference<ledControl>(activity);
}
public void setTarget(ledControl target) {
mActivity.clear();
mActivity = new WeakReference<ledControl>(target);
}
#Override
public void handleMessage(Message msg) {
ledControl activity = mActivity.get();
String Data = (String)msg.obj;
if (activity != null) {
switch (msg.what) {
case DataIsReady :
if( Data == null ) return;
RecieveBuffer=Data;
if(RecieveBuffer.contains(SendBuffer))
{
tv_DataReaded.append(Data);
SendFlag=true;
TransmiterCode="";
SendBuffer="";
RecieveBuffer="";
}
else
{
SendFlag=false;
}
break;
}
}
}
}
}
Thank you a lot in advance.
I found a way to solve the mentioned problem so that I applied a CountDownTimer which sends data every 1 sec through 3 sec and the timer will be canceled due to avoid wasting time if sent data and response are ok both. in regular conditions, this timer sends data once since the application receives an appropriate response.
SendBuffer=LoadDateTimeBuffer();
CountDownTimer yourCountDownTimer=new CountDownTimer(3000, 1000) {
public void onFinish() {
Toast.makeText(ledControl.this, "Error", Toast.LENGTH_SHORT).show();
}
public void onTick(long millisUntilFinished) {
// millisUntilFinished The amount of time until finished.
if(!SendFlag)SendData( SendBuffer+"\r" );
else {Toast.makeText(ledControl.this, "sent", Toast.LENGTH_SHORT).show();this.cancel();}
}
}.start();
Tried using native access to implement a bluetooth functionality in android but on starting the app on a device it seems the native access variable is null. Need help in figuring out why it happened and how to solve it. Thanks
These are my build hints
An example of usage in StateMachine class
BTNative nativeBT = (BTNative)NativeLookup.create(BTNative.class);
#Override
protected void onMain_ScanButtonAction(Component c, ActionEvent event) {
super.onMain_ScanButtonAction(c, event);
try {
if (nativeBT != null && nativeBT.isSupported()) {
try {
nativeBT.findBT();
nativeBT.openBT();
} catch (Throwable t) {
Dialog.show("Error", "Exception during findBT and openBT access: " + t, "OK", null);
}
}else{
Dialog.show("Error", "Can't get native access", "OK", null);
}
} catch (Throwable t) {
Dialog.show("Error", "Exception during native access: " + t, "OK", null);
}
}
NativeImpl
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Intent;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Set;
import java.util.UUID;
import android.widget.Toast;
public class BTNativeImpl{
//android built in classes for bluetooth operations
BluetoothAdapter mBluetoothAdapter;
BluetoothSocket mmSocket;
BluetoothDevice mmDevice;
//needed for communication to bluetooth device / network
OutputStream mmOutputStream;
InputStream mmInputStream;
Thread workerThread;
byte[] readBuffer;
int readBufferPosition;
volatile boolean stopWorker;
public void closeBT() {
try {
stopWorker = true;
mmOutputStream.close();
mmInputStream.close();
mmSocket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
//this will send text data to be printed by the bluetooth printer
public void sendData(String param){
try {
// the text typed by the user
param += "\n";
mmOutputStream.write(param.getBytes());
// tell the user data were sent
} catch (Exception e) {
e.printStackTrace();
}
}
//this will find a bluetooth printer device
public void findBT() {
try {
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter == null) {
Toast.makeText(com.codename1.impl.android.AndroidNativeUtil.getActivity(), "No bluetooth adapter available", Toast.LENGTH_LONG).show();
}
if (!mBluetoothAdapter.isEnabled()) {
Intent enableBluetooth = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
com.codename1.impl.android.AndroidNativeUtil.getActivity().startActivityForResult(enableBluetooth, 0);
}
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
if (pairedDevices.size() > 0) {
for (BluetoothDevice device : pairedDevices) {
if (device.getName().equals("BlueTooth Printer")) {
mmDevice = device;
break;
}
}
}
Toast.makeText(com.codename1.impl.android.AndroidNativeUtil.getActivity(), "Bluetooth device found.", Toast.LENGTH_LONG).show();
} catch (Exception e) {
e.printStackTrace();
}
}
public void openBT() {
try {
//Standard SerialPortService ID
UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb");
mmSocket = mmDevice.createRfcommSocketToServiceRecord(uuid);
mmSocket.connect();
mmOutputStream = mmSocket.getOutputStream();
mmInputStream = mmSocket.getInputStream();
beginListenForData();
Toast.makeText(com.codename1.impl.android.AndroidNativeUtil.getActivity(), "Bluetooth Opened", Toast.LENGTH_LONG).show();
} catch (Exception e) {
e.printStackTrace();
}
}
public void beginListenForData() {
try {
final Handler handler = new Handler();
//this is the ASCII code for a newline character
final byte delimiter = 10;
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);
// specify US-ASCII encoding
final String data = new String(encodedBytes, "US-ASCII");
readBufferPosition = 0;
// tell the user data were sent to bluetooth printer device
handler.post(new Runnable() {
public void run() {
Toast.makeText(com.codename1.impl.android.AndroidNativeUtil.getActivity(), data, Toast.LENGTH_LONG).show();
}
});
} else {
readBuffer[readBufferPosition++] = b;
}
}
}
} catch (IOException ex) {
stopWorker = true;
}
}
}
});
workerThread.start();
} catch (Exception e) {
e.printStackTrace();
}
}
public boolean isSupported() {
return true;
}
}
You likely also need BLUETOOTH_ADMIN permission. I'm not sure if that is the only issue, but definitely would cause problems.
From Android's developer guide:
https://developer.android.com/guide/topics/connectivity/bluetooth.html#Permissions
You also made a big mistake in changing the inheritance of the impl class to derive Activity!
You need to create a separate activity class and register it separately as we create the impl class and Android creates the activity class and both are different. I suggest looking at other cn1libs most of which are open source to see how this was done. I also suggest connecting your device with a cable and viewing output in ddms to track issues.
I want to record the android click event when I use other apps. For each click, I record its timestamp. So, this app should run background. I use the "getevent" to catch the click event. I am not very familiar with Android operation. My code
has a bug. Its output is not very good, there are many "null"s in the output, and the record is not exactly right.(My app needs root permission)
1.MainActivity.java
package kingofne.seu.edu.ndktest;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private EditText editText = null;
private TextView textView = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editText = (EditText) findViewById(R.id.editText);
textView = (TextView) findViewById(R.id.textView);
Button btn_start = (Button) findViewById(R.id.btn_start);
if (btn_start != null) {
btn_start.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setClass(getApplicationContext(), MyService.class);
int param = 1;
if (editText != null) {
param = Integer.valueOf(String.valueOf(editText.getText()));
}
intent.putExtra("param", param);
startService(intent);
Toast.makeText(getApplicationContext(), "start", Toast.LENGTH_SHORT).show();
textView.setText(String.valueOf(System.currentTimeMillis()));
}
});
}
Button btn_stop = (Button) findViewById(R.id.btn_stop);
if (btn_stop != null) {
btn_stop.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setClass(getApplicationContext(), MyService.class);
stopService(intent);
Toast.makeText(getApplicationContext(), "stop", Toast.LENGTH_SHORT).show();
}
});
}
}
}
2.MyService.java
package kingofne.seu.edu.ndktest;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.text.SimpleDateFormat;
import java.util.Date;
public class MyService extends Service {
private boolean isRunning = false;
private int param = 1;
private Thread captureThread = null;
private volatile boolean doCapture = false;
public MyService() {
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (isRunning) {
return START_NOT_STICKY;
}
param = intent.getIntExtra("param", 1);
this.captureThread = new Thread(new Producer());
captureThread.setDaemon(true);
this.doCapture = true;
captureThread.start();
isRunning = true;
return START_NOT_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
// stop the thread
this.doCapture = false;
// destroy the thread
this.captureThread = null;
}
private class Producer implements Runnable {
public void run() {
Log.d("ps", "going to run");
Date now = new Date();
SimpleDateFormat sDateFormat = new SimpleDateFormat(
"yyyy-MM-dd-HH-mm-ss");
String str2 = sDateFormat.format(now);
// String location = str2;
//String cmdLine = "getevent -t -l /dev/input/event" + String.valueOf(param) + " > /sdcard/guo" + ".txt";
String cmdLine = "cat /dev/input/event" + String.valueOf(param) + " > /sdcard/guo.txt";
CMDExecute cmd = new CMDExecute();
try {
// cmd.run_su("getevent -t > /sdcard/Yang_"+location+".txt");
cmd.run_su(cmdLine);
} catch (IOException e) {
// TODO Auto-generated catch block
Log.d("ps", "error");
e.printStackTrace();
}
}
};
class CMDExecute {
public synchronized String run(String[] cmd, String workdirectory)
throws IOException {
String result = "";
try {
ProcessBuilder builder = new ProcessBuilder(cmd);
BufferedReader in = null;
// 设置一个路径
if (workdirectory != null) {
builder.directory(new File(workdirectory));
builder.redirectErrorStream(true);
Process process = builder.start();
process.waitFor();
in = new BufferedReader(new InputStreamReader(process
.getInputStream()));
char[] re = new char[1024];
int readNum;
while ((readNum = in.read(re, 0, 1024)) != -1) {
// re[readNum] = '\0';
result = result + new String(re, 0, readNum);
}
}
if (in != null) {
in.close();
}
} catch (Exception ex) {
ex.printStackTrace();
}
return result;
}
public synchronized String run_su(String cmd)
throws IOException {
String result = "";
Process p=null;
try {
p = Runtime.getRuntime().exec("su");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
DataOutputStream os = new DataOutputStream(p.getOutputStream());
BufferedReader is = new BufferedReader(new InputStreamReader(p.getInputStream()));
try {
String istmp;
os.writeBytes(cmd+"\n");
//os.writeBytes("exit\n");
os.flush();
os.writeBytes("exit\n");
os.flush();
p.waitFor();
is.close();
os.close();
p.destroy();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} return result;
}
}
}
I have created an application which gives statistics for the UDP packet loss in android. This is my architecture of the applications.
1) An application which multicast the UDP packets. Below is the code for it:
package rockwell.multicastserverproj;
import android.content.Context;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
public class MainActivity extends AppCompatActivity {
EditText txtMsg;
EditText txtPackets;
EditText txtMs;
EditText txtBytes;
EditText txtCount;
byte[] rtpData;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
/*Thread thrClient = new Thread(new ReceiveMulticast());
thrClient.start();*/
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public void onBtnClicked(View view)
{
Thread threadTotalPackets = new Thread(new SendMulticast());
threadTotalPackets.start();
Thread thread = new Thread(new MulticastPackets());
thread.start();
//Toast.makeText(this,"Message multicasted",Toast.LENGTH_LONG).show();
}
public class MulticastPackets implements Runnable{
#Override
public void run() {
InetAddress group = null;
MulticastSocket multiSocket = null;
int PORT = 6500;
txtPackets =(EditText)findViewById(R.id.txtPackets);
txtMs = (EditText)findViewById(R.id.txtMs);
txtBytes = (EditText)findViewById(R.id.txtBytes);
txtCount = (EditText)findViewById(R.id.txtCount);
int noOfPackets = Integer.parseInt(txtPackets.getText().toString());
int delayMS = Integer.parseInt(txtMs.getText().toString());
int packetSize = Integer.parseInt(txtBytes.getText().toString());
int cntPacket = Integer.parseInt(txtCount.getText().toString());
WifiManager wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
WifiManager.MulticastLock mLock = wifi.createMulticastLock("mylock");
mLock.acquire();
try{
group = InetAddress.getByName("230.0.0.1");
multiSocket = new MulticastSocket(PORT);
} catch (IOException e) {
e.printStackTrace();
}
for(int pcktCnt=1; pcktCnt<=noOfPackets; pcktCnt++) {
rtpData = new byte[packetSize];
int cnt = unsigned_int(pcktCnt);
byte[] seqArr = null;
seqArr = toBytes(cnt);
byte varFirst = 0xa;
byte varSecond = 0x5;
for(int i=4;i<packetSize;i+=2)
{
if(i%4 ==0) {
rtpData[i] = varFirst;
rtpData[i + 1] = varFirst;
}
else {
rtpData[i] = varSecond;
rtpData[i + 1] = varSecond;
}
}
for(int i=0;i<4;i++)
{
rtpData[i] = seqArr[i];
}
DatagramPacket requestPacket = new DatagramPacket(rtpData, rtpData.length, group, PORT);
try {
for(int i=0;i<cntPacket;i++) {
multiSocket.send(requestPacket);
Thread.sleep(delayMS, 0);
}
int test = fromByteArray(seqArr);
Log.i("Multicast", "Packet send. Sequence number is: " + test);
} catch (Exception e) {
e.printStackTrace();
}
int test = fromByteArray(seqArr);
}
try{
multiSocket.leaveGroup(group);
multiSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
mLock.release();
MainActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(MainActivity.this,"Packet sent",Toast.LENGTH_LONG).show();
}
});
}
}
public class SendMulticast implements Runnable{
#Override
public void run() {
InetAddress group = null;
MulticastSocket multiSocket = null;
int PORT = 5500;
txtPackets =(EditText)findViewById(R.id.txtPackets);
txtBytes = (EditText)findViewById(R.id.txtBytes);
String requestString = txtPackets.getText().toString();
String strPackSize = txtBytes.getText().toString();
requestString = requestString +";" + strPackSize;
Log.i("reqstring",requestString);
byte[] requestData = new byte[requestString.length()];
requestData = requestString.getBytes();
WifiManager wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
WifiManager.MulticastLock mLock = wifi.createMulticastLock("mylock");
mLock.acquire();
try{
group = InetAddress.getByName("230.0.0.1");
multiSocket = new MulticastSocket(PORT);
multiSocket.joinGroup(group);
} catch (IOException e) {
e.printStackTrace();
}
try{
DatagramPacket requestPacket = new DatagramPacket(requestData, requestData.length, group, PORT);
multiSocket.send(requestPacket);
Log.i("multicastproj","message multicasted");
} catch (IOException e) {
e.printStackTrace();
}
try{
multiSocket.leaveGroup(group);
multiSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
mLock.release();
}
}
static int unsigned_int(int nb) {
if (nb >= 0)
return (nb);
else
return (256 + nb);
}
public byte[] toBytes(int i)
{
byte[] result = new byte[4];
result[0] = (byte) (i >> 24);
result[1] = (byte) (i >> 16);
result[2] = (byte) (i >> 8);
result[3] = (byte) (i /*>> 0*/);
return result;
}
public int fromByteArray(byte[] bytes) {
return bytes[0] << 24 | (bytes[1] & 0xFF) << 16 | (bytes[2] & 0xFF) << 8 | (bytes[3] & 0xFF);
}
public class ReceiveMulticast implements Runnable{
#Override
public void run() {
byte[] requestData = new byte[1024];
InetAddress group = null;
MulticastSocket multiSocket = null;
int PORT = 4500;
WifiManager wifi = (WifiManager) getSystemService(getApplicationContext().WIFI_SERVICE);
WifiManager.MulticastLock mLock = wifi.createMulticastLock("mylock");
mLock.acquire();
try{
group = InetAddress.getByName("230.0.0.1");
multiSocket = new MulticastSocket(PORT);
multiSocket.joinGroup(group);
} catch (IOException e) {
e.printStackTrace();
}
try{
while(true)
{
DatagramPacket requestPacket = new DatagramPacket(requestData, requestData.length);
multiSocket.receive(requestPacket);
String requestString = new String(requestPacket.getData(), 0, requestPacket.getLength());
Log.d("CreateMulticastServer", "Got request = " + requestString);
/*txtMsg = (EditText)findViewById(R.id.txtMsg);
txtMsg.setText(requestString);*/
}
} catch (IOException e) {
e.printStackTrace();
}
try{
multiSocket.leaveGroup(group);
multiSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
mLock.release();
}
}
}
Another application which receives those multicast UDP packets
Service which runs continuously and receives the multicast packet:
package rockwell.packetstatistics;
import android.app.IntentService;
import android.content.Context;
import android.content.Intent;
import android.net.wifi.WifiManager;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
/**
* Created by mmjoshi on 2/10/2016.
*/
public class PacketReceive_Service extends IntentService {
boolean flag = true;
int packetSize = 0;
public PacketReceive_Service() {
super("PacketReceive_Service");
}
#Override
protected void onHandleIntent(Intent intent) {
String strVar = intent.getStringExtra("vari");
Log.i("onstartservice","string is " + strVar);
Thread thread = new Thread(new PacketThread());
thread.setPriority(Thread.MAX_PRIORITY);
thread.start();
Thread thread1 = new Thread(new TotalPackets());
thread1.start();
}
public class PacketThread implements Runnable
{
#Override
public void run() {
InetAddress group = null;
MulticastSocket multiSocket = null;
WifiManager.MulticastLock mLock = null;
int prevSeqNo=0;
String strMissingPackets="";
int TotalpacketsReceived = 0;
try {
if(packetSize == 0)
packetSize = 1036;
byte[] requestData = new byte[packetSize];
int PORT = 6500;
byte varFirst = 0xa;
byte varSecond = 0x5;
WifiManager wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
mLock = wifi.createMulticastLock("mylock");
mLock.setReferenceCounted(true);
mLock.acquire();
try{
group = InetAddress.getByName("230.0.0.1");
multiSocket = new MulticastSocket(PORT);
multiSocket.joinGroup(group);
} catch (IOException e) {
e.printStackTrace();
}
while (flag) {
final DatagramPacket requestPacket = new DatagramPacket(requestData, requestData.length);
multiSocket.receive(requestPacket);
byte[] resultData = requestPacket.getData();
byte[] seqArr = new byte[4];
for(int i=0;i<4;i++){
seqArr[i] = resultData[i];
}
int seqNo = fromByteArray(seqArr);
Log.i("RecvPackets","multiple packet received # is: " + seqNo);
if(prevSeqNo!=seqNo)
{
TotalpacketsReceived++;
if(prevSeqNo!=0)
{
if((seqNo - prevSeqNo)>1)
{
for(int k=(prevSeqNo+1);k<seqNo;k++)
{
strMissingPackets += k + ", ";
sendResultMessage("Missing;" + String.valueOf(k));
Log.i("RecvPackets","Packet missing. Missing# is: " + k);
}
}
}
for(int i=4;i<packetSize;i+=2)
{
if(i%4 ==0) {
if(resultData[i] != varFirst || resultData[i+1] != varFirst)
{
if(seqNo != 1) {
sendResultMessage("DataError;" + String.valueOf(seqNo));
Log.i("DataCheck", "Error in data");
}
}
}
else {
if(resultData[i] != varSecond || resultData[i+1] != varSecond)
{
if(seqNo != 1) {
sendResultMessage("DataError;" + String.valueOf(seqNo));
Log.i("DataCheck", "Error in data");
}
}
}
}
prevSeqNo = seqNo;
Log.i("MulticastService", "Packet size is: " + packetSize + " Packet receive. Sequence number is: " + seqNo);
sendResultMessage("TotalPacketsReceived;" + String.valueOf(TotalpacketsReceived));
}
}
} catch (IOException e) {
Log.i("DEU Service", "In cache");
flag = false;
e.printStackTrace();
}
finally {
try {
if(multiSocket != null) {
if(group != null)
multiSocket.leaveGroup(group);
multiSocket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
if(mLock != null)
mLock.release();
}
}
}
private void sendResultMessage(String strPacks) {
Intent intent = new Intent("intData");
intent.putExtra("result",strPacks);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
private void sendTotalPackets(String strPacks) {
Intent intent = new Intent("intPacket");
intent.putExtra("result",strPacks);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
public int fromByteArray(byte[] bytes) {
return bytes[0] << 24 | (bytes[1] & 0xFF) << 16 | (bytes[2] & 0xFF) << 8 | (bytes[3] & 0xFF);
}
public class TotalPackets implements Runnable{
#Override
public void run() {
byte[] requestData = new byte[1024];
InetAddress group = null;
MulticastSocket multiSocket = null;
int PORT = 5500;
WifiManager wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
WifiManager.MulticastLock mLock = wifi.createMulticastLock("mylock");
mLock.acquire();
try{
group = InetAddress.getByName("230.0.0.1");
multiSocket = new MulticastSocket(PORT);
multiSocket.joinGroup(group);
} catch (IOException e) {
e.printStackTrace();
}
try{
while(true)
{
DatagramPacket requestPacket = new DatagramPacket(requestData, requestData.length);
multiSocket.receive(requestPacket);
String requestString = new String(requestPacket.getData(), 0, requestPacket.getLength());
Log.i("requestString",requestString);
String[] spltStr = requestString.split(";");
packetSize = Integer.parseInt(spltStr[1].toString());
Log.i("service","Packet size is: " + spltStr[1].toString() + " Total Packs: " + spltStr[0]);
sendTotalPackets(spltStr[0].toString());
/*txtMsg = (EditText)findViewById(R.id.txtMsg);
txtMsg.setText(requestString);*/
}
} catch (IOException e) {
e.printStackTrace();
}
try{
multiSocket.leaveGroup(group);
multiSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
mLock.release();
}
}
}
So, my question is, at the service side when I receives the packet mostly 5-7% of packets are loss. It means, if I send 1000 packets of 512 bytes at 5ms of interval 50-70 packet losses at the receiving end.
Is there a way I can reduce this packet loss? Or Is there any chances of my code for improvement so that packet loss can be reduced?
Thanks in advance.
There's not much you can do.
UDP is a transport layer that does not have delivery guarantees.
Packet loss over wifi will vary based on the different makes/models/configurations of the access points and the device it runs on.
For example, 5ghz may perform better as the air waves are usually cleaner but it does not penetrate through walls as well as 2.4 ghz.
Not all Android devices use the same wifi radios.
You can actually get practically 0% packet loss if you use an access point that does multicast to unicast conversion at the MAC layer. So you use UDP in your application software. Then the access point internally does retransmissions at the 802.11 layer. For example, Cisco, and Xirrus have multicast to unicast conversion options and yield practically 0% packet loss. However, there is a price to pay as it does not scale very well because each multicast stream is sent individually to each subscribed device.
Well... What can you do in software....
Ways to "deal" with packet loss in multicast:
Forward error correction.
You can send each packet twice. AABBCCDDEE
You can send each packet twice but delayed: ABACBDCED
You can send part of the data twice: AABCCDE
Any forward error correction scheme ads more bandwidth and also increases latency.
Loss concealment
You can try to estimate the data between losses.
You haven't really stated your application so it is difficult to make suggestions on dealing with losses. With your 5ms limitation, it sounds like you are transmitting 240 frame packets of 48khz audio.
Did you try to increase the interval to >5ms? Also did you try to test this application where there was no kind of interference for wifi?
I am trying to debug an app with eclipse. I am using the USB to connect to an accessory so USB in not Available to debug. I am using ADB connect to wirelessly debug, but with this app I have to unplug and plug in USB cable to get app to run and when I do this I lose connection to eclipse.
SO the only thing I can think is to try and use Toast to figure out what is going on in a class.
Maybe there is a better way?
But When I try to call toast app crashes.. I want to be able to toast messages in vaious methods like BroadcastReceiver, and ResumeAccessory
Call anyone tell me how to implement toast in this class?:
//
User must modify the below package with their package name
package com.UARTDemo;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.usb.UsbAccessory;
import android.hardware.usb.UsbManager;
import android.os.Handler;
import android.os.Message;
import android.os.ParcelFileDescriptor;
import android.util.Log;
/******************************FT311 GPIO interface class******************************************/
public class FT311UARTInterface extends Activity
{
private static final String ACTION_USB_PERMISSION = "com.UARTDemo.USB_PERMISSION";
public UsbManager usbmanager;
public UsbAccessory usbaccessory;
public PendingIntent mPermissionIntent;
public ParcelFileDescriptor filedescriptor;
public FileInputStream inputstream;
public FileOutputStream outputstream;
public boolean mPermissionRequestPending = true;
public handler_thread handlerThread;
private byte [] usbdata;
private byte [] writeusbdata;
private byte [] readBuffer; /*circular buffer*/
private int readcount;
private int totalBytes;
private int writeIndex;
private int readIndex;
private byte status;
private byte maxnumbytes = (byte)64;
public boolean datareceived = false;
/*constructor*/
public FT311UARTInterface(Context context){
super();
/*shall we start a thread here or what*/
usbdata = new byte[64];
writeusbdata = new byte[64];
/*128(make it 256, but looks like bytes should be enough)*/
readBuffer = new byte [maxnumbytes];
readIndex = 0;
writeIndex = 0;
/***********************USB handling******************************************/
usbmanager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
// Log.d("LED", "usbmanager" +usbmanager);
mPermissionIntent = PendingIntent.getBroadcast(context, 0, new Intent(ACTION_USB_PERMISSION), 0);
IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
filter.addAction(UsbManager.ACTION_USB_ACCESSORY_DETACHED);
context.registerReceiver(mUsbReceiver, filter);
inputstream = null;
outputstream = null;
}
/*reset method*/
public void Reset()
{
/*create the packet*/
writeusbdata[0] = 0x49;
writeusbdata[1] = 0x00;
writeusbdata[2] = 0x00;
writeusbdata[3] = 0x00;
/*send the packet over the USB*/
SendPacket(4);
}
public void SetConfig(int baud, byte dataBits, byte stopBits,
byte parity, byte flowControl)
{
/*prepare the baud rate buffer*/
writeusbdata[0] = (byte)baud;
writeusbdata[1] = (byte)(baud >> 8);
writeusbdata[2] = (byte)(baud >> 16);
writeusbdata[3] = (byte)(baud >> 24);
/*data bits*/
writeusbdata[4] = dataBits;
/*stop bits*/
writeusbdata[5] = stopBits;
/*parity*/
writeusbdata[6] = parity;
/*flow control*/
writeusbdata[7] = flowControl;
/*send the UART configuration packet*/
SendPacket((int)8);
}
/*write data*/
public byte SendData(byte numBytes, char[] buffer)
{
status = 0x00; /*success by default*/
/*
* if num bytes are more than maximum limit
*/
if(numBytes < 1){
/*return the status with the error in the command*/
return status;
}
/*check for maximum limit*/
if(numBytes > 64){
numBytes = 64;
}
/*prepare the packet to be sent*/
for(int count = 0;count<numBytes;count++)
{
writeusbdata[count] = (byte)buffer[count];
}
SendPacket((int)numBytes);
return status;
}
/*read data*/
public byte ReadData(byte numBytes,char[] buffer, byte [] actualNumBytes)
{
status = 0x00; /*success by default*/
/*should be at least one byte to read*/
if((numBytes < 1) || (totalBytes == 0)){
actualNumBytes[0] = 0x00;
return status;
}
/*check for max limit*/
if(numBytes > 64){
numBytes = 64;
}
if(numBytes > 64){
numBytes = 64;
}
if(numBytes > totalBytes)
numBytes = (byte)totalBytes;
/*update the number of bytes available*/
totalBytes -= numBytes;
actualNumBytes[0] = numBytes;
/*copy to the user buffer*/
for(int count = 0; count<numBytes;count++)
{
buffer[count] = (char)readBuffer[readIndex];
readIndex++;
/*shouldnt read more than what is there in the buffer,
* so no need to check the overflow
*/
readIndex %= maxnumbytes;
}
return status;
}
/*method to send on USB*/
private void SendPacket(int numBytes)
{
try {
if(outputstream != null){
outputstream.write(writeusbdata, 0,numBytes);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/*resume accessory*/
public void ResumeAccessory()
{
// Intent intent = getIntent();
if (inputstream != null && outputstream != null) {
return;
}
UsbAccessory[] accessories = usbmanager.getAccessoryList();
UsbAccessory accessory = (accessories == null ? null : accessories[0]);
if (accessory != null) {
if (usbmanager.hasPermission(accessory)) {
OpenAccessory(accessory);
}
else
{
synchronized (mUsbReceiver) {
if (!mPermissionRequestPending) {
usbmanager.requestPermission(accessory,
mPermissionIntent);
mPermissionRequestPending = true;
}
}
}
} else {}
}
/*destroy accessory*/
public void DestroyAccessory(){
unregisterReceiver(mUsbReceiver);
CloseAccessory();
}
/*********************helper routines*************************************************/
public void OpenAccessory(UsbAccessory accessory)
{
filedescriptor = usbmanager.openAccessory(accessory);
if(filedescriptor != null){
usbaccessory = accessory;
FileDescriptor fd = filedescriptor.getFileDescriptor();
inputstream = new FileInputStream(fd);
outputstream = new FileOutputStream(fd);
/*check if any of them are null*/
if(inputstream == null || outputstream==null){
return;
}
}
handlerThread = new handler_thread(handler, inputstream);
handlerThread.start();
}
private void CloseAccessory()
{
try{
if(filedescriptor != null)
filedescriptor.close();
}catch (IOException e){}
try {
if(inputstream != null)
inputstream.close();
} catch(IOException e){}
try {
if(outputstream != null)
outputstream.close();
}catch(IOException e){}
/*FIXME, add the notfication also to close the application*/
filedescriptor = null;
inputstream = null;
outputstream = null;
System.exit(0);
}
/***********USB broadcast receiver*******************************************/
private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver()
{
#Override
public void onReceive(Context context, Intent intent)
{
String action = intent.getAction();
if (ACTION_USB_PERMISSION.equals(action))
{
synchronized (this)
{
UsbAccessory accessory = (UsbAccessory) intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false))
{
OpenAccessory(accessory);
}
else
{
Log.d("LED", "permission denied for accessory "+ accessory);
}
mPermissionRequestPending = false;
}
}
else if (UsbManager.ACTION_USB_ACCESSORY_DETACHED.equals(action))
{
UsbAccessory accessory = (UsbAccessory)intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
if (accessory != null )//&& accessory.equals(usbaccessory))
{
CloseAccessory();
}
}else
{
Log.d("LED", "....");
}
}
};
final Handler handler = new Handler()
{
#Override
public void handleMessage(Message msg)
{
for(int count = 0;count<readcount;count++){
readBuffer[writeIndex] = usbdata[count];
/*move to the next write location*/
writeIndex++;
writeIndex %= maxnumbytes;
/*FIXME,check for overflow*/
//if(writeIndex == readIndex){
//}
}
/*caluclate the available bytes to read*/
if(writeIndex >= readIndex)
totalBytes = writeIndex-readIndex;
else
totalBytes = (maxnumbytes-readIndex)+writeIndex;
}
};
/*usb input data handler*/
private class handler_thread extends Thread {
Handler mHandler;
FileInputStream instream;
handler_thread(Handler h,FileInputStream stream ){
mHandler = h;
instream = stream;
}
public void run()
{
while(true)
{
Message msg = mHandler.obtainMessage();
try{
if(instream != null)
{
readcount = instream.read(usbdata,0,64);
if(readcount > 0)
{
datareceived = true;
msg.arg1 = usbdata[0];
msg.arg2 = usbdata[1];
}
mHandler.sendMessage(msg);
}
}catch (IOException e){}
}
}
}
}
Its better to use Log.d(TAG, text)
OR
In any subclass of activity you can do:
Toast.makeText(getApplicationContext(), "text", Toast.LENGTH_LONG).show();