s5p4418 android 驱动 hal 应用之led 串口 rs485 can总线应用(app 有源码)
本篇是繼上篇的jni層后的app應用層。
由于app相對比較大,說起來也比較麻煩,這里就用一個串口來說明即可,實際上也就串口最具代表性,這個明白了,其他都不是問題。
串口涉及的java文件如下圖紅色圈所示:
具體的代碼下面一一貼出來,撿重要的說明:
MainActivity.java:
package com.example.realarmapp;import realarm.can.RealarmCanActivity; import realarm.serial.RealarmUartActivity; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button;public class MainActivity extends Activity implements OnClickListener {private Button btnLED, btnUART, btnRS485, btnCAN;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);btnLED = (Button) findViewById(R.id.btnLED);btnUART = (Button) findViewById(R.id.btnUART);btnRS485 = (Button) findViewById(R.id.btnRS485);btnCAN = (Button) findViewById(R.id.btnCAN);btnLED.setOnClickListener(this);btnUART.setOnClickListener(this);btnRS485.setOnClickListener(this);btnCAN.setOnClickListener(this);}@Overridepublic void onClick(View v) {if(v.equals(btnLED)){Intent i = new Intent(MainActivity.this, RealarmLedActivity.class);startActivity(i);}else if(v.equals(btnUART)) {Intent i = new Intent(MainActivity.this, RealarmUartActivity.class);startActivity(i);}else if(v.equals(btnRS485)) {Intent i = new Intent(MainActivity.this, RealarmUartActivity.class);startActivity(i);}else if(v.equals(btnCAN)) {Intent i = new Intent(MainActivity.this, RealarmCanActivity.class);startActivity(i);}}} 這個文件是主activity文件,沒什么好說的,就是四個按鈕執行不同的功能。HardwareControl.java:
package realarm.hardware;
該文件是聲明native接口,并加載libRealarmHardwareJNI.so庫。
MyApplication.java:
package realarm.serial;import java.io.File; import java.io.IOException; import java.security.InvalidParameterException;import realarm.serial.utils.SerialPort; import realarm.serial.utils.SerialPortFinder;import android.app.Application; import android.content.SharedPreferences; import realarm.hardware.HardwareControl; public class MyApplication extends Application {public SerialPortFinder mSerialPortFinder = new SerialPortFinder();private SerialPort mSerialPort = null;public SerialPort getSerialPort() throws SecurityException, IOException, InvalidParameterException {if (mSerialPort == null) {/* Read serial port parameters */SharedPreferences sp = getSharedPreferences("android_serialport_api.sample_preferences", MODE_PRIVATE);String path = sp.getString("DEVICE", "/dev/ttyAMA4");int baudrate = Integer.decode(sp.getString("BAUDRATE", "115200"));/* Check parameters */if ( (path.length() == 0) || (baudrate == -1)) {throw new InvalidParameterException();}/* Open the serial port */mSerialPort = new SerialPort(new File(path), baudrate, 0);}return mSerialPort;}public SerialPort getSerialPort(String path, String baudrate, int flag) throws NumberFormatException, SecurityException, IOException{if (mSerialPort == null) {/* Open the serial port */mSerialPort = new SerialPort(new File(path), Integer.decode(baudrate), flag);} return mSerialPort;}public void closeSerialPort() {if (mSerialPort != null) {HardwareControl.CloseSerialPort();mSerialPort = null;}} } 該文件實現串口的創建和關閉方法。SerialPort.java: package realarm.serial.utils;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; import realarm.hardware.HardwareControl; 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/xbin/su");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 = HardwareControl.OpenSerialPort(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 setterspublic InputStream getInputStream() {return mFileInputStream;}public OutputStream getOutputStream() {return mFileOutputStream;} } 該文件實現串口的打開、數據輸入、數據輸出的方法。
SerialPortFinder.java:
package realarm.serial.utils;import java.io.File; import java.io.FileReader; import java.io.IOException; import java.io.LineNumberReader; import java.util.Iterator; import java.util.Vector;import android.util.Log;public class SerialPortFinder {private static final String TAG = "SerialPort";private Vector<Driver> mDrivers = null;public class Driver {public Driver(String name, String root) {mDriverName = name;mDeviceRoot = root;}private String mDriverName;private String mDeviceRoot;Vector<File> mDevices = null;public Vector<File> getDevices() {if (mDevices == null) {mDevices = new Vector<File>();File dev = new File("/dev");File[] files = dev.listFiles();int i;for (i = 0; i < files.length; i++) {if (files[i].getAbsolutePath().startsWith(mDeviceRoot)) {Log.d(TAG, "Found new device: " + files[i]);mDevices.add(files[i]);}}}return mDevices;}public String getName() {return mDriverName;}}Vector<Driver> getDrivers() throws IOException {if (mDrivers == null) {mDrivers = new Vector<Driver>();LineNumberReader r = new LineNumberReader(new FileReader("/proc/tty/drivers"));String l;while ((l = r.readLine()) != null) {// Issue 3:// Since driver name may contain spaces, we do not extract// driver name with split()String drivername = l.substring(0, 0x15).trim();String[] w = l.split(" +");if ((w.length >= 5) && (w[w.length - 1].equals("serial"))) {Log.d(TAG, "Found new driver " + drivername + " on "+ w[w.length - 4]);mDrivers.add(new Driver(drivername, w[w.length - 4]));}}r.close();}return mDrivers;}public String[] getAllDevices() {Vector<String> devices = new Vector<String>();// Parse each driverIterator<Driver> itdriv;try {itdriv = getDrivers().iterator();while (itdriv.hasNext()) {Driver driver = itdriv.next();Iterator<File> itdev = driver.getDevices().iterator();while (itdev.hasNext()) {String device = itdev.next().getName();String value = String.format("%s (%s)", device,driver.getName());devices.add(value);}}} catch (IOException e) {e.printStackTrace();}return devices.toArray(new String[devices.size()]);}public String[] getAllDevicesPath() {Vector<String> devices = new Vector<String>();// Parse each driverIterator<Driver> itdriv;try {itdriv = getDrivers().iterator();while (itdriv.hasNext()) {Driver driver = itdriv.next();Iterator<File> itdev = driver.getDevices().iterator();while (itdev.hasNext()) {String device = itdev.next().getAbsolutePath();devices.add(device);}}} catch (IOException e) {e.printStackTrace();}return devices.toArray(new String[devices.size()]);} } 該文件實現應用程序在/dev目錄下檢索tty*節點的方法。
RealarmUartActivity.java:
也許有朋友在http://blog.csdn.net/tangcheng_ok/article/details/7021470這篇文章時,就遇到了這個問題,雖然編譯通過,可是運行就會蹦掉。當然了,我也看了,而且遇到了。
那么這是怎么回事呢,通過報錯提示“找不到資源”,可以知道當執行到紅色部分時,應用程序無法找到資源。可是我們明明定義了MyApplication這個類,且繼承與Application,為什么會找不到呢。代碼定義當然沒問題,實際上問題出在沒有告訴app我定義了這個MyApplication。只需要在AndroidManifest.xml文件中添加下面紅色的代碼即可解決問題:
這句代碼就是告訴app要使用MyApplication這個繼承與Application的類。
下面貼出運行的界面,O(∩_∩)O。
主界面:
led操作界面:
串口操作界面:
485與串口區別就是打開的串口號不同:
can操作界面:
再來個豎屏的,在布局時考慮到了適應問題,所以沒有采用絕對布局,可以適應各分辨率大小的屏幕,只要分辨率不要太小,完全顯示都是沒問題的。
源碼下載地址:http://download.csdn.net/detail/u010406724/8539209
轉載請注明出處:http://blog.csdn.net/wang_shuai_ww/article/details/44676937
總結
以上是生活随笔為你收集整理的s5p4418 android 驱动 hal 应用之led 串口 rs485 can总线应用(app 有源码)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android应用开发 led 驱动层
- 下一篇: healthd: battery l=1