如果出现任何新数据,此函数从usb设备获取usb数据:
gpiointerface.java
//usb input data handler
private class handler_thread extends Thread {
FileInputStream instream;
handler_thread(FileInputStream stream ){
instream = stream;
}
public void run()
{
while(READ_ENABLE)
{
try{
if(instream != null)
{
readcount = instream.read(usbdata,0,4);
}
}catch (IOException e){}
}
}
}
我可以使用此功能到达usbdata
:
/*read port*/
public byte ReadPort(){
return usbdata[1];
}
我想要实现的目标是:
如果handler_thread
读取了任何新数据,我想立即将新数据发送到MainActivity并显示在用户界面中。
我想出了这个AsyncTask但是在新数据出现后它没有在UI中显示新数据。
MainActivity.java
class usbrun extends AsyncTask<Byte, String, Byte>
{
@Override
protected Byte doInBackground(Byte... params) {
try {
inData = gpiointerface.ReadPort(); //Get usbdata
Thread.sleep(100);
} catch (Exception e) {
e.printStackTrace();
}
return inData;
}
@Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
}
@Override
protected void onPostExecute(Byte result) {
readdata.setText(Integer.toHexString(result)); //Show in UI
Log.d("LED", "istegeldi "+ result);
}
}
完整代码
gpiointerface.java
//User must modify the below package with their package name
/******************************FT311 GPIO interface class******************************************/
public class FT311GPIOInterface extends Activity
{
private static final String ACTION_USB_PERMISSION = "com.GPIODemo.USB_PERMISSION";
public UsbManager usbmanager;
public UsbAccessory usbaccessory;
public PendingIntent mPermissionIntent;
public ParcelFileDescriptor filedescriptor;
public FileInputStream inputstream;
public FileOutputStream outputstream;
public boolean mPermissionRequestPending = false;
public boolean READ_ENABLE = true;
public handler_thread handlerThread;
private byte [] usbdata;
private byte [] writeusbdata;
private int readcount;
public byte inData;
public Context global_context;
public static String ManufacturerString = "mManufacturer=FTDI";
public static String ModelString = "mModel=FTDIGPIODemo";
public static String VersionString = "mVersion=1.0";
/*constructor*/
public FT311GPIOInterface(Context context){
super();
global_context = context;
/*shall we start a thread here or what*/
usbdata = new byte[4];
writeusbdata = new byte[4];
/***********************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 port*/
public void ResetPort()
{
writeusbdata[0] = 0x14;
writeusbdata[1] = 0x00;
writeusbdata[2] = 0x00;
writeusbdata[3] = 0x00;
new android.os.Handler().postDelayed(
new Runnable() {
public void run() {
try {
if(outputstream != null){
outputstream.write(writeusbdata,0,4);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
},
30);
}
/*read port*/
public byte ReadPort(){
Log.d("LED", "istegeldi "+ Integer.toHexString(usbdata[1] & 0xff));
return usbdata[1];
}
/*resume accessory*/
public void ResumeAccessory()
{
// Intent intent = getIntent();
if (inputstream != null && outputstream != null) {
return;
}
UsbAccessory[] accessories = usbmanager.getAccessoryList();
if(accessories != null)
{
Toast.makeText(global_context, "Accessory Attached", Toast.LENGTH_SHORT).show();
}
UsbAccessory accessory = (accessories == null ? null : accessories[0]);
if (accessory != null) {
if( -1 == accessory.toString().indexOf(ManufacturerString))
{
Toast.makeText(global_context, "Manufacturer is not matched!", Toast.LENGTH_SHORT).show();
return;
}
if( -1 == accessory.toString().indexOf(ModelString))
{
Toast.makeText(global_context, "Model is not matched!", Toast.LENGTH_SHORT).show();
return;
}
if( -1 == accessory.toString().indexOf(VersionString))
{
Toast.makeText(global_context, "Version is not matched!", Toast.LENGTH_SHORT).show();
return;
}
Toast.makeText(global_context, "Manufacturer, Model & Version are matched!", Toast.LENGTH_SHORT).show();
if (usbmanager.hasPermission(accessory)) {
OpenAccessory(accessory);
}
else
{
synchronized (mUsbReceiver) {
if (!mPermissionRequestPending) {
Toast.makeText(global_context, "Request USB Permission", Toast.LENGTH_SHORT).show();
usbmanager.requestPermission(accessory,
mPermissionIntent);
mPermissionRequestPending = true;
}
}
}
} else {}
}
/*destroy accessory*/
public void DestroyAccessory(){
READ_ENABLE = false; // set false condition for handler_thread to exit waiting data loop
// ResetPort(); // send dummy data for instream.read going
try{Thread.sleep(10);}
catch(Exception e){}
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(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))
{
Toast.makeText(global_context, "Allow USB Permission", Toast.LENGTH_SHORT).show();
OpenAccessory(accessory);
}
else
{
Toast.makeText(global_context, "Deny USB Permission", Toast.LENGTH_SHORT).show();
Log.d("LED", "permission denied for accessory "+ accessory);
}
mPermissionRequestPending = false;
}
}
else if (UsbManager.ACTION_USB_ACCESSORY_DETACHED.equals(action))
{
CloseAccessory();
}else
{
Log.d("LED", "....");
}
}
};
//usb input data handler
private class handler_thread extends Thread {
FileInputStream instream;
handler_thread(FileInputStream stream ){
instream = stream;
}
public void run()
{
while(READ_ENABLE)
{
try{
if(instream != null)
{
readcount = instream.read(usbdata,0,4);
}
}catch (IOException e){}
}
}
}
}
MainActivity.java
/*FT311 GPIO interface exposes the following methods:
* ConfigPort, WritePort and ReadPort are for user to use for port operations.
* - ConfigPort(outMap, inMap): to configure the port as input or output, with outMap and inMap
* are arguments for out bitmap and input bitmap.
* - WritePort(outData): to write the port data, with outData as argument.
* - ReadPort: to read port, it returns the current level on the input IOs.
*
* DestroyAccessory and ResumeAccessory methods should be called from
* overridden from onResume() and onDestroy routines of main activity class.
*
* - DestoryAccessory: to be called from onDestory routine of main activity class.
* - ResumeAccessory: to be called from onResume routine of main activity class.
*
*
*/
public class GPIODemoActivity extends Activity {
/*declare a FT311 GPIO interface variable*/
public FT311GPIOInterface gpiointerface;
/*button object*/
public Button readbutton;
/*text boxes for data display*/
public EditText readdata;
/*variables*/
public byte inData; /*input Data*/
public String sstt;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
/*text boxes for data display*/
readdata = (EditText)findViewById(R.id.readdata);
/**** command buttons*****/
readbutton = (Button)findViewById(R.id.readbutton);
/******************************process button presses*********************************/
/*user code to read the accessory data*/
readbutton.setOnClickListener(new View.OnClickListener() {
//@Override
public void onClick(View v) {
// TODO Auto-generated method stub
//readbutton.setBackgroundResource(drawable.start);
inData = gpiointerface.ReadPort();
readdata.setText(Integer.toHexString(inData & 0xff));
//ProcessReadData(inData);
}
});
/*create an object of GPIO interface class*/
gpiointerface = new FT311GPIOInterface(this);
resetFT311();
new usbrun().execute();
}
class usbrun extends AsyncTask<Byte, String, Byte>
{
@Override
protected Byte doInBackground(Byte... params) {
try {
inData = gpiointerface.ReadPort();
Thread.sleep(100);
} catch (Exception e) {
e.printStackTrace();
}
return inData;
}
@Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
}
@Override
protected void onPostExecute(Byte result) {
readdata.setText("asd");
}
}
protected void resetFT311(){
gpiointerface.ResetPort();
}
@Override
protected void onResume() {
// Ideally should implement onResume() and onPause()
// to take appropriate action when the activity looses focus
super.onResume();
gpiointerface.ResumeAccessory();
}
@Override
protected void onPause() {
// Ideally should implement onResume() and onPause()
// to take appropriate action when the activity looses focus
super.onPause();
}
@Override
protected void onDestroy(){
gpiointerface.DestroyAccessory();
super.onDestroy();
}
}
答案 0 :(得分:1)
抽象背景线程类:
public abstract class AbstractPollThread extends Thread {
//the default amount of bytes to read at once
public static final int DEFAULT_PACKET_SIZE = 4;
//flag indicating wether this thread should still run
private volatile boolean isFinished = false;
//the input stream to obtain bytes from
private InputStream inputStream;
//the packet size specified in constructor
private int packetSize;
//constructor using packetSize = DEFAULT_PACKET_SIZE
public AbstractPollThread(@NonNull InputStream inputStream) {
this(inputStream, DEFAULT_PACKET_SIZE);
}
//constructor using custom packetSize
public AbstractPollThread(@NonNull InputStream inputStream, int packetSize) {
this.inputStream = inputStream;
this.packetSize = packetSize;
}
//notify this Thread that it should finish
public void finish() {
isFinished = true;
interrupt();
}
//this thread's loop method
@Override
public void run() {
//loop while finish() has not been called
while (!isFinished) {
try {
//obtain the next packetSize bytes as array
//this blocks until at least packetSize bytes are available
byte[] packet = nextPacket();
//invoke abstract handle method and pass the packet we just read
handlePacket(packet);
} catch (IOException e) {
e.printStackTrace();
}
}
try {
//try to close the underlying stream
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
//Child classes need to implement this method
protected abstract void handlePacket(byte[] packet);
private byte[] nextPacket() throws IOException {
//create a new byte array of packetSize length
byte[] bytePacket = new byte[packetSize];
//read in a loop, until exactly packetSize bytes are read
int c = 0;
while (c < packetSize) {
int r = inputStream.read(bytePacket, c, packetSize - c);
if (r == -1) {
//if this stream is closed, call finish() on this Thread
finish();
} else {
//increment the index by the amount of bytes we could read at once
c += r;
}
}
//return the bytePacket we just read
return bytePacket;
}
}
实际后台线程实现:
public class BufferedPollThread extends AbstractPollThread {
//the initial capacity of the packet buffer
public static final int INITIAL_BUFFER_CAPACITY = 16;
//the read handler that wants to receive packets
private ReadHandler readHandler;
//handler hooked to the UIThread's message loop
private Handler uiThreadHandler = new Handler(Looper.getMainLooper());
//a simple list implementation acting as packetBuffer
private List<byte[]> packetBuffer = new ArrayList<>(INITIAL_BUFFER_CAPACITY);
//same constructor as in AbstractPollThread
public BufferedPollThread(@NonNull InputStream inputStream) {
super(inputStream);
}
//same constructor as in AbstractPollThread
public BufferedPollThread(@NonNull InputStream inputStream, int packetSize) {
super(inputStream, packetSize);
}
public void setReadHandler(ReadHandler readHandler) {
//set the Handler that should handle packets
this.readHandler = readHandler;
//if the buffer contains packets, push them to the readHandler
if (packetBuffer.size() > 0) {
for (byte[] packet : packetBuffer)
handlePacket(packet);
}
packetBuffer.clear();
}
public void clearReadHandler() {
//clear the reference to the Handler to avoid memory leaks
this.readHandler = null;
}
@Override
protected void handlePacket(final byte[] packet) {
//if a handler is set, push the packet directly
//otherwise add it to buffer
uiThreadHandler.post(new Runnable() {
@Override
public void run() {
if (readHandler != null)
readHandler.onReadPacket(packet);
else
packetBuffer.add(packet);
}
});
}
public interface ReadHandler {
//this is called for every packet in your custom read handler
void onReadPacket(byte[] packet);
}
}
主要活动的示例设置:
public class MainActivity extends AppCompatActivity implements BufferedPollThread.ReadHandler {
//hold the reference to the pollThread
private BufferedPollThread bufferedPollThread;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//do your setup here (FileInputStream implements InputStream, so no problems here)
InputStream usbInputStream = null; //Open the FileInputStream to USB here
//create and start the pollThread that will deliver USB read packets
bufferedPollThread = new BufferedPollThread(usbInputStream);
bufferedPollThread.start();
}
@Override
public void onDestroy() {
//if this activity is about to be destroyed, stop the background poll thread as well
bufferedPollThread.finish();
super.onDestroy();
}
@Override
public void onResume() {
super.onResume();
//if this activity is in foreground, listen to packets from USB
bufferedPollThread.setReadHandler(this);
}
@Override
public void onPause() {
//if this activity is about to be paused, stop listening to packets from USB
//this is to avoid memory leaks on configuration changes
bufferedPollThread.clearReadHandler();
super.onPause();
}
@Override
public void onReadPacket(byte[] packet) {
//This method is called on the UIThread, so you can do all your View updates here
}
}
请参阅https://github.com/newcrows/UsbExample/tree/master/app/src/main/java/com/crowsnet/usbexample了解来源