Android USB转ttl串口

       讲到USB转串口,大都是用的USB->ttl模块,我手里这个是USB CH340的一个usb转串口模块,具体长什么样子可以百度搜一下,这种串口的实现方式和谷歌提供的那种串口解决方式不通,这种是通过USB传输数据的,实现起来比较简单一些,下面来看一下方法:

1、需要用到的jar包  CH34xUARTDriver.jar   

        链接:https://pan.baidu.com/s/14QHOf_-4jK03u687lCRWIw 
        提取码:yjhk 
2、AndroidManifest.xml配置USB权限

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

3、在当前的activity下添加

            <intent-filter>
                <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
            </intent-filter>

            <intent-filter>
                <action android:name="android.media.action.IMAGE_CAPTURE"/>
                <category android:name="android.intent.category.DEFAULT"/>
            </intent-filter>

            <meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
                android:resource="@xml/device_filter" />

4、在Application 里实现一个静态的CH34xUARTDriver  对象

public class MyApp extends Application {
	public static CH34xUARTDriver driver;
}

5、在activity内实现串口读写开关

public class MainActivity extends Activity {
    
    private static final String ACTION_USB_PERMISSION = "cn.wch.wchusbdriver.USB_PERMISSION";
    private EditText readText;
    
    private boolean isOpen;
    private Handler handler;
    private int retval;
    private MainActivity activity;
    
    public byte[] writeBuffer;
    public byte[] readBuffer;
    
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        MyApp.driver = new CH34xUARTDriver(
                (UsbManager) getSystemService(Context.USB_SERVICE), this,
                ACTION_USB_PERMISSION);
        initUI();
        //判断系统是否支持USB HOST
        if (!MyApp.driver.UsbFeatureSupported()) {
            Dialog dialog = new AlertDialog.Builder(MainActivity.this)
                    .setTitle("提示")
                    .setMessage("您的设备不支持USBhost")
                    .setPositiveButton("确认",
                            new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface arg0,
                                                    int arg1) {
                                    System.exit(0);
                                }
                            }).create();
            dialog.setCanceledOnTouchOutside(false);
            dialog.show();
        }
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);//保持屏幕常亮状态
        writeBuffer = new byte[512];
        readBuffer = new byte[512];
        isOpen = false;
        
        activity = this;
        //打开流程主要步骤为ResumeUsbList,UartInit
        openButton.setOnClickListener(new openButton());
        openButton.post(new Runnable() {
            @Override
            public void run() {
                openButton.performClick();
            }
        });

        handler = new Handler() {
            public void handleMessage(Message msg) {
                String str = msg.obj.toString();//设备回来的数据
                String s0 = str.substring(0, 8);
                if(s0.equals("01 03 09")){
                    //String s1 = str.substring(9,23); /**卡号*/
                    String s2 = str.substring(24,35);/**余额*/
                    int i = Integer.valueOf(s2.replaceAll(" ",""),16);//转换成分
                    String s = String.valueOf(i/100);                 //转换成元
                    synthesizer.showVideo("您的卡上余额为:"+s+"元");
                }
                readText.append((String) msg.obj);
            }
        };
    }

    class WriteButton implements View.OnClickListener{
        @Override
        public void onClick(View v) {
            byte[] to_send = toByteArray(writeText.getText().toString());
            int retval = MyApp.driver.WriteData(to_send, to_send.length);
            //写数据,第一个参数为需要发送的字节数组,第二个参数为需要发送的字节长度,返回实际发送的字节长度
            if (retval < 0){
                Toast.makeText(MainActivity.this, "写失败",
                        Toast.LENGTH_SHORT).show();
            }else {
                writeBtn.setOnClickListener(new WriteBtn());
                writeBtn.post(new Runnable() {
                    @Override
                    public void run() {
                        writeBtn.performClick();
                    }
                });
            }
        }
    }

    class WriteBtn implements View.OnClickListener{
        @Override
        public void onClick(View v) {
            byte[] to_send = toByteArray(write.getText().toString());
            int retval = MyApp.driver.WriteData(to_send, to_send.length);
            //写数据,第一个参数为需要发送的字节数组,第二个参数为需要发送的字节长度,返回实际发送的字节长度
            if (retval < 0) {
                Toast.makeText(MainActivity.this, "写失败",
                        Toast.LENGTH_SHORT).show();
            }
        }
    }

    class setButton implements View.OnClickListener{
        @Override
        public void onClick(View v) {
            if (MyApp.driver.SetConfig((byte)9600, (byte)8, (byte)1, (byte)0,
                    (byte)0)) {//配置串口波特率,函数说明可参照编程手册
                Toast.makeText(MainActivity.this, "串口设置成功",
                        Toast.LENGTH_SHORT).show();
                //01      05     00  00       FF  00        8c  3a
                //01      06     00  00       00  64             88  21
                /*byte[] send = toByteArray(write.getText().toString());
                MyApp.driver.WriteData(send, send.length);*/
                writeButton.setOnClickListener(new WriteButton());
                writeButton.post(new Runnable() {
                    @Override
                    public void run() {
                        writeButton.performClick();
                    }
                });
            } else {
                Toast.makeText(MainActivity.this, "串口设置失败",
                        Toast.LENGTH_SHORT).show();
            }
        }
    }

    class openButton implements View.OnClickListener{

        @Override
        public void onClick(View v) {
            if (!isOpen) {
                retval = MyApp.driver.ResumeUsbList();
                if (retval == -1) {// ResumeUsbList方法用于枚举CH34X设备以及打开相关设备
                    Toast.makeText(MainActivity.this, "打开设备失败",
                            Toast.LENGTH_SHORT).show();
                    MyApp.driver.CloseDevice();
                } else if (retval == 0){
                    if (!MyApp.driver.UartInit()) {//对串口设备进行初始化操作
                        Toast.makeText(MainActivity.this, "设备初始化失败",
                                Toast.LENGTH_SHORT).show();
                        Toast.makeText(MainActivity.this, "打开" +
                                        "设备失败",
                                Toast.LENGTH_SHORT).show();
                        return;
                    }
                    Toast.makeText(MainActivity.this, "打开设备成功",
                            Toast.LENGTH_SHORT).show();
                    isOpen = true;
                    openButton.setText("关闭");
                    configButton.setEnabled(true);
                    writeButton.setEnabled(true);
                    new readThread().start();//开启读线程读取串口接收的数据

                    configButton.setOnClickListener(new setButton());
                    configButton.post(new Runnable() {
                        @Override
                        public void run() {
                            configButton.performClick();
                        }
                    });
                } else {
                    AlertDialog.Builder builder = new AlertDialog.Builder(activity);
                    builder.setIcon(R.drawable.icon);
                    builder.setTitle("未授权限");
                    builder.setMessage("确认退出吗?");
                    builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            System.exit(0);
                        }
                    });
                    builder.setNegativeButton("返回", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                        }
                    });
                    builder.show();
                }
            } else {
                MyApp.driver.CloseDevice();
                openButton.setText("打开");
                configButton.setEnabled(false);
                writeButton.setEnabled(false);
                isOpen = false;
            }
        }
    }

    /*
    * 读取设备数据
    * */
    private class readThread extends Thread {
        public void run() {
            byte[] buffer = new byte[4096];
            while (true) {
                Message msg = Message.obtain();
                if (!isOpen) {
                    break;
                }
                int length = MyApp.driver.ReadData(buffer, 4096);
                if (length > 0) {
                    String recv = toHexString(buffer, length);
                    msg.obj = recv;
                    handler.sendMessage(msg);
                }
            }
        }
    }

    /**
     * 将byte[]数组转化为String类型
     * @param arg
     *            需要转换的byte[]数组
     * @param length
     *            需要转换的数组长度
     * @return 转换后的String队形
     */
    private String toHexString(byte[] arg, int length) {
        String result = new String();
        if (arg != null) {
            for (int i = 0; i < length; i++) {
                result = result
                        + (Integer.toHexString(
                        arg[i] < 0 ? arg[i] + 256 : arg[i]).length() == 1 ? "0"
                        + Integer.toHexString(arg[i] < 0 ? arg[i] + 256
                        : arg[i])
                        : Integer.toHexString(arg[i] < 0 ? arg[i] + 256
                        : arg[i])) + " ";
            }
            return result;
        }
        return "";
    }

    /**
     * 将String转化为byte[]数组
     * @param arg
     *            需要转换的String对象
     * @return 转换后的byte[]数组
     */
    private byte[] toByteArray(String arg) {
        if (arg != null) {
            char[] NewArray = new char[1000];
            char[] array = arg.toCharArray();
            int length = 0;
            for (int i = 0; i < array.length; i++) {
                if (array[i] != ' ') {
                    NewArray[length] = array[i];
                    length++;
                }
            }
            int EvenLength = (length % 2 == 0) ? length : length + 1;
            if (EvenLength != 0) {
                int[] data = new int[EvenLength];
                data[EvenLength - 1] = 0;
                for (int i = 0; i < length; i++) {
                    if (NewArray[i] >= '0' && NewArray[i] <= '9') {
                        data[i] = NewArray[i] - '0';
                    } else if (NewArray[i] >= 'a' && NewArray[i] <= 'f') {
                        data[i] = NewArray[i] - 'a' + 10;
                    } else if (NewArray[i] >= 'A' && NewArray[i] <= 'F') {
                        data[i] = NewArray[i] - 'A' + 10;
                    }
                }
                byte[] byteArray = new byte[EvenLength / 2];
                for (int i = 0; i < EvenLength / 2; i++) {
                    byteArray[i] = (byte) (data[i * 2] * 16 + data[i * 2 + 1]);
                }
                return byteArray;
            }
        }
        return new byte[] {};
    }
    /**
     * 将String转化为byte[]数组
     * @param arg
     *            需要转换的String对象
     * @return 转换后的byte[]数组
     */
    private byte[] toByteArray2(String arg) {
        if (arg != null) {
            char[] NewArray = new char[1000];
            char[] array = arg.toCharArray();
            int length = 0;
            for (int i = 0; i < array.length; i++) {
                if (array[i] != ' ') {
                    NewArray[length] = array[i];
                    length++;
                }
            }
            NewArray[length] = 0x0D;
            NewArray[length + 1] = 0x0A;
            length += 2;
            byte[] byteArray = new byte[length];
            for (int i = 0; i < length; i++) {
                byteArray[i] = (byte)NewArray[i];
            }
            return byteArray;
        }
        return new byte[] {};
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<resource>
   <usb-device product-id="29987" vendor-id="6790" />
   <usb-device product-id="21795" vendor-id="6790" />
   <usb-device product-id="21778" vendor-id="6790" />
</resource>

另外再提供一个github上面开源的一个开源库:

https://github.com/mik3y/usb-serial-for-android

  • 4
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

落魄的Android开发

感谢支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值