Android 串行接口(serial port)编程

本例子来自实际的出租车项目,

背景

客户下载Android/iOS客户端订车系统,出租车司机的Driver系统接受订单后,驾驶至目的地,客户上车,计价器off/on,客户下车。Android程序需要读取计价器的off/on状态,进行后继处理。

解决方案:

利用开源的android-serialport-api项目(http://code.google.com/p/android-serialport-api/),重新连接usb线到Adapter(USB to RS232 adapters,参考http://code.google.com/p/android-serialport-api/wiki/android_to_rs232_guideline?tm=6。),连接后如下图:






编码:

android-serialport-api项目包装了串行接口的通讯,因此我们不需要关心jni的调用等一系列的过程。自带的sample实例,演示了怎样读取串行口的信号码,代码也比较简单,稍微修改拿过来使用即可。直接上代码

SerialApplication.java

package com.whyonly.serial;



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


import android.app.Application;
import android.content.SharedPreferences;
import android.location.Location;
import android.preference.PreferenceManager;
import android.util.Log;
import android_serialport_api.SerialPort;
import android_serialport_api.SerialPortFinder;

public class SerialApplication extends Application{
	private static final String TAG = "SerialApplication";
	private SharedPreferences mPrefs;


	@Override
	public void onCreate(){
		Log.d(TAG,"load....");
		super.onCreate();
		//will save the values to Preference later.
		mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
	}
	
	
	
	public SharedPreferences getmPrefs() {
		return mPrefs;
	}



	public String getUserId() {
		// TODO Auto-generated method stub
		return null;
	}
	
	
	//for serial port
	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);
			SharedPreferences sp = ((SerialApplication)this.getApplicationContext()).getmPrefs();
			String path = sp.getString("DEVICE", "");
			int baudrate = Integer.decode(sp.getString("BAUDRATE", "-1"));

			/* 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 void closeSerialPort() {
		if (mSerialPort != null) {
			mSerialPort.close();
			mSerialPort = null;
		}
	}



	
}

MainActivity.java


package com.whyonly.serial;


import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.view.Menu;

public class MainActivity extends Activity {

	private static final String TAG = "MainActivity";
	
	private USBSerialHelper usbSerialHelper;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		usbSerialHelper = new USBSerialHelper(MainActivity.this);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	public void flag(int onoff) {
		//the message returned from serial port, do anything you want.
		Log.d(TAG,"onoff:"+onoff);
		
	}
	
	@Override
	protected void onDestroy() {
    	super.onDestroy();
    	Log.d(TAG,"onDestroy()");
    	stopUSBSerial();
	}
	
	private void stopUSBSerial() {
		if(usbSerialHelper != null){
			usbSerialHelper.onDestroy();
		}
		
	}

}

USBSerialHelper.java


package com.whyonly.serial;

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


import android_serialport_api.SerialPort;




public class USBSerialHelper {
	
	private MainActivity activity;
	protected SerialApplication mApplication;
	protected SerialPort mSerialPort;
	protected OutputStream mOutputStream;
	private InputStream mInputStream;
	private ReadThread mReadThread;
	
	public USBSerialHelper(final MainActivity mActivity){
		this.activity = mActivity;
		mApplication = (SerialApplication) mActivity.getApplication();
		Preferences.saveUSBSetting(mActivity);
		start();
	}
	
	public void start(){
		try {
			mSerialPort = mApplication.getSerialPort();
			mOutputStream = mSerialPort.getOutputStream();
			mInputStream = mSerialPort.getInputStream();

			/* Create a receiving thread */
			mReadThread = new ReadThread();
			mReadThread.start();
		} catch (SecurityException e) {
			DisplayError(R.string.error_security);
		} catch (IOException e) {
			DisplayError(R.string.error_unknown);
		} catch (InvalidParameterException e) {
			DisplayError(R.string.error_configuration);
		}
	}
	
	private void DisplayError(int resourceId) {
		DialogUtil.showWarningDialog(activity, resourceId);
	}
	
	private String lastStatus = "";//1:flag off;2:flag on;0 power off

	private void onDataReceived(final byte[] buffer, final int size) {
		activity.runOnUiThread(new Runnable() {
			public void run() {
				//receive serial number from usb serial device.
				String signal = new String(buffer, 0, size);
				if(signal.length()>0){
					String status = signal.substring(0,1);
					if(!status.equals("0") && !lastStatus.equals(status)){
						lastStatus = status;
						if(status.equals("1")){//flag on status
							activity.flag(1);
						}else if(status.equals("2")){//flag off status
							activity.flag(0);
						}
					}
				}
			}
		});
	}
	
	public void onDestroy() {
		if (mReadThread != null)
			mReadThread.interrupt();
		mApplication.closeSerialPort();
		mSerialPort = null;
	}
	
	private class ReadThread extends Thread {

		@Override
		public void run() {
			super.run();
			while(!isInterrupted()) {
				int size;
				try {
					byte[] buffer = new byte[64];
					if (mInputStream == null) return;
					size = mInputStream.read(buffer);
					if (size > 0) {
						onDataReceived(buffer, size);
					}
				} catch (IOException e) {
					e.printStackTrace();
					return;
				}
			}
		}
	}
}

Preferences.java


package com.whyonly.serial;

import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;

public class Preferences {
	public static void saveUSBSetting(Context activity){
		SharedPreferences pref = getAppPrefs(activity);
		Editor editor = pref.edit();
		editor.putString("DEVICE", "/dev/ttyUSB0");
		editor.putString("BAUDRATE", "9600");
		editor.commit(); 	
	} 
	
	public static SharedPreferences getAppPrefs(Context context) {
		return ((SerialApplication)context.getApplicationContext()).getmPrefs();
	}
}

DialogUtil.java

package com.whyonly.serial;



import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;

public class DialogUtil {
	
	public static void showWarningDialog(Context context,int messageid){
		showWarningDialog(context,context.getResources().getString(messageid));
	}
	
	public static void showWarningDialog(Context context,String message){
		String warningTitle = context.getResources().getString(R.string.defaultWarningTitle);
		String warningButtonName = context.getResources().getString(R.string.defaultWarningButton);
		showWarningDialog(context,warningTitle,message,warningButtonName);
	}
	
	private static void showWarningDialog(Context context,String title,String message,String positive){
		final AlertDialog.Builder builder = new AlertDialog.Builder(context);
		builder.setTitle(title).setMessage(message);
		builder.setPositiveButton(positive, new DialogInterface.OnClickListener() {  
			public void onClick(DialogInterface dialog, int which) {
				dialog.dismiss();  
			}	
		   });
		builder.create().show();
	}

}

strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <string name="app_name">serial</string>
    <string name="action_settings">Settings</string>
    <string name="hello_world">Hello world!</string>
    <string name="defaultWarningTitle">Taxi Driver</string>
	<string name="defaultWarningButton">Yes</string>
    <string name="error_configuration">Please configure your serial port first.</string>
    <string name="error_security">You do not have read/write permission to the serial
		port.</string>
    <string name="error_unknown">The serial port can not be opened for an unknown
		reason.</string>

</resources>


如需下载整个工程的代码,请到本人的资源列表(下载)。另外,本代码只供学习之用,因此比较简单,不能适用于于所有的串行情况,如果需要应用于工业,请自行处理。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值