android usb串口通信

allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}

引用 implementation'com.github.mik3y:usb-serial-for-android:3.3.0' 库文件

权限 <uses-feature android:name="android.hardware.usb.host" />

代码:


/**

* create nano on 2020/12/19 23:10

*/

public class UsbActivity extends BaseActivity<ActivityUsbBinding, UsbViewModel> {

    /**

    * 初始化根布局

    *

    * @return 布局layout的id

    */

    @Override

    public int initContentView() {

        return R.layout.activity_usb;

    }

    @Override

    public void initView() {

        super.initView();

        register();

        search();

    }

    @Override

    public void initClick() {

        super.initClick();

        binding.usbBtn.setOnClickListener(new View.OnClickListener() {

            @Override

            public void onClick(View view) {

             if(usbDevicesList!=null && usbDevicesList.size()>0){
                    mUsbSerialPort = usbDevicesList.get(0);
                    RequestNormalPermission(usbManager, mUsbSerialPort.getDriver().getDevice());
                }else{
                    ToastUtils.showToast("未找到usb设备");
                }

            }

        });

        binding.usbClose.setOnClickListener(new View.OnClickListener() {

            @Override

            public void onClick(View view) {

//                byte[] bys = {(byte) 0xA0, 0x01, 0x00, (byte) 0xA1};

                byte[] bys = {(byte) 0xA0, 0x01, 0x01, (byte) 0xA2};

                sendData(bys);

            }

        });

        binding.usbOpen.setOnClickListener(new View.OnClickListener() {

            @Override

            public void onClick(View view) {

                byte[] bys = {(byte) 0xA0, 0x01, 0x00, (byte) 0xA1};

                sendData(bys);

            }

        });

    }

    private String USB_PERMISSION = "com.android.usb.USB_PERMISSION";

    private PendingIntent mPrtPermissionIntent; //获取外设权限的意图

    /**

    * 动态注册usb广播,拔插动作,注册动作

    */

    private void register() {

        //注册在此service下的receiver的监听的action

        IntentFilter intentFilter = new IntentFilter();

        intentFilter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);

        intentFilter.addAction(UsbManager.ACTION_USB_ACCESSORY_ATTACHED);

        intentFilter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);

        intentFilter.addAction(USB_PERMISSION);

        registerReceiver(usbReceiver, intentFilter);//注册receiver

        //通知监听外设权限注册状态

        //PendingIntent:连接外设的intent

        //ask permission

        mPrtPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(USB_PERMISSION), 0);

    }

    private BroadcastReceiver usbReceiver = new BroadcastReceiver() {

        @Override

        public void onReceive(Context context, Intent intent) {

            if (intent == null) {

                return;

            }

            String action = intent.getAction();

            // USB注册动作

            if (USB_PERMISSION.equals(action)) {

                synchronized (this) {

                    if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {

                        if ((UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE) != null) {

                            // usbDev = (UsbDevice)

                            // intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);

                            // after request dev permission and granted

                            // pemission , connect printer by usb

                            LogUtil.i("after request dev permission and granted pemission , connect printer by usb.");

                            usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);

                            List<UsbSerialDriver> drivers = UsbSerialProber.getDefaultProber().findAllDrivers(usbManager);

                            UsbDevice device = drivers.get(0).getDevice();

                            UsbSerialDriver driver = UsbSerialProber.getDefaultProber().probeDevice(device);

                            mUsbSerialPort = driver.getPorts().get(0);

                            getUsbInfo(mUsbSerialPort.getDriver().getDevice());

                        } else {

                            LogUtil.e("usb device suddenly disappera.");

                            ToastUtils.showToast("USB外设意外消失。");

                        }

                    } else {

                        LogUtil.e("usb permission granted fail.");

                        ToastUtils.showToast("USB权限注册失败。");

                    }

                }

            }

            // USB拔插动作

            else if (UsbManager.ACTION_USB_ACCESSORY_ATTACHED.equals(action)

                    || UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action)) {

                LogUtil.i("USB 插入...");

                search();

            }

        }

    };

    UsbManager usbManager;

    List<UsbSerialPort> usbDevicesList = new ArrayList<>();

    //查询设备

    private void search() {

        usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);

        List<UsbSerialDriver> drivers =

                UsbSerialProber.getDefaultProber().findAllDrivers(usbManager);

        //try get enable printer dev

        if (drivers.size() > 0) {

            usbDevicesList.clear();

            for (UsbSerialDriver driver : drivers) {

                usbDevicesList.addAll(driver.getPorts());

            }

//            adapter.notifyDataSetChanged();

        } else {

            LogUtil.e("not find device.");

            return;

        }

    }

    UsbSerialPort mUsbSerialPort;

    UsbDeviceConnection usbDeviceConnection;

    /**

    * 请求权限:一般来说有弹框

    */

    public void RequestNormalPermission(UsbManager usbManager, UsbDevice device) {

        if (!usbManager.hasPermission(device)) {

            // ask has dev permission,pop dialog

            LogUtil.d("printer dev has no permission,try request it.");

            ToastUtils.showToast("printer dev has no permission,try request it.");

            usbManager.requestPermission(device, mPrtPermissionIntent);// will recall mReceiver

        } else {

            // when dev has granted permission , connect printer by usb

            LogUtil.d("printer dev has granted permission,connect usb.");

            ToastUtils.showToast("USB权限注册成功。");

            UsbSerialDriver driver = UsbSerialProber.getDefaultProber().probeDevice(device);

            mUsbSerialPort = driver.getPorts().get(0);

            getUsbInfo(mUsbSerialPort.getDriver().getDevice());

        }

    }

    /**

    * 获得授权USB的基本信息

    * 1、USB接口,一般是第一个

    * 2、USB设备的输入输出端

    */

    private void getUsbInfo(UsbDevice usbDevice) {

        StringBuilder sb = new StringBuilder();

        if (Build.VERSION.SDK_INT >= 23) {

            sb.append(String.format("VID:%04X  PID:%04X  ManuFN:%s  PN:%s V:%s",

                    usbDevice.getVendorId(),

                    usbDevice.getProductId(),

                    usbDevice.getManufacturerName(),

                    usbDevice.getProductName(),

                    usbDevice.getVersion()

            ));

        } else if (Build.VERSION.SDK_INT >= 21) {

            sb.append(String.format("VID:%04X  PID:%04X  ManuFN:%s  PN:%s",

                    usbDevice.getVendorId(),

                    usbDevice.getProductId(),

                    usbDevice.getManufacturerName(),

                    usbDevice.getProductName()

            ));

        } else {

            sb.append(String.format("VID:%04X  PID:%04X",

                    usbDevice.getVendorId(),

                    usbDevice.getProductId()

            ));

        }

        LogUtil.d("获得授权USB的基本信息: " + sb.toString());

        connect();//连接

    }

    /**

    * usb设备的连接

    */

    private void connect() {

        LogUtil.i("usb connect...");

        usbDeviceConnection = null;

        usbDeviceConnection = usbManager.openDevice(mUsbSerialPort.getDriver().getDevice());

        if (usbDeviceConnection == null) {

//            ll_usb_connect.setVisibility(View.GONE);

//            tv_usb.setText(tv_usb.getText().toString() + " 连接失败!!!");

            ToastUtils.showToast("连接失败");

        } else {

//            tv_usb.setText(tv_usb.getText().toString() + " 连接成功。");

//            ll_usb_connect.setVisibility(View.VISIBLE);

//            tv_connect_state.setText("USB通信");

//            tv_receive.setText("");

//            et_send.setText("01 03 00 01 00 01 D5 CA");

            ToastUtils.showToast("连接成功");

            setConnectionParam();

            onDeviceStateChange();

        }

    }

    /**

    * 设置通讯参数

    */

    private void setConnectionParam() {

        try {

            if (mUsbSerialPort.getDriver().getDevice().getInterfaceCount() > 0) {

                mUsbSerialPort.open(usbDeviceConnection);
                 //9600 就是波特率
                mUsbSerialPort.setParameters(9600, 8, UsbSerialPort.STOPBITS_1, UsbSerialPort.PARITY_NONE);

                StringBuilder sb = new StringBuilder();

                sb.append("\n CD  - Carrier Detect = " + mUsbSerialPort.getCD());

                sb.append("\n CTS - Clear To Send = " + mUsbSerialPort.getCTS());

                sb.append("\n DSR - Data Set Ready = " + mUsbSerialPort.getDSR());

                sb.append("\n DTR - Data Terminal Ready = " + mUsbSerialPort.getDTR());

                sb.append("\n DSR - Data Set Ready = " + mUsbSerialPort.getDSR());

                sb.append("\n RI  - Ring Indicator = " + mUsbSerialPort.getRI());

                sb.append("\n RTS - Request To Send = " + mUsbSerialPort.getRTS());

//                tv_connect_state.setText(sb.toString());

                LogUtil.d(sb.toString());

                try {

                    mUsbSerialPort.setDTR(true);

                } catch (IOException x) {

                    LogUtil.e("IOException DTR: " + x.getMessage());

                }

                try {

                    mUsbSerialPort.setRTS(true);

                } catch (IOException x) {

                    LogUtil.e("IOException RTS: " + x.getMessage());

                }

            }

            //无通讯接口

            else {

//                tv_connect_state.setText("该USB无通讯接口");

                ToastUtils.showToast("该USB无通讯接口");

            }

        } catch (IOException e) {

            LogUtil.e("Error setting up device: " + e.getMessage());

//            tv_connect_state.setText("Error opening device: " + e.getMessage());

            ToastUtils.showToast("Error opening device: " + e.getMessage());

            try {

                mUsbSerialPort.close();

            } catch (IOException e2) {

                // Ignore.

            }

            mUsbSerialPort = null;

            return;

        }

    }

    public boolean sendData(byte[] data) {

        LogUtil.i("sendData:" + Arrays.toString(data));

        if (mSerialIoManager != null) {

//            mSerialIoManager.writeAsync(data);

            try {

                mUsbSerialPort.write(data, 2000);

            } catch (IOException e) {

                e.printStackTrace();

            }

        }

        return false;

    }

    private final SerialInputOutputManager.Listener mListener =

            new SerialInputOutputManager.Listener() {

                @Override

                public void onRunError(Exception e) {

                    LogUtil.d("Runner stopped.");

                }

                @Override

                public void onNewData(final byte[] data) {

                    LogUtil.i("onReceiver data=" + Arrays.toString(data));

//                    instance.runOnUiThread(new Runnable() {

//                        @Override

//                        public void run() {

//                            tv_receive.setText(HexUtil.bytesToHexString(data));

//                        }

//                    });

                }

            };

    /**

    * usb设备断开连接

    */

    private void disconnect() {

        LogUtil.e("usb disconnect...");

        stopIoManager();

        if (mUsbSerialPort != null) {

            try {

                mUsbSerialPort.close();

            } catch (IOException e) {

                // Ignore.

            }

            mUsbSerialPort = null;

        }

        //usbdevice usbmanager

    }

    private final ExecutorService mExecutor = Executors.newSingleThreadExecutor();

    private SerialInputOutputManager mSerialIoManager;

    private void stopIoManager() {

        if (mSerialIoManager != null) {

            LogUtil.i("Stopping io manager ..");

            mSerialIoManager.stop();

            mSerialIoManager = null;

        }

    }

    private void startIoManager() {

        if (mSerialIoManager == null) {

            LogUtil.i("Starting io manager ..");

            mSerialIoManager = new SerialInputOutputManager(mUsbSerialPort, mListener);

            mExecutor.submit(mSerialIoManager);

        }

    }

    private void onDeviceStateChange() {

        stopIoManager();

        startIoManager();

    }

    @Override

    public void onDestroy() {

        unregisterReceiver(usbReceiver);

        usbReceiver = null;

        disconnect();

        super.onDestroy();

    }

}


public class LogUtil {

    public static void i(String ss){

        Log.d("liu",ss);

    }

    public static void e(String ss){

        i(ss);

    }

    public static void d(String ss){

        i(ss);

    }

}

布局文件 activity_usb.xml


<?xml version="1.0" encoding="utf-8"?>

<layout xmlns:android="http://schemas.android.com/apk/res/android">

    <data>

    </data>

    <LinearLayout

        android:layout_width="match_parent"

        android:layout_height="match_parent"

        android:orientation="vertical"

        android:gravity="center">

        <TextView

            android:id="@+id/usb_btn"

            android:background="@drawable/color_c7c7c7_2"

            android:layout_width="80dp"

            android:layout_height="80dp"

            android:gravity="center"

            android:text="申请权限" />

        <TextView

            android:id="@+id/usb_close"

            android:background="@drawable/color_c7c7c7_2"

            android:layout_width="80dp"

            android:layout_height="80dp"

            android:layout_marginTop="20dp"

            android:gravity="center"

            android:text="关门" />

        <TextView

            android:id="@+id/usb_open"

            android:background="@drawable/color_c7c7c7_2"

            android:layout_width="80dp"

            android:layout_height="80dp"

            android:layout_marginTop="20dp"

            android:gravity="center"

            android:text="开门" />

    </LinearLayout>

</layout>

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,012评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,628评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,653评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,485评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,574评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,590评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,596评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,340评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,794评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,102评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,276评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,940评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,583评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,201评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,441评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,173评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,136评论 2 352

推荐阅读更多精彩内容