打開後的第一個界面如下,點擊connect後開始連接,並跳到第二個節目:
第二個界面如下:
Connect.java
package com.example.usb_to_ttl;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.hardware.usb.UsbManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import cn.wch.ch34xuartdriver.CH34xUARTDriver;
public class Connect extends AppCompatActivity implements View.OnClickListener {
private Button connect_to_main;
private boolean isOpen = false;
private int retval;
private Connect activity;
public byte[] writeBuffer;
public byte[] readBuffer;
public int baudRate;
public byte stopBit;
public byte dataBit;
public byte parity;
public byte flowControl;
public int totalrecv;
private Handler handler;
private static final String ACTION_USB_PERMISSION = "cn.wch.wchusbdriver.USB_PERMISSION";
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_connect);
connect_to_main = findViewById(R.id.button_connect);
connect_to_main.setOnClickListener(this);
//usb-ttl
MyApp.driver = new CH34xUARTDriver(
(UsbManager) getSystemService(Context.USB_SERVICE), this,
ACTION_USB_PERMISSION);
baudRate = 9600;
stopBit = 1;
dataBit = 8;
parity = 0;
flowControl = 0;
if (!MyApp.driver.UsbFeatureSupported())// 判斷系統是否支持USB HOST
{
Dialog dialog = new AlertDialog.Builder(Connect.this)
.setTitle("提示")
.setMessage("您的手機不支持USB HOST,請更換其他手機再試!")
.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);//keep screen always on
writeBuffer = new byte[512];
readBuffer = new byte[512];
isOpen = false;
activity = this;
handler = new Handler() {
public void handleMessage(Message msg) {
MainActivity.editText_ele.setText((String) msg.obj);
}
};
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.button_connect:
connect_to_main();
break;
}
}
private void connect_to_main(){
Toast.makeText(Connect.this,"成功",Toast.LENGTH_LONG).show();
openUSB();
configUSB();
Intent intent=new Intent(Connect.this, MainActivity.class);
startActivityForResult(intent,0x01);
}
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, buffer.length);
if (length > 0) {
// String recv = toHexString(buffer, length);
// String recv = new String(buffer, 0, length);
totalrecv += length;
// String content = String.valueOf(totalrecv);
String content = new String(buffer);
//String content = hexStringToString(toHexString(buffer,length));
//String content = toHexString(buffer,length*2);
msg.obj = content+"";
handler.sendMessage(msg);
}
}
}
}
private void openUSB(){
if (!isOpen) {
retval = MyApp.driver.ResumeUsbList();
if (retval == -1)// ResumeUsbList方法用於枚舉CH34X設備以及打開相關設備
{
Toast.makeText(Connect.this, "打開設備失敗!",
Toast.LENGTH_SHORT).show();
MyApp.driver.CloseDevice();
} else if (retval == 0){
if (!MyApp.driver.UartInit()) {//對串口設備進行初始化操作
Toast.makeText(Connect.this, "設備初始化失敗!",
Toast.LENGTH_SHORT).show();
Toast.makeText(Connect.this, "打開" +
"設備失敗!",
Toast.LENGTH_SHORT).show();
return;
}
Toast.makeText(Connect.this, "打開設備成功!",
Toast.LENGTH_SHORT).show();
isOpen = true;
connect_to_main.setText("Close");
new readThread().start();//開啓讀線程讀取串口接收的數據
} else {
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
builder.setIcon(R.mipmap.ic_launcher);
builder.setTitle("未授權限");
builder.setMessage("確認退出嗎?");
builder.setPositiveButton("確定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
// MainFragmentActivity.this.finish();
System.exit(0);
}
});
builder.setNegativeButton("返回", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
}
});
builder.show();
}
} else {
connect_to_main.setText("Open");
isOpen = false;
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
MyApp.driver.CloseDevice();
totalrecv = 0;
}
}
private void configUSB(){
if(isOpen) {
if (MyApp.driver.SetConfig(baudRate, dataBit, stopBit, parity,//配置串口波特率,函數說明可參照編程手冊
flowControl)) {
Toast.makeText(Connect.this, "串口設置成功!",
Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(Connect.this, "串口設置失敗!",
Toast.LENGTH_SHORT).show();
}
}
}
}
MainActivity.java
package com.example.usb_to_ttl;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Context;
import android.widget.Toast;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.os.Handler;
import android.os.Message;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.hardware.usb.UsbManager;
import android.view.WindowManager;
import cn.wch.ch34xuartdriver.CH34xUARTDriver;
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
private Button connect;
//number 0-9
private Button n_0;
private Button n_1;
private Button n_2;
private Button n_3;
private Button n_4;
private Button n_5;
private Button n_6;
private Button n_7;
private Button n_8;
private Button n_9;
//other symbol
private Button clear_all;
private Button equal;
boolean clean;
public static EditText editText_table;
public static EditText editText_ele;
private Context context;
private String usbNumber;
private static final String ACTION_USB_PERMISSION = "cn.wch.wchusbdriver.USB_PERMISSION";
private boolean isOpen = false;
private Handler handler;
private int retval;
private MainActivity activity;
public byte[] writeBuffer;
public byte[] readBuffer;
public int baudRate;
public byte stopBit;
public byte dataBit;
public byte parity;
public byte flowControl;
public int totalrecv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/*
//usb-ttl
MyApp.driver = new CH34xUARTDriver(
(UsbManager) getSystemService(Context.USB_SERVICE), this,
ACTION_USB_PERMISSION);
baudRate = 9600;
stopBit = 1;
dataBit = 8;
parity = 0;
flowControl = 0;
if (!MyApp.driver.UsbFeatureSupported())// 判斷系統是否支持USB HOST
{
Dialog dialog = new AlertDialog.Builder(MainActivity.this)
.setTitle("提示")
.setMessage("您的手機不支持USB HOST,請更換其他手機再試!")
.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);//keep screen always on
writeBuffer = new byte[512];
readBuffer = new byte[512];
isOpen = false;
activity = this;
*/
connect = findViewById(R.id.button10);
//the instantiation of number 0-9
n_0 = findViewById(R.id.button0);
n_1 = findViewById(R.id.button1);
n_2 = findViewById(R.id.button2);
n_3 = findViewById(R.id.button3);
n_4 = findViewById(R.id.button4);
n_5 = findViewById(R.id.button5);
n_6 = findViewById(R.id.button6);
n_7 = findViewById(R.id.button7);
n_8 = findViewById(R.id.button8);
n_9 = findViewById(R.id.button9);
//the instantiation of others
clear_all = findViewById(R.id.button11);
equal = findViewById(R.id.button12);
editText_table = findViewById(R.id.editText);
editText_ele = findViewById(R.id.editText2);
//unable to edit
editText_ele.setFocusable(false);
editText_ele.setFocusableInTouchMode(false);
editText_table.setFocusable(false);
editText_table.setFocusableInTouchMode(false);
//click
n_0.setOnClickListener(this);
n_1.setOnClickListener(this);
n_2.setOnClickListener(this);
n_3.setOnClickListener(this);
n_4.setOnClickListener(this);
n_5.setOnClickListener(this);
n_6.setOnClickListener(this);
n_7.setOnClickListener(this);
n_8.setOnClickListener(this);
n_9.setOnClickListener(this);
connect.setOnClickListener(this);
// sb = new StringBuilder();//usb
clear_all.setOnClickListener(this);
equal.setOnClickListener(this);
context = this;
handler = new Handler() {
public void handleMessage(Message msg) {
editText_ele.setText((String) msg.obj);
}
};
}
public void onClick(View view){
//get the input
String input = editText_table.getText().toString();
//Determine which key is being pressed
switch (view.getId()){
case R.id.button0:
case R.id.button1:
case R.id.button2:
case R.id.button3:
case R.id.button4:
case R.id.button5:
case R.id.button6:
case R.id.button7:
case R.id.button8:
case R.id.button9:
if(clean){
clean = false;
editText_table.setText("");
}
editText_table.setText(input+((Button)view).getText()+"");
break;
//clean
case R.id.button11:
if(clean){
clean = false;
input = "";
editText_table.setText("");
}
if(!input.equals("")){
editText_table.setText(input.substring(0,input.length() - 1));
break;
}
break;
case R.id.button12:
sendToUSB();
break;
case R.id.button10:
openUSB();
configUSB();
break;
}
}
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, buffer.length);
if (length > 0) {
// String recv = toHexString(buffer, length);
// String recv = new String(buffer, 0, length);
totalrecv += length;
// String content = String.valueOf(totalrecv);
String content = new String(buffer);
//String content = hexStringToString(toHexString(buffer,length));
//String content = toHexString(buffer,length*2);
msg.obj = content+"";
handler.sendMessage(msg);
}
}
}
}
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 "";
}
/*
private byte[] toByteArray(String arg) {
if (arg != null) {
// 1.先去除String中的' ',然後將String轉換爲char數組
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++;
}
}
// 將char數組中的值轉成一個實際的十進制數組
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;
}
}
//將 每個char的值每兩個組成一個16進制數據
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[] {};
}
*/
private byte[] toByteArray2(String arg) {
if (arg != null) {
/* 1.先去除String中的' ',然後將String轉換爲char數組 */
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[] {};
}
private void openUSB(){
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;
connect.setText("Close");
new readThread().start();//開啓讀線程讀取串口接收的數據
} else {
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
builder.setIcon(R.mipmap.ic_launcher);
builder.setTitle("未授權限");
builder.setMessage("確認退出嗎?");
builder.setPositiveButton("確定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
// MainFragmentActivity.this.finish();
System.exit(0);
}
});
builder.setNegativeButton("返回", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
}
});
builder.show();
}
} else {
connect.setText("Open");
isOpen = false;
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
MyApp.driver.CloseDevice();
totalrecv = 0;
}
}
private void configUSB(){
if(isOpen) {
if (MyApp.driver.SetConfig(baudRate, dataBit, stopBit, parity,//配置串口波特率,函數說明可參照編程手冊
flowControl)) {
Toast.makeText(MainActivity.this, "串口設置成功!",
Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(MainActivity.this, "串口設置失敗!",
Toast.LENGTH_SHORT).show();
}
}
}
private void sendToUSB() {
usbNumber = editText_table.getText().toString();
//byte[] to_send = toByteArray(usbNumber);
if(usbNumber.length() < 3) {
byte[] to_send2 = toByteArray2(usbNumber);
//txtContent.setText(new String(to_send)+"---"+new String(to_send2));
int retval = MyApp.driver.WriteData(to_send2, to_send2.length);//寫數據,第一個參數爲需要發送的字節數組,第二個參數爲需要發送的字節長度,返回實際發送的字節長度
if (retval < 0)
Toast.makeText(MainActivity.this, "寫失敗!", Toast.LENGTH_SHORT).show();
Toast t = Toast.makeText(context, "Succeed to send " + usbNumber, Toast.LENGTH_LONG);
t.show();
}else {
Toast t = Toast.makeText(context, "Error :input too long " + usbNumber, Toast.LENGTH_LONG);
t.show();
editText_table.setText("");
}
}
}
activity_connect.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/button_connect"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Connect"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.499" />
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.usb_to_ttl">
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<!-- 基礎模塊(必須加入以下聲明)START -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<!-- 統計分析權限 -->
<uses-permission android:name="android.permission.READ_LOGS" />
<application
android:allowBackup="true"
android:icon="@drawable/train"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".Connect">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<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" />
</activity>
<activity android:name=".MainActivity"/>
</application>
</manifest>