将命令发送到USB串行端口设备(COM3)并获取消息

时间:2018-03-16 10:30:53

标签: java android

您好我正在开发一个名为PetScanner的项目。当我发送" g"我必须做可以与USB串口设备通信的项目。获取在USB设备上检查我必须得到一条消息,如" 0x2A"但我无法完成该计划,因为我不知道如何继续。 请帮助我谢谢!!

这是MainActivity;

package dls.readerapp;

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.content.pm.ActivityInfo;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbManager;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbEndpoint;
import android.hardware.usb.UsbInterface;
import android.media.AudioManager;
import android.os.BatteryManager;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.Handler;
import android.os.Message;


import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.android.volley.AuthFailureError;
import com.android.volley.DefaultRetryPolicy;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.VolleyLog;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;

import org.json.JSONException;
import org.json.JSONObject;
import java.lang.String;

import java.io.OutputStream;
import java.nio.charset.Charset;
import java.io.UnsupportedEncodingException;
import java.util.Iterator;



public class MainActivity extends Activity {

//Static property to know if activity is running or now - viz StartReceiver
public static Boolean Running = null;
float fullVoltage;
int batteryVol;
String currentBatteryVol = "Current Input Voltage:";
//Instance of class which works with reader - viz ReaderManager
private ReaderManager readerManager = null;
//Instance of ui elements
private Button mainButton = null;
private Button button10 = null;
private Button button = null;
private Button button2 = null;
private Button button3 = null;
private Button button4 = null;
private Button button5 = null;
private Button button6 = null;
private Button button7 = null;
private Button button8 = null;
private ProgressBar scanProgressBar = null;
private TextView infoTextView = null;
private TextView textView = null;
private IntentFilter intentfilter = null;


private String outputString = null;
private String serialNumber = null;

private Handler handler = null;

private UsbDeviceConnection usbDeviceConnection = null;
private UsbDevice usbDevice = null;
private UsbInterface usbInterface = null;
private UsbManager usbManager = null;




//Timer to make progressbar effect
private CountDownTimer timer = null;

//handler for sending event back to activity from readerManager
private Handler logHandler = null;


public void setCharacter(String outputString) {this.outputString = outputString; }

public String getSerialNumber(){
    if(serialNumber == null){
        usbDeviceConnection = usbManager.openDevice(usbDevice);
        serialNumber = usbDeviceConnection.getSerial();
        usbDeviceConnection.close();
    }
    return serialNumber;
}

private BroadcastReceiver broadcastreceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        //give the Input Voltage of the device
        batteryVol = intent.getIntExtra(BatteryManager.EXTRA_VOLTAGE, 0);

    }
};


private BroadcastReceiver broadcastreceiverr = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        //give the Input Voltage of the device
        batteryVol = intent.getIntExtra(BatteryManager.EXTRA_VOLTAGE, 0);

    }
};


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    //To prevent unneeded changing to landscape
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

    setVolumeControlStream(AudioManager.STREAM_MUSIC);



    //Indicator that activity is running
    Running = true;

    //Initialization of Volley - for communicating with server
    final RequestQueue queue = Volley.newRequestQueue(this);

    //Register usbReceiver to get Usb events + own intent ("own.usb.action") to call receiver whenever i want
    BroadcastReceiver usbReceiver = new UsbReceiver();
    final IntentFilter intentFilter = new IntentFilter(UsbManager.ACTION_USB_DEVICE_ATTACHED);
    intentFilter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
    intentFilter.addAction(UsbManager.EXTRA_PERMISSION_GRANTED);
    intentFilter.addAction("own.usb.action");
    this.registerReceiver(usbReceiver, intentFilter);


    //Initialization of timer - CountDownTimer seemed to be most easy way
    timer = new CountDownTimer(100000, 50) {
        //decrementing progress bar to add effect that reader's going away
        public void onTick(long millisUntilFinished) {
            if (scanProgressBar.getProgress() > 0) {
                scanProgressBar.incrementProgressBy(-2);
            }
        }

        //if reader wasn't find in 100s close scanning
        public void onFinish() {
            readerManager.close();
            infoTextView.append("Scanning Stopped\n");
            mainButton.setText("Start A");
        }
    };

    //get instances of ui elements
    infoTextView = (TextView) findViewById(R.id.InfoTextView);
    textView = (TextView) findViewById(R.id.textView);
    mainButton = (Button) findViewById(R.id.mainButton);
    button = (Button) findViewById(R.id.button);
    button2 = (Button) findViewById(R.id.button2);
    button3 = (Button) findViewById(R.id.button3);
    button4 = (Button) findViewById(R.id.button4);
    button5 = (Button) findViewById(R.id.button5);
    button6 = (Button) findViewById(R.id.button6);
    button7 = (Button) findViewById(R.id.button7);
    button8 = (Button) findViewById(R.id.button8);
    button10 = (Button) findViewById(R.id.button10);
    scanProgressBar = (ProgressBar) findViewById(R.id.ScanProgressBar);
    intentfilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);


    //add click listener
    mainButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            //control if reader is plugged
            if (readerManager != null) {
                if (!readerManager.getScanning()) {
                    //if don't running start scanning
                    new Thread(readerManager).start();
                    timer.start();
                    infoTextView.setText("Scanning started\n");
                    mainButton.setText("Stop A");
                    //give the visibility of the button
                    button.setVisibility(View.VISIBLE);
                    button2.setVisibility(View.VISIBLE);
                    button3.setVisibility(View.VISIBLE);
                    button4.setVisibility(View.VISIBLE);
                    button5.setVisibility(View.VISIBLE);
                    button6.setVisibility(View.VISIBLE);
                    button7.setVisibility(View.VISIBLE);
                    button8.setVisibility(View.VISIBLE);
                    button10.setVisibility(View.VISIBLE);
                    textView.setVisibility(View.VISIBLE);

                } else {
                    //else close communication
                    readerManager.close();
                    timer.cancel();
                    scanProgressBar.setProgress(0);
                    infoTextView.append("Scanning Stopped\n");
                    mainButton.setText("Start A");
                    //give the visibility of the button
                    button.setVisibility(View.VISIBLE);
                    button2.setVisibility(View.VISIBLE);
                    button3.setVisibility(View.VISIBLE);
                    button4.setVisibility(View.VISIBLE);
                    button5.setVisibility(View.VISIBLE);
                    button6.setVisibility(View.VISIBLE);
                    button7.setVisibility(View.VISIBLE);
                    button8.setVisibility(View.VISIBLE);
                    button10.setVisibility(View.VISIBLE);
                    textView.setVisibility(View.VISIBLE);

                }
            }
        }
    });


    //different button operation
    button2.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            if (readerManager != null) {
                //readerManager.send("c0a\n");
                textView.setText("Gain set to 0x0A\n");
                infoTextView.setText("Gain c0a\n");
                readerManager.setScanning(false);
                mainButton.setText("Start A");
                textView.setVisibility(View.INVISIBLE);
            }
        }
    });

    button3.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (readerManager != null) {
                //readerManager.send("c2a\n");
                //textView.setText("");
                textView.setText("Gain set to 0x2A\n");
                infoTextView.setText("Gain c2a\n");
                readerManager.setScanning(false);
                mainButton.setText("Start A");
                textView.setVisibility(View.INVISIBLE);
            }
        }
    });

    button4.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            if (readerManager != null) {
                //readerManager.send("c4a\n");
                textView.setText("Gain set to 0x4A\n");
                infoTextView.setText("Gain c4a\n");
                readerManager.setScanning(false);
                mainButton.setText("Start A");
                textView.setVisibility(View.INVISIBLE);
            }
        }
    });

    button5.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (readerManager != null) {
                //readerManager.send("c6a\n");
                textView.setText("Gain set to 0x6A\n");
                infoTextView.setText("Gain c6a\n");
                readerManager.setScanning(false);
                mainButton.setText("Start A");
                textView.setVisibility(View.INVISIBLE);
            }
        }
    });

    button6.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (readerManager != null) {
                String a = readerManager.send("g");
                /*infoTextView.setText("0x2A");
                /*textView.setVisibility(View.INVISIBLE);*/
                //readerManager.send("Gain set to" + a + "\n");
                textView.setVisibility(View.VISIBLE);
                readerManager.setScanning(false);
                mainButton.setText("Start A");
            }
        }
    });

    button7.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (readerManager != null) {
                readerManager.setScanning(false);
                mainButton.setText("Start A");
                textView.setText("0x2A");
                MainActivity.this.registerReceiver(broadcastreceiver, intentfilter);
                fullVoltage = (float) (batteryVol * 0.001 + 1.185);
                infoTextView.setText(currentBatteryVol + " " + fullVoltage + " volt");
                textView.setVisibility(View.INVISIBLE);
            }
        }
    });

    button8.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (readerManager != null) {
                readerManager.setScanning(false);
                mainButton.setText("Start A");
                textView.setText("0x2A");
                MainActivity.this.registerReceiver(broadcastreceiverr, intentfilter);
                fullVoltage = (float) (batteryVol * 0.001 + 1.1);
                infoTextView.setText(currentBatteryVol + " " + fullVoltage + " volt");

                textView.setVisibility(View.INVISIBLE);
            }
        }
    });

    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            infoTextView.setText("");
            textView.setText("");
        }
    });

    button10.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (readerManager != null) {
                textView.setVisibility(View.INVISIBLE);
                textView.setText("");
                usbDeviceConnection = usbManager.openDevice(usbDevice);
                serialNumber = usbDeviceConnection.getSerial();
                infoTextView.setText("1699293DF3834F6F85C2\n79EEA5C6845200010001");
                readerManager.setScanning(false);
                mainButton.setText("Start A");
                textView.setVisibility(View.INVISIBLE);

            }
        }
    });

    //crate instance of handler
    logHandler = new Handler() {
        @Override
        public void handleMessage(Message message) {
            if (message.what == 0) {
                //if empty message only increment progressBar to add effect that reader's near
                if (scanProgressBar.getProgress() < 100) {
                    scanProgressBar.incrementProgressBy(10);
                }
            }
            if (message.what == 1) {
                //if succsesful read then end progressBar effect
                timer.cancel();
                scanProgressBar.setProgress(0);
                //inform user
                infoTextView.append("Scan successful\n");
                infoTextView.append("Waining for server...\n\n");
                //start communication - sanding scanned encrypted id + initialization vector and serial number
                String encID = (String) message.obj;
                String serialNumber = readerManager.getSerialNumber();
                JSONObject jsonBody = new JSONObject();
                try {
                    //Encrypted VID, ID,  Temperature(if a chip supports)\\\\\\\\\\\\
                    jsonBody.put("encryptedID", encID);
                    //User ID,
                    jsonBody.put("userID", "59aeb4edcb2d192cec094d8d");
                    // User Name
                    jsonBody.put("userName", "User Name");
                } catch (JSONException e) {
                    e.printStackTrace();
                }
                final String requestBody = jsonBody.toString();
                //using html POST - address of the server
                //String url = "https://scans.petscanner.com/scans/create-scan"; //***needs ssl endpoint paid for on Heroku as they charge for this on custom domains
                String url = "https://pet-scanner-api.herokuapp.com/scans/create-scan";
                //Address of local the server
                //String url = "http://192.168.1.5:3000/scans/create-scan";
                StringRequest stringRequest = new StringRequest(Request.Method.POST, url,
                        new Response.Listener<String>() {
                            /*@Override
                            public void onResponse(String response) {
                               infoTextView.append(response);
                            }*/
                            @Override
                            public void onResponse(String response) {
                                 //if successful print response (, -> ,\n to better visualization if json)j
                                JSONObject json = new JSONObject();
                                try {
                                    json = new JSONObject(response);
                                    infoTextView.append("ID: " + json.get("id") + "\n");
                                    //infoTextView.append((String)json.get("status")+"\n");
                                    infoTextView.append("Temperature " + json.get("temp") + "°C");
                                } catch (JSONException e) {
                                    /*response = response.replaceAll(",", ",\n");
                                    infoTextView.append(response);*/
                                }// create JSON obj from string
                                //infoTextView.append("Scanned message is:\n"+ response);
                            }
                        }, new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        //if not inform user
                        infoTextView.append("Network error");
                    }
                }) {
                    @Override
                    public String getBodyContentType() {
                        return "application/json; charset=utf-8";
                    }

                    @Override
                    public byte[] getBody() throws AuthFailureError {
                        try {
                            return requestBody == null ? null : requestBody.getBytes("utf-8");
                        } catch (UnsupportedEncodingException uee) {
                            VolleyLog.wtf("Unsupported Encoding while trying to get the bytes of %s using %s", requestBody, "utf-8");
                            return null;
                        }
                    }
                };

                stringRequest.setRetryPolicy(new DefaultRetryPolicy(12000,
                        DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));

                queue.add(stringRequest);
                mainButton.setText("Start A");
                button.setVisibility(View.VISIBLE);
                button2.setVisibility(View.VISIBLE);
                button3.setVisibility(View.VISIBLE);
                button4.setVisibility(View.VISIBLE);
                button5.setVisibility(View.VISIBLE);
                button6.setVisibility(View.VISIBLE);
                button7.setVisibility(View.VISIBLE);
                textView.setVisibility(View.INVISIBLE);
                infoTextView.setVisibility(View.VISIBLE);

            }
        }
    };

    //call usb receiver on end of onCreate in case that device is already connected
    Intent message = new Intent("own.usb.action");
    intentFilter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
    this.getApplicationContext().sendBroadcast(message);
}


//usb receiver catching all usb events in activity (inside activity cause it was most easy way to changing ui outside of activity
public class UsbReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        //get usb service and create empty device variable
        UsbManager usbManager = (UsbManager) context.getSystemService(USB_SERVICE);
        final IntentFilter intentFilter = new IntentFilter(UsbManager.ACTION_USB_DEVICE_ATTACHED);
        intentFilter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
        UsbDevice usbDevice = null;
        //iterate over all usb devices to find one with desired vid (also pid) -
        Iterator<UsbDevice> deviceIterator = usbManager.getDeviceList().values().iterator();
        if (deviceIterator.hasNext()) {
            UsbDevice device = deviceIterator.next();
            if (device.getVendorId() == 0x04D8) {
                //if find bring activity to front if already wasn't
                Intent i = new Intent(context, MainActivity.class);
                i.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
                startActivity(i);
                //save instance to variable
                usbDevice = device;
            }
        }
        if (usbDevice != null) {
            if (usbManager.hasPermission(usbDevice)) {
                //if has permission create instance of ReaderManager
                readerManager = new ReaderManager(context, logHandler, usbDevice);
                //start scanning
                new Thread(readerManager).start();
                timer.start();
                infoTextView.setText("Scanning started\n");
                mainButton.setText("Stop A");
            } else {
                //if hasn't permission request it
                PendingIntent permissionIntent = PendingIntent.getBroadcast(context, 0, new Intent(UsbManager.EXTRA_PERMISSION_GRANTED), 0);
                usbManager.requestPermission(usbDevice, permissionIntent);
            }
        } else if (readerManager != null) {
            //if there isn't reader and readerManager was created - close scanning + inform user
            readerManager.close();
            mainButton.setText("NoReader");
        }
    }
}
}

1 个答案:

答案 0 :(得分:-1)

以下是USB串口设备的ReaderManger代码:

package dls.readerapp;

import android.annotation.TargetApi;
import android.content.Context;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbEndpoint;
import android.hardware.usb.UsbInterface;
import android.hardware.usb.UsbManager;
import android.media.AudioManager;
import android.media.ToneGenerator;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.util.Log;

import java.io.OutputStream;
import java.nio.charset.Charset;

public class ReaderManager implements Runnable {

//1. bool to set closeRequested
private Boolean closeRequested = null;
//2. bool to get if scanning
private Boolean scanning = null;

//3. volumes of beep sound (min == usual sound, max == successful scan sound)
private Integer minVolume = null;
private Integer maxVoleme = null;

//4. string variable of character to send in communication
private String outputString = null;
private String serialNumber = null;

//5. instance of handler
private Handler handler = null;

//6.usb variables
private UsbDeviceConnection usbDeviceConnection = null;
private UsbDevice usbDevice = null;
private UsbInterface usbInterface = null;
private UsbManager usbManager = null;

//7. toneGenerator for beeping sound
private ToneGenerator toneGenerator = null;


public  ReaderManager(Context context, Handler handler, UsbDevice usbDevice) {
    //8. initialization to default values
    this.closeRequested = false;
    this.scanning = false;
    this.minVolume = 80;
    this.maxVoleme = 100;
    this.outputString = "a";

    //9. save handler and desired usbDevice
    this.handler = handler;
    this.usbDevice = usbDevice;

    //10. get interface 1 where communication takes place
    this.usbInterface = usbDevice.getInterface(1);
    //11. get usbManger from context
    this.usbManager = (UsbManager)context.getSystemService(Context.USB_SERVICE);

    //initialization toneGenerator to min volume (only way i find to change volume is to create new instance)
    this.toneGenerator = new ToneGenerator(AudioManager.STREAM_MUSIC, minVolume);
}

//12. change character to send
public void setCharacter(String outputString) {
    this.outputString = outputString;
}

//13. get scanning status
public Boolean getScanning(){
    return scanning;
}

public void setScanning(boolean b){
    this.scanning = b;
}

//14. get serial number !!! permission needed !!!
public String getSerialNumber() {
    if(serialNumber == null){
        //15. if scanning wast start yet - it is needed to open new connection to get serial
        usbDeviceConnection = usbManager.openDevice(usbDevice);
        serialNumber = usbDeviceConnection.getSerial();
        usbDeviceConnection.close();
    }
    return serialNumber;
}

//16. request close
public void close() {
    closeRequested = true;
}

public String send(String out){
    usbDeviceConnection = usbManager.openDevice(usbDevice);
    usbDeviceConnection.claimInterface(usbInterface, true);

    //17 .get serial number for latter use
    serialNumber = usbDeviceConnection.getSerial();

    //18. get endpoints (ways of communication) of interface
    UsbEndpoint endpointIn = usbInterface.getEndpoint(1);
    UsbEndpoint endpointOut = usbInterface.getEndpoint(0);

    //19. crate variables for communication
    byte[] readData = new byte[8];
    byte[] sendData = out.getBytes(Charset.forName("US-ASCII"));

    //20. send start character for communication
    usbDeviceConnection.bulkTransfer(endpointOut, sendData, sendData.length, 100);
    usbDeviceConnection.bulkTransfer(endpointIn, readData, readData.length, 100);

    String result = new String(readData);
    //if (result.length() < 1) {
        return new String(readData);
    /*} else {
        return "?";
    }*/
}

//21. main scanning method - !!! permission needed !!!
@Override
public void run() {
    //22. set variables to desired values
    scanning = true;
    this.toneGenerator = new ToneGenerator(AudioManager.STREAM_MUSIC, minVolume);

    //23. open communication and claim interface
    usbDeviceConnection = usbManager.openDevice(usbDevice);
    usbDeviceConnection.claimInterface(usbInterface, true);

    //24. get serial number for latter use
    serialNumber = usbDeviceConnection.getSerial();

    //25. get endpoints (ways of communication) of interface
    UsbEndpoint endpointIn = usbInterface.getEndpoint(1);
    UsbEndpoint endpointOut = usbInterface.getEndpoint(0);

    //26. crate variables for communication
    byte[] readData = new byte[64];
    byte[] sendData = outputString.getBytes(Charset.forName("US-ASCII"));
    String finalMessage = "";

    //27. send start character for communication
    usbDeviceConnection.bulkTransfer(endpointOut, sendData, sendData.length, 500);

    //28. main communication cycle
    while (true) {
        if (closeRequested) {
            //29. if close requested close
            closeRequested = false;
            scanning = false;
            this.send("g");
            break;
        }

        //30. get message from scanner[]
        usbDeviceConnection.bulkTransfer(endpointIn, readData, readData.length, 25);

        //31. get actual string message
        String message = new String(readData, Charset.forName("US-ASCII"));
        message = message.substring(0, message.indexOf('\0'));

        if (message.contains("*")) {
            //32. if contains * then make short beep sound (means not chip is near)
            handler.sendMessage(handler.obtainMessage(0));
            toneGenerator.startTone(ToneGenerator.TONE_CDMA_ALERT_CALL_GUARD, 20);
        }

        if (message.length() == 32) {
            //33. if message is 32 chars long means its either encrypted id or initialization vector
            if (message.length() < 6) {
                if (finalMessage != "") {
                    //34. if finalMessage isn't "" then it means first part was scanned -> successful read
                    //35. create new instance of toneGenerator to raise volume and play longer sound;
                    toneGenerator = new ToneGenerator(AudioManager.STREAM_MUSIC, maxVoleme);
                    toneGenerator.startTone(ToneGenerator.TONE_CDMA_ALERT_CALL_GUARD, 200);

                    //36. inform main thread
                    handler.sendMessage(handler.obtainMessage(1, finalMessage + message));

                    //37. sleep to let beep sound end
                    try {
                        Thread.sleep(250);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    //38. close scanning
                    toneGenerator.release();
                    scanning = false;
                    break;
                }
                //39. if first 32 chars then save it to finalMessage
                finalMessage = message;
            }
            //40. refresh buffer
            readData = new byte[64];
        }
    }
}
}