我一直在問我關於我的Android項目的問題,該項目不斷地實時繪製藍牙數據。Android應用程序使用靜態方法來傳輸和繪製數據
基本上我已經做是拼湊它已經提出了一些開放源代碼Blueterm和OrientationSensorExample
創建我的應用程序的第一個版本,我添加了一個線程,處理程序,服務,或使用異步任務,或AIDL等,但我不知道如何使用任何這些,並會感謝解釋。
下面是我開始使用的Blueterm開放源代碼的描述(請參閱上面的鏈接)。 Blueterm基本上是一個通過藍牙進行通信的終端仿真器程序。它由Blueterm中最重要的幾項活動組成。它發現,配對並連接支持SPP/RfComm的遠程藍牙設備。連接後,我可以使用Blueterm通過發送命令來打開採樣,改變採樣通道的數量(改爲一個通道),改變輸入數據的格式(我喜歡逗號分隔的數據)等等來配置遠程設備
下面是我開始使用的OrientationSensorExample開放源代碼的描述(請參閱上面的鏈接)。它基本上是AnroidPlot庫的一個示例應用程序。 OrientationSensor活動實現SensorEventListener。這包括覆蓋onSenorChanged(),無論何時取得新的方向傳感器數據,都會調用onSenorChanged(),並重新繪製圖形。
將這兩個開放源代碼項目(Blueterm和OrientationSensorExample)拼湊在一個應用程序(Blueterm)中後,這裏描述了整個應用程序(Blueterm)的工作方式。當我啓動Blueterm時,整個屏幕模擬一個漂亮的藍色終端。從選項菜單中,我發現,配對,連接並配置遠程藍牙設備,如上所述。配置好遠程設備後,我再次進入選項菜單並選擇啓動繪圖活動的「繪圖數據」。終端模擬器消失了,並且Plot活動出現了一個很好的滾動實時圖。
據我可以告訴有如下調用的update()方法在後臺線程:
/**
* Look for new input from the ptty, send it to the terminal emulator.
*/
private void update() {
int bytesAvailable = mByteQueue.getBytesAvailable();
int bytesToRead = Math.min(bytesAvailable, mReceiveBuffer.length);
try {
int bytesRead = mByteQueue.read(mReceiveBuffer, 0, bytesToRead);
append(mReceiveBuffer, 0, bytesRead);
//VTR use existing handler that calls update() to get data into plotting activity
Plot.plotData(mReceiveBuffer, 0, bytesRead);
} catch (InterruptedException e) {
//VTR OMG their swallowing this exception
}
}
在update()方法我認爲很方便叫我Plot.plotData()方法並將其傳遞給傳遞給append()方法的同一日期以繪製數據。注意:這隻適用於plotData()是靜態方法。沒有人能夠解釋爲什麼。
反正plotData()是一個靜態方法,這裏是如何它和它的輔助方法現在看起來:
private static StringBuffer strData = new StringBuffer("");
public static void plotData(byte[] buffer, int base, int length) {
Log.i("Entering: ", "plotData()");
/*
byte[] buffer = (byte[]) msg.obj;
int base = msg.arg1;
int length = msg.arg2;
*/
for (int i = 0; i < length; i++) {
byte b = buffer[base + i];
try {
if (true) {
char printableB = (char) b;
if (b < 32 || b > 126) {
printableB = ' ';
}
Log.w("Log_plotData", "'" + Character.toString(printableB)
+ "' (" + Integer.toString(b) + ")");
strData.append(Character.toString(printableB));
if (b == 10)
{
Log.i("End of line: ", "processBlueData()");
Log.i("strData", strData.toString());
splitData(strData);
strData = new StringBuffer("");
}
}
} catch (Exception e) {
Log.e("Log_plotData_exception", "Exception while processing character "
+ Integer.toString(i) + " code "
+ Integer.toString(b), e);
}
}
Log.i("Leaving: ", "plotData()");
}
private static void splitData(StringBuffer strBuf) {
String strDash = strBuf.toString().trim();
String[] strDashSplit = strDash.split("-");
for (int ndx = 0; ndx < strDashSplit.length; ndx++)
{
if (strDashSplit[ndx].length() > 0)
Log.i("strDashSplit", ndx + ":" + strDashSplit[ndx]);
String strComma = strDashSplit[ndx].trim();
String[] strCommaSplit = strComma.split(",");
for (int mdx = 0; mdx < strCommaSplit.length; mdx++)
{
if (strCommaSplit[mdx].length() > 0)
Log.i("strCommaSplit", mdx + ":" + strCommaSplit[mdx]);
if (mdx == 1)
{
int raw = Integer.parseInt(strCommaSplit[1],16);
Log.i("raw", Integer.toString(raw));
float rawFloat = raw;
Log.i("rawFloat", Float.toString(rawFloat));
float ratio = (float) (rawFloat/65535.0);
Log.i("ratio", Float.toString(ratio));
float voltage = (float) (5.0*ratio);
Log.i("voltage", Float.toString(voltage));
nowPlotData(voltage);
}
}
}
}
public static void nowPlotData(float data) {
// get rid the oldest sample in history:
if (plotHistory.size() > HISTORY_SIZE) {
plotHistory.removeFirst();
}
// add the latest history sample:
plotHistory.addLast(data);
// update the plot with the updated history Lists:
plotHistorySeries.setModel(plotHistory, SimpleXYSeries.ArrayFormat.Y_VALS_ONLY);
//VTR null pointer exception?
if (plotHistoryPlot == null)
Log.i("aprHistoryPlot", "null pointer exception");
// redraw the Plots:
plotHistoryPlot.redraw();
}
如果強烈建議plotData()不是一個靜態方法,我應該做些什麼否則請在這裏解釋以及如何。謝謝!
感謝您的鏈接!我會看看Code Review和CommonsWare的書。 – Vince 2011-06-06 13:18:03
哈!目錄中的章節沒有編號! LOL – Vince 2011-06-06 13:25:45
第20章「處理線索」第255頁,第35章「服務:理論」第503頁,第36章「基本服務模式」,第513頁。當然可以搜索章節標題。我想這次我終於明白了。 – Vince 2011-06-06 18:24:01