• <noscript id="e0iig"><kbd id="e0iig"></kbd></noscript>
  • <td id="e0iig"></td>
  • <option id="e0iig"></option>
  • <noscript id="e0iig"><source id="e0iig"></source></noscript>
  • Android外設編程:01_串口編程

    標簽: Android


    模擬器與虛擬串口之間的通信

    • Eclipse + ADT
    • 模擬器版本:Andoid 4.4.2:該版本 不需要root操作:注意:不是第三方模擬器
      在這里插入圖片描述
    • 串口助手與模擬器之間的串口通信的步驟:

    (1)第一步 :創建虛擬串口
    在這里插入圖片描述
    (2)第二步 :模擬器掛載虛擬串口并啟動模擬器:在cmd小黑屏下輸入

    emulator -avd dcom -writable-system -qemu -serial COM2
    > emulator:emulator.exe程序在\android-sdk-windows\tools目錄下
    > dcom:模擬器名稱
    > COM2:串口號
    完整格式: emulator -avd 模擬器名稱 -writable-system -qemu -serial 串口號
    =======================================================================
    查看模擬器列表命令:emulator -list-avds
    

    在這里插入圖片描述
    (3)第三步 :在Android模擬器上安裝一個串口調試工具:adb instanll ApkPath
    在這里插入圖片描述
    (4)第四步 :測試串口助手與模擬器之間串口通信
    在這里插入圖片描述


    Android串口API編程

    • 第一步:上網down一個Android串口開發包:android-serialport-api-master是Android串口開源類
      在這里插入圖片描述
    • 第二步:創建Android工程
      在這里插入圖片描述
    • 第三步:導包:將Android開發包android-serialport-api中的jni目錄與libs目錄下的文件拷貝到當前工程中
      在這里插入圖片描述
    • 第四步: 拷貝兩個核心類到當前工程中:
      在這里插入圖片描述
      在這里插入圖片描述
    • 第五步: 測試打開串口是否能夠成功并寫串口寫入數據
      在這里插入圖片描述

    完整Android串口代碼Demo

    • 布局文件
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context="${relativePackage}.${activityClass}" >
    
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="測試打卡串口并發送數據" />
        <Button 
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="打開串口"
            android:onClick="onOpenSerialPort"/>
        <Button 
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="發送數據[0x01, 0x02, 0x04, 0x08]"
            android:onClick="onSendData"/>
        <Button 
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="關閉串口"
            android:onClick="onCloseSerialPort"/>
    
    </LinearLayout>
    
    • MainActivity代碼
    package com.ycom.androidserialassistant;
    
    import java.io.File;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.util.Arrays;
    
    import android.app.Activity;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.View;
    import android.widget.Toast;
    import android_serialport_api.SerialPort;
    
    public class MainActivity extends Activity {
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_main);
    	}
    	
    	private SerialPort port = null;
    	private OutputStream os = null;
    	private InputStream in = null;
    	
    	// 打開串口
    	public void onOpenSerialPort(View v) {
    		if (port == null) {
    			String portName = "/dev/ttyS2";
    			int baudrate = 9600;
    			try {
    				port = new SerialPort(new File(portName), baudrate, 0);
    			} catch (Exception e) {
    				Toast.makeText(this, "打開串口失敗", 0).show();
    				return;
    			} 
    		}
    		os = port.getOutputStream();
    		in = port.getInputStream();
    		
    		// 開啟分線程來讀取串口中的數據
    		new Thread() {
    			public void run() {
    				byte[] data = new byte[64];
    				while (true) {
    					try {
    						int len = in.read(data);
    						Log.i("MainActivity", "len = " + len);
    						Log.i("MainActivity", Arrays.toString(data));
    					} catch (IOException e) {
    					}
    				}
    			}
    		}.start();
    		
    		Toast.makeText(this, "打開串口成功", 0).show();
    	}
    	// 發送數據
    	public void onSendData(View v) {
    		if (port != null) {
    			byte data[] = {0x01, 0x02, 0x04, 0x08};
    			try {
    				os.write(data);
    				os.flush();
    			} catch (IOException e) {
    				
    			}
    		}
    	}
    	// 關閉串口
    	public void onCloseSerialPort(View v) throws IOException {
    		if (port != null) {
    			os.close();
    			in.close();
    			port.close();
    			port = null;
    		}
    	}
    }
    

    在這里插入圖片描述


    核心類SerialPort的完整代碼

    /*
     * Copyright 2009 Cedric Priscal
     * 
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     * 
     * http://www.apache.org/licenses/LICENSE-2.0
     * 
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License. 
     */
    
    package android_serialport_api; // 包名不要修改☆☆☆☆☆
    
    import java.io.File;
    import java.io.FileDescriptor;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    
    import android.util.Log;
    
    public class SerialPort {
    
    	private static final String TAG = "SerialPort";
    
    	/*
    	 * Do not remove or rename the field mFd: it is used by native method close();
    	 */
    	private FileDescriptor mFd;
    	private FileInputStream mFileInputStream;
    	private FileOutputStream mFileOutputStream;
    
    	public SerialPort(File device, int baudrate, int flags) throws SecurityException, IOException {
    
    		/* Check access permission */
    		if (!device.canRead() || !device.canWrite()) {
    			try {
    				/* Missing read/write permission, trying to chmod the file */
    				Process su;
    				su = Runtime.getRuntime().exec("/system/bin/su");
    				// 注: 如果需要可以講chmod 666修改為chmod 777
    				String cmd = "chmod 666 " + device.getAbsolutePath() + "\n"
    						+ "exit\n";
    				su.getOutputStream().write(cmd.getBytes());
    				if ((su.waitFor() != 0) || !device.canRead()
    						|| !device.canWrite()) {
    					throw new SecurityException();
    				}
    			} catch (Exception e) {
    				e.printStackTrace();
    				throw new SecurityException();
    			}
    		}
    
    		mFd = open(device.getAbsolutePath(), baudrate, flags);
    		if (mFd == null) {
    			Log.e(TAG, "native open returns null");
    			throw new IOException();
    		}
    		mFileInputStream = new FileInputStream(mFd);
    		mFileOutputStream = new FileOutputStream(mFd);
    	}
    
    	// Getters and setters: 獲取串口對象的輸入流對象
    	// 用于從串口讀取數據
    	public InputStream getInputStream() {
    		return mFileInputStream;
    	}
    
    	// 獲取串口對象的輸出流對象
    	// 用于向串口寫數據
    	public OutputStream getOutputStream() {
    		return mFileOutputStream;
    	}
    
    	// JNI
    	private native static FileDescriptor open(String path, int baudrate, int flags);
    	public native void close();
    	static {
    		System.loadLibrary("serial_port");
    	}
    }
    
    版權聲明:本文為MOOG007原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。
    本文鏈接:https://blog.csdn.net/MOOG007/article/details/107812951

    智能推薦

    Linux之串口編程

    Linux之串口編程 一、串口編程的流程分析 打開串口,一般使用 open 函數,打開之后會返回句柄,這個句柄就可以提供給發送和接收函數使用。串口本質上也是字符設備,但是串口是屬于一種比較特殊的字符設備。 初始化串口,串口需要配置波特率,數據位,校驗位等等一系列的參數,初始化的過程掌握了,發送和接收都比較容易實現。雖然初始化比較麻煩,但是無論是在 window 下還是在 linux下,串口的初始化...

    Linux 串口編程

    首先了解一下終端,Linux 下包括當前終端、前臺控制臺終端、串口和虛擬終端主設備,這些終端均被映射成一個文件(即設備文件),從而能用文件IO函數來操作這些文件來控制終端。 實際的物理串口: 即串口終端/dev/ttyS[n],ttyS系列指的是物理串行接口,即ttyS0為COM1,ttyS1為COM2。 若使用當前主機串口通過串口線連接到另一臺主機的串口時,就能直接通信。 若使用的是VMware...

    PCI串口編程

    一、硬件環境 硬件開發環境是PCI9054+FPGA,16串口或8串口。 軟件開發平臺則是linux、VxWorks。 主要是運用在工控領域,在一般商用平臺可能用不到這玩意。 二、PCI相關知識 PCI相關知識主要是參考了網上一些前輩寫的博文,這里將其貼出來,以免后來人繼續收集。 PCI 總線學習筆記-PCI9054  http://blog.csdn.net/lg2lh/ar...

    HTML中常用操作關于:頁面跳轉,空格

    1.頁面跳轉 2.空格的代替符...

    freemarker + ItextRender 根據模板生成PDF文件

    1. 制作模板 2. 獲取模板,并將所獲取的數據加載生成html文件 2. 生成PDF文件 其中由兩個地方需要注意,都是關于獲取文件路徑的問題,由于項目部署的時候是打包成jar包形式,所以在開發過程中時直接安照傳統的獲取方法沒有一點文件,但是當打包后部署,總是出錯。于是參考網上文章,先將文件讀出來到項目的臨時目錄下,然后再按正常方式加載該臨時文件; 還有一個問題至今沒有解決,就是關于生成PDF文件...

    猜你喜歡

    電腦空間不夠了?教你一個小秒招快速清理 Docker 占用的磁盤空間!

    Docker 很占用空間,每當我們運行容器、拉取鏡像、部署應用、構建自己的鏡像時,我們的磁盤空間會被大量占用。 如果你也被這個問題所困擾,咱們就一起看一下 Docker 是如何使用磁盤空間的,以及如何回收。 docker 占用的空間可以通過下面的命令查看: TYPE 列出了docker 使用磁盤的 4 種類型: Images:所有鏡像占用的空間,包括拉取下來的鏡像,和本地構建的。 Con...

    requests實現全自動PPT模板

    http://www.1ppt.com/moban/ 可以免費的下載PPT模板,當然如果要人工一個個下,還是挺麻煩的,我們可以利用requests輕松下載 訪問這個主頁,我們可以看到下面的樣式 點每一個PPT模板的圖片,我們可以進入到詳細的信息頁面,翻到下面,我們可以看到對應的下載地址 點擊這個下載的按鈕,我們便可以下載對應的PPT壓縮包 那我們就開始做吧 首先,查看網頁的源代碼,我們可以看到每一...

    Linux C系統編程-線程互斥鎖(四)

    互斥鎖 互斥鎖也是屬于線程之間處理同步互斥方式,有上鎖/解鎖兩種狀態。 互斥鎖函數接口 1)初始化互斥鎖 pthread_mutex_init() man 3 pthread_mutex_init (找不到的情況下首先 sudo apt-get install glibc-doc sudo apt-get install manpages-posix-dev) 動態初始化 int pthread_...

    統計學習方法 - 樸素貝葉斯

    引入問題:一機器在良好狀態生產合格產品幾率是 90%,在故障狀態生產合格產品幾率是 30%,機器良好的概率是 75%。若一日第一件產品是合格品,那么此日機器良好的概率是多少。 貝葉斯模型 生成模型與判別模型 判別模型,即要判斷這個東西到底是哪一類,也就是要求y,那就用給定的x去預測。 生成模型,是要生成一個模型,那就是誰根據什么生成了模型,誰就是類別y,根據的內容就是x 以上述例子,判斷一個生產出...

    精品国产乱码久久久久久蜜桃不卡