adnroid串口编程

此次串口开发参考了开源项目android-serialport-api开发,但是一直遇到读取数据问题

开发步骤:

1.修改SerialPort.c文件方法名,使之与包名类名一致,具体请学习jni开发

2.修改SerialPort.java,使用java发送cmd命令关闭selinux防火墙并添加权限操作文件

3.修改Application.java,设置与自己设备对应的端口和波特率并返回串口,获取输入输出流以便操作文件

问题描述:

ReadThread一直阻塞在mInputStream.read(buffer),所以一直读不出数据。

现象:

每次开机重启可以读取到数据,之后就很难读取到,只有偶尔才能读取到一次。(注:因为我的设备问题,不能主动退出app,所以只能重启退出,大家可以根据自身情况尝试重启手机或app观察现象)

原因:线程问题。

因为每次跳转activity都会重新创建并启动一个ReadThread,而就算创建线程的activity销毁了,线程也还一直存在,并阻塞在读取输入流的方法上,所以就造成了线程一直在增加的情况。而第二次跳转activity时,因为第一次跳转开启的线程还在运行,并且阻塞在读取数据的方法上,因此基本上每次都会是之前的那个线程把数据读取了,所以跳转时新创建的线程未能读取到此次发送指令返回的数据,就又会等待并读取到下一次的数据,所以就造成了除了重启后,每次读取数据线程都会无法读取数据并阻塞在read方法上的假象。

解决方法:

去除掉ReadThread的循环,每次发送AT指令之前先开启线程,这样线程就会等待读取数据,当发送了AT指令之后返回一个输入流,这时线程就会读取数据并将自身销毁。这样每次跳转时开启的新线程就可以读取到数据了。有兴趣的可以参考参考我的源代码。

CSDN下载地址:项目地址

GitHub地址:项目代码

下面贴上部分代码示例:

package android_serialport_api.sample;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.InvalidParameterException;

import android.R.string;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Handler.Callback;
import android.os.Message;
import android.util.Log;
import android.widget.EditText;
import android_serialport_api.SerialPort;
import android_serialport_api.sample.SerialPortActivity.ReadThread;
import android_serialport_api.util.HexUtils;

/**
 * @author dengjifu
 */
public class TestActivity extends Activity implements Callback {

    private static final String TAG = "TestActivity";
    private static int SamCard1 = 12;
    private static int SamCard2 = 14;
    private static String path1 = "/dev/ttyMT0";
    private static String path2 = "/dev/ttyMT1";
    private static int baudrate = 38400;

    private EditText rspEditText;

    protected Application mApplication;
    protected SerialPort mSerialPort;
    protected OutputStream mOutputStream;
    protected InputStream mInputStream;
    private ReadThread mReadThread;

    private String respTextString;

    public class ReadThread extends Thread {

        @Override
        public void run() {
            super.run();

            Log.i("dengjifu", Thread.currentThread().getName()
                    + "--ReadThread/isInterrupted():" + isInterrupted());
            try {
                byte[] buffer = new byte[1024];
                if (mInputStream == null) {
                    Log.i("dengjifu", "mInputStream == null");
                    return;
                }
                Log.i("dengjifu", "ReadThread-->read");
                int size = mInputStream.read(buffer);
                Log.i("dengjifu", "size:" + size);
                if (size > 0) {
                    onDataReceived(buffer, size);
                }
                Log.i("dengjifu", Thread.currentThread().getName()
                        + "--ReadThread/isInterrupted():" + isInterrupted());
            } catch (IOException e) {
                e.printStackTrace();
                return;
            }
        }
    }

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

        rspEditText = (EditText) findViewById(R.id.rspEditText);
        rspEditText.setSaveEnabled(false);
        mApplication = (Application) getApplication();
        try {
            // 串口操作初始化
            mSerialPort = mApplication.getSerialPort();
            mOutputStream = mSerialPort.getOutputStream();
            mInputStream = mSerialPort.getInputStream();
            mReadThread = new ReadThread();
            mReadThread.start();
        } catch (InvalidParameterException e1) {
            e1.printStackTrace();
        } catch (SecurityException e1) {
            e1.printStackTrace();
        } catch (IOException e1) {
            e1.printStackTrace();
        }

        // 上电GPIO
        pownOn(SamCard1);
        pownOn(SamCard2);

        // 发送AT指令
        try {
            sendATCmds();
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    private void sendATCmds() throws SecurityException, IOException {
        Runnable sendCmdRunnable = new Runnable() {
            @Override
            public void run() {
                try {
                    // 66 00 00 00 00 00 00 02 00 00 60
                    String cmd = new String("6200000000000200000060");
                    byte[] buffer = HexUtils.HexToByteArr(cmd);
                    Log.i("dengjifu", mOutputStream + ":" + buffer);
                    mOutputStream.write(buffer);
                    mOutputStream.write('\r');
                    mOutputStream.write('\n');
                    Log.i("dengjifu",
                            "Send AT command: " + HexUtils.byte2HexStr(buffer));
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        };
        new Thread(sendCmdRunnable).start();
    }

    private void pownOn(int portid) {
        Intent i = new Intent("testsam.SAMCARD_POWER_UP");
        i.putExtra("gpio_port_id", portid);
        sendBroadcast(i);
        Log.i("dengjifu", "GPIO pownOn!");
    }

    private void pownOff(int portid) {
        Intent i = new Intent("testsam.SAMCARD_POWER_DOWN");
        i.putExtra("gpio_port_id", portid);
        sendBroadcast(i);
        Log.i("dengjifu", "GPIO pownOff!");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
    }

    protected void onDataReceived(byte[] buffer, int size) {
        respTextString = HexUtils.byte2HexStr(buffer);
        Log.i("dengjifu", "buffer:" + respTextString + ",size" + size);
        Message msg = new Message();
        msg.what = 1;
        handler.sendMessage(msg);
    }

    Handler handler = new Handler(this);

    @Override
    public boolean handleMessage(Message msg) {
        switch (msg.what) {
        case 1:
            rspEditText.setText(respTextString);
            break;

        default:
            break;
        }
        return false;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值