Back to project page simple-hud.
The source code is released under:
GNU General Public License
If you think the Android project simple-hud listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.
package com.openxc.hardware.hud; /*ww w.j a v a2s.c o m*/ import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.PrintWriter; import android.app.Service; import android.bluetooth.BluetoothSocket; import android.content.Intent; import android.os.Binder; import android.os.IBinder; import android.util.Log; /** * The HudService manages the connection to the Bluetooth HUD. * * This is meant to be used as an in-process Android service, and all commands * to the HUD go through this class. Users of the service should call connect() * with the HUD's MAC address after the service connects. Once connected, any of * the other methods can be used to control the LEDs. */ public class HudService extends Service implements BluetoothHudInterface { private final String TAG = "HudService"; private final long RETRY_DELAY = 1000; private final long POLL_DELAY = 3000; private DeviceManager mDeviceManager; private PrintWriter mOutStream; private BufferedReader mInStream; private BluetoothSocket mSocket; private final IBinder mBinder = new LocalBinder(); public class LocalBinder extends Binder { public HudService getService() { return HudService.this; } } private ConnectionKeepalive mConnectionKeepalive; private class ConnectionKeepalive implements Runnable { private boolean mRunning; public ConnectionKeepalive() { mRunning = true; } public void stop() { mRunning = false; } public void run() { while(mRunning) { try { connectSocket(); } catch(BluetoothException e) { Log.w(TAG, "Unable to connect to socket", e); try { Thread.sleep(RETRY_DELAY); } catch(InterruptedException e2) { return; } continue; } while(ping() && mRunning){ try { Thread.sleep(POLL_DELAY); } catch(InterruptedException e) { return; } } Log.i(TAG, "Socket " + mSocket + " has been disconnected!"); } } } @Override public void onCreate() { try { mDeviceManager = new DeviceManager(this); } catch(BluetoothException e) { Log.w(TAG, "Unable to open Bluetooth device manager", e); } mSocket = null; } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.i(TAG, "Received start id " + startId + ": " + intent); // We want this service to continue running until it is explicitly // stopped, so return sticky. return START_STICKY; } @Override public void onDestroy() { Log.d(TAG, "Being destroyed"); try { disconnect(); } catch(BluetoothException e) { Log.d(TAG, "Unable to disconnect when being destroyed", e); } } @Override public IBinder onBind(Intent intent) { Log.d(TAG, "Binding from " + intent); return mBinder; } @Override public void disconnect() throws BluetoothException { if(!isConnected()) { Log.w(TAG, "Unable to disconnect -- not connected"); throw new BluetoothException(); } mConnectionKeepalive.stop(); Log.d(TAG, "Disconnecting from the socket " + mSocket); mOutStream.close(); try { mInStream.close(); } catch(IOException e) { Log.w(TAG, "Unable to close the input stream", e); } if(mSocket != null) { try { mSocket.close(); } catch(IOException e) { Log.w(TAG, "Unable to close the socket", e); } } mSocket = null; Log.d(TAG, "Disconnected from the socket"); } @Override public synchronized void set(int chan, double value) throws BluetoothException { if(!isConnected()) { Log.w(TAG, "Unable to set -- not connected"); throw new BluetoothException(); } mOutStream.write("S" + chan + Math.round(value * 255) + "M"); mOutStream.flush(); } @Override public synchronized void setAll(double value) throws BluetoothException { if(!isConnected()) { Log.w(TAG, "Unable to setAll -- not connected"); throw new BluetoothException(); } for(int i = 0; i < 5; i++) { set(i, value); } } @Override public synchronized void fade(int chan, long duration, double value) throws BluetoothException { if(!isConnected()) { Log.w(TAG, "Unable to fade -- not connected"); throw new BluetoothException(); } mOutStream.write("F" + chan + duration + "," + Math.round(value * 255) + "M"); mOutStream.flush(); } @Override public synchronized int rawBatteryLevel() throws BluetoothException { if(!isConnected()) { Log.w(TAG, "Unable to check battery level -- not connected"); throw new BluetoothException(); } mOutStream.write("BM"); mOutStream.flush(); String response = getResponse(mInStream); if(response != null && response.indexOf("VAL:") >= 0) { return Integer.parseInt(response.substring(4)); } else { throw new BluetoothException("Invalid battery level: " + response); } } @Override public void connect(String targetAddress) throws BluetoothException { if(mConnectionKeepalive != null) { mConnectionKeepalive.stop(); } mDeviceManager.connect(targetAddress); mConnectionKeepalive = new ConnectionKeepalive(); new Thread(mConnectionKeepalive).start(); } @Override public synchronized boolean ping() { if(!isConnected()) { Log.w(TAG, "Unable to ping -- not connected"); return false; } mOutStream.write("PM"); mOutStream.flush(); String response = getResponse(mInStream); if(response == null) { Log.w(TAG, "Received unexpected ping response: " + response); try { disconnect(); } catch(BluetoothException e) { Log.w(TAG, "Unable to disconnect after failed ping", e); } return false; } Log.d(TAG, "Ping? Pong!"); return true; } private String getResponse(BufferedReader reader){ String line = ""; try { line = mInStream.readLine(); } catch(IOException e) { Log.e(TAG, "unable to read response"); return null; } if(line == null){ Log.e(TAG, "device has dropped offline"); return null; } return line; } private void connectSocket() throws BluetoothException { try { mSocket = mDeviceManager.setupSocket(); mOutStream = new PrintWriter(new OutputStreamWriter( mSocket.getOutputStream())); mInStream = new BufferedReader(new InputStreamReader( mSocket.getInputStream())); Log.i(TAG, "Socket stream to HUD opened successfully"); } catch(IOException e) { // We are expecting to see "host is down" when repeatedly // autoconnecting if(!(e.toString().contains("Host is Down"))){ Log.d(TAG, "Error opening streams "+e); } else { Log.e(TAG, "Error opening streams "+e); } mSocket = null; throw new BluetoothException(); } } private boolean isConnected() { return mSocket != null; } }