小R科技-WIFI机器人网·机器人创意工作室

 找回密码
 立即注册
查看: 45129|回复: 49

Android手机蓝牙控制智能小车机器人V2.0源代码

[复制链接]
发表于 2012-7-29 12:08:05 | 显示全部楼层 |阅读模式
BluetoothCar.java


  1. package com.BluetoothCar.liuviking;

  2. import java.io.DataInputStream;
  3. import java.io.DataOutputStream;
  4. import java.io.IOException;
  5. import java.io.InputStream;
  6. import java.io.OutputStream;
  7. import java.io.UnsupportedEncodingException;
  8. import java.util.UUID;
  9. import android.app.Activity;
  10. import android.bluetooth.BluetoothAdapter;
  11. import android.bluetooth.BluetoothDevice;
  12. import android.bluetooth.BluetoothSocket;
  13. import android.content.Intent;
  14. import android.content.SharedPreferences;
  15. import android.graphics.Color;
  16. import android.os.Bundle;
  17. import android.os.Handler;
  18. import android.os.Message;
  19. import android.util.Log;
  20. import android.view.KeyEvent;
  21. import android.view.Menu;
  22. import android.view.MenuInflater;
  23. import android.view.MenuItem;
  24. import android.view.MotionEvent;
  25. import android.view.View;
  26. import android.view.WindowManager;
  27. import android.view.View.OnTouchListener;
  28. import android.view.Window;
  29. import android.view.View.OnClickListener;
  30. import android.view.inputmethod.EditorInfo;
  31. import android.widget.ArrayAdapter;
  32. import android.widget.Button;
  33. import android.widget.EditText;
  34. import android.widget.ImageButton;
  35. import android.widget.ListView;
  36. import android.widget.TextView;
  37. import android.widget.Toast;
  38. /**
  39. * 这是主要的活动显示当前聊天会话。
  40. */
  41. public class BluetoothCar extends Activity {
  42.     // Debugging

  43.     private static final String TAG = "BluetoothChat";
  44.     private static final boolean D = true;
  45.     //从 BluetoothChatService 处理程序发送的消息类型
  46.     // Message types sent from the BluetoothChatService Handler
  47.     public static final int MESSAGE_STATE_CHANGE = 1;
  48.     public static final int MESSAGE_READ = 2;
  49.     public static final int MESSAGE_WRITE = 3;
  50.     public static final int MESSAGE_DEVICE_NAME = 4;
  51.     public static final int MESSAGE_TOAST = 5;
  52. private String DEFULT_PRES = "0";
  53.     public static final String PREFS_NAME = "BluetoothCar";
  54.     public static final String DEVICE_NAME = "device_name";
  55.     public static final String TOAST = "toast";
  56.     // Intent request codes意向请求代码
  57.     private static final int REQUEST_CONNECT_DEVICE = 1;
  58.     private static final int REQUEST_ENABLE_BT = 2;
  59.     // Layout Views布局视图
  60.     private TextView mTitle;
  61.     private ListView mConversationView;
  62.     private EditText mOutEditText;
  63.     private Button mSendButton;
  64.     private String up,down,left,right,stop;
  65.     private ImageButton mForward,mBack,mLeft,mRight,mStop;
  66.     // 连接的设备名称
  67.     private String mConnectedDeviceName = null;
  68.     // 对话线程数组适配器
  69.     private ArrayAdapter<String> mConversationArrayAdapter;
  70.     // 本地蓝牙适配器
  71.     private BluetoothAdapter mBluetoothAdapter = null;
  72.     //发送服务
  73.     private BluetoothChatService mChatService = null;
  74.     @Override
  75.     public void onCreate(Bundle savedInstanceState) {
  76.         super.onCreate(savedInstanceState);
  77.         if(D) Log.e(TAG, "+++ ON CREATE +++");
  78.       
  79.         // Set up the window layout设置窗口布局
  80.         requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
  81.         setContentView(R.layout.main1);
  82.         getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.custom_title);
  83.         this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
  84.     WindowManager.LayoutParams.FLAG_FULLSCREEN);
  85.   
  86.         // 设置自定义标题
  87.         mTitle = (TextView) findViewById(R.id.title_left_text);
  88.         mTitle.setText(R.string.app_name);
  89.         mTitle = (TextView) findViewById(R.id.title_right_text);
  90.         onShow();//读取配置文件
  91.         // 获取本地蓝牙适配器
  92.         mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
  93.         // 如果空适配器那么蓝牙不受支持
  94.         if (mBluetoothAdapter == null) {
  95.             Toast.makeText(this, "蓝牙设备不可用!", Toast.LENGTH_LONG).show();
  96.             finish();
  97.             return;
  98.         }
  99.         Intent serverIntent = new Intent(this, DeviceListActivity.class);
  100.         startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE);
  101.     }
  102.     @Override
  103.     public void onStart() {
  104.         super.onStart();
  105.         if(D) Log.e(TAG, "++ ON START ++");
  106.         // 如果BT未启动,请求启用它。
  107.         // 然后将调用期间 onActivityResult
  108.         if (!mBluetoothAdapter.isEnabled()) {
  109.             Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
  110.             startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
  111.         // 否则,设置聊天会话
  112.         } else {
  113.             if (mChatService == null)
  114.              setupControl();
  115.         }
  116.     }
  117.     @Override
  118.     public synchronized void onResume() {
  119.         super.onResume();
  120.         if(D) Log.e(TAG, "+ ON RESUME +");
  121.         if (mChatService != null) {
  122.             
  123.          //只有当开始是STATE_NONE,表明还没真正连接
  124.             if (mChatService.getState() == BluetoothChatService.STATE_NONE) {
  125.               // 启动蓝牙设备服务
  126.               mChatService.start();
  127.             }
  128.         }
  129.     }
  130.     private void setupControl() {
  131.         // 初始化一个侦听程序,单击事件的发送按钮
  132.         
  133.         mForward = (ImageButton) findViewById(R.id.Forward);
  134.         mForward.setOnTouchListener(new OnTouchListener() {
  135.    @Override
  136.    public boolean onTouch(View v, MotionEvent event) {
  137.     // TODO Auto-generated method stub
  138.     switch (event.getAction()) {
  139.     case MotionEvent.ACTION_DOWN:
  140.      
  141.      sendMessage(up);
  142.      break;
  143.     case MotionEvent.ACTION_UP:
  144.      
  145.      sendMessage(stop);
  146.      break;
  147.     }
  148.     return false;
  149.    }
  150.    
  151.         });
  152.         mBack = (ImageButton) findViewById(R.id.Back);
  153.         mBack.setOnTouchListener(new OnTouchListener() {
  154.    @Override
  155.    public boolean onTouch(View v, MotionEvent event) {
  156.     // TODO Auto-generated method stub
  157.     switch (event.getAction()) {
  158.     case MotionEvent.ACTION_DOWN:
  159.      sendMessage(down);
  160.      break;
  161.     case MotionEvent.ACTION_UP:
  162.      sendMessage(stop);
  163.      break;
  164.     }
  165.     return false;
  166.    }
  167.    
  168.         });
  169.         mLeft = (ImageButton) findViewById(R.id.Left);
  170.         mLeft.setOnTouchListener(new OnTouchListener() {
  171.    @Override
  172.    public boolean onTouch(View v, MotionEvent event) {
  173.     // TODO Auto-generated method stub
  174.     switch (event.getAction()) {
  175.     case MotionEvent.ACTION_DOWN:
  176.      sendMessage(left);
  177.      break;
  178.     case MotionEvent.ACTION_UP:
  179.      sendMessage(stop);
  180.      break;
  181.     }
  182.     return false;
  183.    }
  184.    
  185.         });
  186.         mRight = (ImageButton) findViewById(R.id.Right);
  187.         mRight.setOnTouchListener(new OnTouchListener() {
  188.    @Override
  189.    public boolean onTouch(View v, MotionEvent event) {
  190.     // TODO Auto-generated method stub
  191.     switch (event.getAction()) {
  192.     case MotionEvent.ACTION_DOWN:
  193.      sendMessage(right);
  194.      break;
  195.     case MotionEvent.ACTION_UP:
  196.      sendMessage(stop);
  197.      break;
  198.     }
  199.     return false;
  200.    }
  201.    
  202.         });
  203.         mStop = (ImageButton) findViewById(R.id.Stop);
  204.         mStop.setOnTouchListener(new OnTouchListener() {
  205.    @Override
  206.    public boolean onTouch(View v, MotionEvent event) {
  207.     // TODO Auto-generated method stub
  208.     switch (event.getAction()) {
  209.     case MotionEvent.ACTION_DOWN:
  210.      sendMessage(stop);
  211.      break;
  212.     case MotionEvent.ACTION_UP:
  213.      sendMessage(stop);
  214.      break;
  215.     }
  216.     return false;
  217.    }
  218.    
  219.         });
  220.         
  221.         //初始化执行蓝牙连接 BluetoothChatService
  222.         mChatService = new BluetoothChatService(this, mHandler);
  223.     }
  224.     @Override
  225.     public synchronized void onPause() {
  226.         super.onPause();
  227.         if(D) Log.e(TAG, "- ON PAUSE -");
  228.     }
  229.     @Override
  230.     public void onStop() {
  231.         super.onStop();
  232.         if(D) Log.e(TAG, "-- ON STOP --");
  233.     }
  234.     @Override
  235.     public void onDestroy() {
  236.         super.onDestroy();
  237.         //停止蓝牙聊天服务
  238.         if (mChatService != null) mChatService.stop();
  239.         if(D) Log.e(TAG, "--- ON DESTROY ---");
  240.     }
  241.     private void ensureDiscoverable() {
  242.         if(D) Log.d(TAG, "ensure discoverable");
  243.         if (mBluetoothAdapter.getScanMode() !=
  244.             BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
  245.             Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
  246.             discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
  247.             startActivity(discoverableIntent);
  248.         }
  249.     }
  250.     /**
  251.      * 发送数据
  252.      * @param message  A string of text to send.
  253.      */
  254.     private void sendMessage(String message) {
  255.         // 检查是否真正连上
  256.         if (mChatService.getState() != BluetoothChatService.STATE_CONNECTED) {
  257.             Toast.makeText(this, R.string.not_connected, Toast.LENGTH_SHORT).show();
  258.             return;
  259.         }
  260.         // 检查有什么实际发送
  261.         if (message.length() > 0) {
  262.             // 获取消息字节并写入 BluetoothChatService
  263.             byte[] send = message.getBytes();      
  264.             mChatService.write(send);      
  265.         }
  266.     }
  267.     //是从该 BluetoothChatService 重新获取信息显示在UI的处理程序
  268.     private final Handler mHandler = new Handler() {
  269.         @Override
  270.         public void handleMessage(Message msg) {
  271.             switch (msg.what) {
  272.             case MESSAGE_STATE_CHANGE:
  273.                 if(D) Log.i(TAG, "MESSAGE_STATE_CHANGE: " + msg.arg1);
  274.                 switch (msg.arg1) {
  275.                 case BluetoothChatService.STATE_CONNECTED:
  276.                     mTitle.setText(R.string.title_connected_to);
  277.                     mTitle.append(mConnectedDeviceName);
  278.                     //mConversationArrayAdapter.clear();
  279.                     break;
  280.                 case BluetoothChatService.STATE_CONNECTING:
  281.                     mTitle.setText(R.string.title_connecting);
  282.                     break;
  283.                 case BluetoothChatService.STATE_LISTEN:
  284.                 case BluetoothChatService.STATE_NONE:
  285.                     mTitle.setText(R.string.title_not_connected);
  286.                     BluetoothAdapter cwjBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
  287.                     
  288.                     if(cwjBluetoothAdapter == null){
  289.                      Toast.makeText(
  290.                  BluetoothCar.this,"本机没有找到蓝牙硬件或驱动存在问题",
  291.                  Toast.LENGTH_SHORT)
  292.                  .show();
  293.                     }
  294.                     if (!cwjBluetoothAdapter.isEnabled()) {
  295.                      Intent TurnOnBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
  296.                      startActivityForResult(TurnOnBtIntent, REQUEST_ENABLE_BT);
  297.                      }

  298.                     break;
  299.                 }
  300.                 break;
  301.             case MESSAGE_WRITE:
  302.             
  303.                 break;
  304.             case MESSAGE_READ:
  305.             
  306.                 break;
  307.             case MESSAGE_DEVICE_NAME:
  308.                 //保存连接设备名称
  309.                 mConnectedDeviceName = msg.getData().getString(DEVICE_NAME);
  310.                 Toast.makeText(getApplicationContext(), "已成功连接到: "
  311.                                + mConnectedDeviceName+"可以开始操纵小车了!", Toast.LENGTH_SHORT).show();
  312.                 break;
  313.             case MESSAGE_TOAST:
  314.                 Toast.makeText(getApplicationContext(), msg.getData().getString(TOAST),
  315.                                Toast.LENGTH_SHORT).show();
  316.                 break;
  317.             }
  318.         }
  319.     };
  320.     public void onActivityResult(int requestCode, int resultCode, Intent data) {
  321.         if(D) Log.d(TAG, "onActivityResult " + resultCode);
  322.         
  323.         switch (requestCode) {
  324.         case REQUEST_CONNECT_DEVICE:  
  325.          if (resultCode == Activity.RESULT_OK) {
  326.                 // 获取设备地址
  327.                 String address = data.getExtras()
  328.                                      .getString(DeviceListActivity.EXTRA_DEVICE_ADDRESS);
  329.                 Toast.makeText(this, "该设备MAC地址为--->"+address, Toast.LENGTH_SHORT).show();
  330.                 //获取设备对象
  331.                 BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
  332.                 UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb");
  333.                 try {
  334.      device.createRfcommSocketToServiceRecord(uuid);
  335.     } catch (IOException e1) {
  336.      // TODO Auto-generated catch block
  337.      e1.printStackTrace();
  338.     }
  339.                 // Attempt to connect to the device
  340.                 mChatService.connect(device);   
  341.             }
  342.             break;
  343.         case REQUEST_ENABLE_BT:
  344.             //当启用蓝牙的请求返回时
  345.             if (resultCode == Activity.RESULT_OK) {
  346.                 // 蓝牙现已启用,因此成立聊天会话
  347.              setupControl();
  348.             } else {
  349.                 // 用户没有启用蓝牙或发生错误
  350.                 Log.d(TAG, "BT not enabled");
  351.                 Toast.makeText(this, R.string.bt_not_enabled_leaving, Toast.LENGTH_SHORT).show();
  352.                 finish();
  353.             }
  354.         }
  355.     }
  356.     @Override
  357.     public boolean onCreateOptionsMenu(Menu menu) {
  358.         MenuInflater inflater = getMenuInflater();
  359.         inflater.inflate(R.menu.option_menu, menu);
  360.         return true;
  361.     }
  362.     @Override
  363.     public boolean onOptionsItemSelected(MenuItem item) {
  364.         switch (item.getItemId()) {
  365.         case R.id.scan:
  366.             // 若要查看设备 DeviceListActivity 启动并扫描
  367.             Intent serverIntent = new Intent(this, DeviceListActivity.class);
  368.             startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE);
  369.             return true;
  370.         case R.id.discoverable:
  371.             // 确保此设备是可被其他人发现
  372.             ensureDiscoverable();
  373.             return true;
  374.         case R.id.config:
  375.          Intent intent = new Intent();  
  376.    intent.setClass(BluetoothCar.this,ControlConfig.class);
  377.    BluetoothCar.this.startActivity(intent);
  378.    BluetoothCar.this.finish();
  379.         }
  380.         return false;
  381.     }
  382.     private void onShow() {
  383.         // TODO Auto-generated method stub
  384.        SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);      
  385.         up=settings.getString("Up", DEFULT_PRES);  
  386.         down=settings.getString("Down", DEFULT_PRES);   
  387.         left=settings.getString("Left", DEFULT_PRES);
  388.         right=settings.getString("Right", DEFULT_PRES);
  389.         stop=settings.getString("Stop", DEFULT_PRES);

  390. }
  391. }
复制代码
BluetoothChatService.java

  1. package com.BluetoothCar.liuviking;

  2. import java.io.IOException;
  3. import java.io.InputStream;
  4. import java.io.OutputStream;
  5. import java.util.UUID;

  6. import android.bluetooth.BluetoothAdapter;
  7. import android.bluetooth.BluetoothDevice;
  8. import android.bluetooth.BluetoothServerSocket;
  9. import android.bluetooth.BluetoothSocket;
  10. import android.content.Context;
  11. import android.os.Bundle;
  12. import android.os.Handler;
  13. import android.os.Message;
  14. import android.util.Log;

  15. public class BluetoothChatService {
  16. // Debugging
  17. private static final String TAG = "BluetoothCarService";
  18. private static final boolean D = true;

  19. // Name for the SDP record when creating server socket
  20. private static final String NAME = "BluetoothCar";

  21. // Unique UUID for this application
  22. private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb");

  23. // Member fields
  24. private final BluetoothAdapter mAdapter;
  25. private final Handler mHandler;
  26. private AcceptThread mAcceptThread;
  27. private ConnectThread mConnectThread;
  28. private ConnectedThread mConnectedThread;
  29. private int mState;


  30. // Constants that indicate the current connection state
  31. public static final int STATE_NONE = 0; // we're doing nothing
  32. public static final int STATE_LISTEN = 1; // now listening for incoming connections
  33. public static final int STATE_CONNECTING = 2; // now initiating an outgoing connection
  34. public static final int STATE_CONNECTED = 3; // now connected to a remote device

  35. /**
  36. * Constructor. Prepares a new BluetoothChat session.
  37. * @param context The UI Activity Context
  38. * @param handler A Handler to send messages back to the UI Activity
  39. */
  40. public BluetoothChatService(Context context, Handler handler) {
  41. mAdapter = BluetoothAdapter.getDefaultAdapter();
  42. mState = STATE_NONE;
  43. mHandler = handler;
  44. }

  45. /**
  46. * Set the current state of the chat connection
  47. * @param state An integer defining the current connection state
  48. */
  49. private synchronized void setState(int state) {
  50. if (D) Log.d(TAG, "setState() " + mState + " -> " + state);
  51. mState = state;

  52. // Give the new state to the Handler so the UI Activity can update
  53. mHandler.obtainMessage(BluetoothCar.MESSAGE_STATE_CHANGE, state, -1).sendToTarget();
  54. }

  55. /**
  56. * Return the current connection state. */
  57. public synchronized int getState() {
  58. return mState;
  59. }

  60. /**
  61. * Start the chat service. Specifically start AcceptThread to begin a
  62. * session in listening (server) mode. Called by the Activity onResume() */
  63. public synchronized void start() {
  64. if (D) Log.d(TAG, "start");

  65. // 取消所有线程意图以创建一个连接
  66. //if (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;}

  67. // 取消当前线程来运行一个连接
  68. // if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;}
  69. /*
  70. // 通过BluetoothServerSocket,开始一个线程
  71. if (mAcceptThread == null) {
  72. mAcceptThread = new AcceptThread();
  73. mAcceptThread.start();
  74. }*/
  75. //if(mConnectThread==null)
  76. // {
  77. // mConnectThread = new ConnectThread(null);
  78. // mConnectThread.start();
  79. // }
  80. setState(STATE_LISTEN);
  81. }

  82. /**
  83. * Start the ConnectThread to initiate a connection to a remote device.
  84. * @param device The BluetoothDevice to connect
  85. */
  86. public synchronized void connect(BluetoothDevice device) {
  87. if (D) Log.d(TAG, "connect to: " + device);

  88. // Cancel any thread attempting to make a connection
  89. if (mState == STATE_CONNECTING) {
  90. if (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;}
  91. }

  92. // Cancel any thread currently running a connection
  93. if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;}

  94. // Start the thread to connect with the given device
  95. mConnectThread = new ConnectThread(device);
  96. mConnectThread.start();
  97. setState(STATE_CONNECTING);
  98. }

  99. /**
  100. * 开始一个ConnectedThread,开始管理蓝牙连接
  101. * @param socket The BluetoothSocket on which the connection was made
  102. * @param device The BluetoothDevice that has been connected
  103. */
  104. public synchronized void connected(BluetoothSocket socket, BluetoothDevice device) {
  105. if (D) Log.d(TAG, "connected");

  106. // 取消已完成连接的线程
  107. if (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;}

  108. // Cancel any thread currently running a connection
  109. if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;}

  110. // Cancel the accept thread because we only want to connect to one device
  111. if (mAcceptThread != null) {mAcceptThread.cancel(); mAcceptThread = null;}

  112. // 开启连接到服务器线程
  113. mConnectedThread = new ConnectedThread(socket);
  114. mConnectedThread.start();

  115. // 把MAC地址发回 UI Activity
  116. Message msg = mHandler.obtainMessage(BluetoothCar.MESSAGE_DEVICE_NAME);
  117. Bundle bundle = new Bundle();
  118. bundle.putString(BluetoothCar.DEVICE_NAME, device.getName());
  119. msg.setData(bundle);
  120. mHandler.sendMessage(msg);

  121. setState(STATE_CONNECTED);
  122. }

  123. /**
  124. * Stop all threads
  125. */
  126. public synchronized void stop() {
  127. if (D) Log.d(TAG, "stop");
  128. if (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;}
  129. if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;}
  130. if (mAcceptThread != null) {mAcceptThread.cancel(); mAcceptThread = null;}
  131. setState(STATE_NONE);
  132. }

  133. /**
  134. * Write to the ConnectedThread in an unsynchronized manner
  135. * @param out The bytes to write
  136. * @see ConnectedThread#write(byte[])
  137. */
  138. public void write(byte[] out) {
  139. // Create temporary object
  140. ConnectedThread r;
  141. // Synchronize a copy of the ConnectedThread
  142. synchronized (this) {
  143. if (mState != STATE_CONNECTED) return;
  144. r = mConnectedThread;
  145. }
  146. // Perform the write unsynchronized
  147. r.write(out);
  148. }

  149. /**
  150. * 连接失败时在UI上显示.
  151. */
  152. private void connectionFailed() {
  153. setState(STATE_LISTEN);

  154. // 失败信息发回Activity
  155. Message msg = mHandler.obtainMessage(BluetoothCar.MESSAGE_TOAST);
  156. Bundle bundle = new Bundle();
  157. bundle.putString(BluetoothCar.TOAST, "无法连接到设备,请确认下位机蓝牙功能是否正常");
  158. msg.setData(bundle);
  159. mHandler.sendMessage(msg);
  160. }

  161. /**
  162. * 丢失连接时在UI上显示.
  163. */
  164. private void connectionLost() {
  165. setState(STATE_LISTEN);

  166. // 失败信息发回Activity
  167. Message msg = mHandler.obtainMessage(BluetoothCar.MESSAGE_TOAST);
  168. Bundle bundle = new Bundle();
  169. bundle.putString(BluetoothCar.TOAST, "与目标设备连接丢失");
  170. msg.setData(bundle);
  171. mHandler.sendMessage(msg);
  172. }

  173. /**
  174. * This thread runs while listening for incoming connections. It behaves
  175. * like a server-side client. It runs until a connection is accepted
  176. * (or until cancelled).
  177. */
  178. private class AcceptThread extends Thread {
  179. // The local server socket
  180. private final BluetoothServerSocket mmServerSocket;

  181. public AcceptThread() {
  182. BluetoothServerSocket tmp = null;

  183. // Create a new listening server socket
  184. try {
  185. tmp = mAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);
  186. } catch (IOException e) {
  187. Log.e(TAG, "listen() failed", e);
  188. }
  189. mmServerSocket = tmp;

  190. }

  191. public void run() {
  192. if (D) Log.d(TAG, "BEGIN mAcceptThread" + this);
  193. setName("AcceptThread");
  194. BluetoothSocket socket = null;

  195. // Listen to the server socket if we're not connected
  196. while (mState != STATE_CONNECTED) {
  197. try {
  198. // This is a blocking call and will only return on a
  199. // successful connection or an exception
  200. socket=mmServerSocket.accept();
  201. } catch (IOException e) {
  202. Log.e(TAG, "accept() failed", e);
  203. break;
  204. }

  205. // 如果连接已经接受
  206. if (socket != null) {
  207. synchronized (BluetoothChatService.this) {
  208. switch (mState) {
  209. case STATE_LISTEN:
  210. case STATE_CONNECTING:
  211. // Situation normal. Start the connected thread.
  212. connected(socket, socket.getRemoteDevice());
  213. break;
  214. case STATE_NONE:
  215. case STATE_CONNECTED:
  216. // 如果没有准备好或者无连接,则终止Socket
  217. try {
  218. socket.close();
  219. } catch (IOException e) {
  220. Log.e(TAG, "Could not close unwanted socket", e);
  221. }
  222. break;
  223. }
  224. }
  225. }
  226. }
  227. if (D) Log.i(TAG, "END mAcceptThread");
  228. }

  229. public void cancel() {
  230. if (D) Log.d(TAG, "cancel " + this);
  231. try {
  232. mmServerSocket.close();
  233. } catch (IOException e) {
  234. Log.e(TAG, "close() of server failed", e);
  235. }
  236. }
  237. }


  238. /**
  239. * This thread runs while attempting to make an outgoing connection
  240. * with a device. It runs straight through; the connection either
  241. * succeeds or fails.
  242. */
  243. private class ConnectThread extends Thread {
  244. private final BluetoothSocket mmSocket;
  245. private final BluetoothDevice mmDevice;

  246. public ConnectThread(BluetoothDevice device) {
  247. mmDevice = device;
  248. BluetoothSocket tmp = null;

  249. //通过蓝牙设备从蓝牙连接中获取一个socket

  250. try {
  251. tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
  252. } catch (IOException e) {
  253. Log.e(TAG, "create() failed", e);
  254. }
  255. mmSocket = tmp;
  256. }

  257. public void run() {
  258. Log.i(TAG, "BEGIN mConnectThread");
  259. setName("连接线程");

  260. // 当关闭连接后,设备可见性设为不可见
  261. mAdapter.cancelDiscovery();

  262. // Make a connection to the BluetoothSocket
  263. try {
  264. // This is a blocking call and will only return on a
  265. // successful connection or an exception
  266. mmSocket.connect();
  267. } catch (IOException e) {
  268. connectionFailed();
  269. // 关闭Socket
  270. try {
  271. mmSocket.close();
  272. } catch (IOException e2) {
  273. Log.e(TAG, "unable to close() socket during connection failure", e2);
  274. }
  275. // Start the service over to restart listening mode
  276. BluetoothChatService.this.start();
  277. return;
  278. }

  279. // Reset the ConnectThread because we're done
  280. synchronized (BluetoothChatService.this) {
  281. mConnectThread = null;
  282. }

  283. // Start the connected thread
  284. connected(mmSocket, mmDevice);
  285. }

  286. public void cancel() {
  287. try {
  288. mmSocket.close();
  289. } catch (IOException e) {
  290. Log.e(TAG, "close() of connect socket failed", e);
  291. }
  292. }
  293. }

  294. /**
  295. * 该线程在取得连接后执行
  296. * It handles all incoming and outgoing transmissions.
  297. */
  298. private class ConnectedThread extends Thread {
  299. private final BluetoothSocket mmSocket;
  300. private final InputStream mmInStream;
  301. private final OutputStream mmOutStream;

  302. public ConnectedThread(BluetoothSocket socket) {
  303. Log.d(TAG, "create ConnectedThread");
  304. mmSocket = socket;
  305. InputStream tmpIn = null;
  306. OutputStream tmpOut = null;

  307. // Get the BluetoothSocket input and output streams
  308. try {
  309. tmpIn = socket.getInputStream();
  310. tmpOut = socket.getOutputStream();
  311. } catch (IOException e) {
  312. Log.e(TAG, "temp sockets not created", e);
  313. }

  314. mmInStream = tmpIn;
  315. mmOutStream = tmpOut;
  316. }

  317. public void run() {
  318. Log.i(TAG, "BEGIN mConnectedThread");
  319. byte[] buffer = new byte[1024];
  320. int bytes;

  321. //保持监听
  322. while (true) {
  323. try {
  324. // 从InputStream读取
  325. bytes = mmInStream.read(buffer);

  326. // Send the obtained bytes to the UI Activity
  327. mHandler.obtainMessage(BluetoothCar.MESSAGE_READ, bytes, -1, buffer)
  328. .sendToTarget();
  329. } catch (IOException e) {
  330. Log.e(TAG, "disconnected", e);
  331. connectionLost();
  332. break;
  333. }
  334. }
  335. }

  336. /**
  337. * Write to the connected OutStream.
  338. * @param buffer The bytes to write
  339. */
  340. public void write(byte[] buffer) {
  341. try {
  342. mmOutStream.write(buffer);
  343. // 把发送的内容在UI上显示
  344. mHandler.obtainMessage(BluetoothCar.MESSAGE_WRITE, -1, -1, buffer)
  345. .sendToTarget();
  346. } catch (IOException e) {
  347. Log.e(TAG, "Exception during write", e);
  348. }
  349. }

  350. public void cancel() {
  351. try {
  352. mmSocket.close();
  353. } catch (IOException e) {
  354. Log.e(TAG, "close() of connect socket failed", e);
  355. }
  356. }
  357. }
  358. }
复制代码
ControlConfig.java
  1. package com.BluetoothCar.liuviking;

  2. import android.app.Activity;
  3. import android.content.Intent;
  4. import android.content.SharedPreferences;
  5. import android.os.Bundle;
  6. import android.text.TextUtils;
  7. import android.util.Log;
  8. import android.view.View;
  9. import android.widget.Button;
  10. import android.widget.EditText;
  11. import android.widget.Toast;

  12. public class ControlConfig extends Activity{
  13. private Button MbuttonOK,MbuttonCancle;
  14. private EditText MUp,MDown,MLeft,MRight,MStop;
  15. private String DEFULT_PRES = "0";
  16. public static final String PREFS_NAME = "BluetoothCar";
  17. @Override
  18. public void onCreate(Bundle savedInstanceState) {
  19. super.onCreate(savedInstanceState);
  20. setContentView(R.layout.configforcontrol);
  21. MbuttonOK=(Button) findViewById(R.id.btnControlOK);
  22. MbuttonCancle=(Button) findViewById(R.id.btnControlCancel);

  23. MUp=(EditText) findViewById(R.id.editUp);
  24. MDown=(EditText) findViewById(R.id.editDown);
  25. MLeft=(EditText) findViewById(R.id.editLeft);
  26. MRight=(EditText) findViewById(R.id.editRight);
  27. MStop=(EditText) findViewById(R.id.editStop);
  28. onShow();//读取预先的配置
  29. MbuttonOK.setOnClickListener(new Button.OnClickListener(){

  30. @Override
  31. public void onClick(View v) {
  32. // TODO Auto-generated method stub
  33. onSave();
  34. Toast.makeText(ControlConfig.this,String.valueOf("控制命令储存成功!"),Toast.LENGTH_SHORT).show();
  35. Intent intent = new Intent();
  36. intent.setClass(ControlConfig.this,BluetoothCar.class);
  37. ControlConfig.this.startActivity(intent);
  38. ControlConfig.this.finish();
  39. }

  40. });

  41. MbuttonCancle.setOnClickListener(new Button.OnClickListener(){

  42. @Override
  43. public void onClick(View v) {
  44. // TODO Auto-generated method stub
  45. Intent intent = new Intent();
  46. intent.setClass(ControlConfig.this,BluetoothCar.class);
  47. ControlConfig.this.startActivity(intent);
  48. ControlConfig.this.finish();
  49. }

  50. });




  51. }

  52. private void onSave() {

  53. // TODO Auto-generated method stub
  54. if (TextUtils.isEmpty(MUp.getText().toString())) {
  55. setPreferences("Up",DEFULT_PRES);
  56. } else {

  57. String mPreferences = MUp.getText().toString();
  58. Log.v("a",mPreferences);
  59. setPreferences("Up",mPreferences);
  60. }
  61. if (TextUtils.isEmpty(MDown.getText().toString())) {
  62. setPreferences("Down",DEFULT_PRES);
  63. } else {

  64. String mPreferences = MDown.getText().toString();
  65. Log.v("b",mPreferences);
  66. setPreferences("Down",mPreferences);
  67. }

  68. if (TextUtils.isEmpty(MLeft.getText().toString())) {
  69. setPreferences("Left",DEFULT_PRES);
  70. } else {

  71. String mPreferences = MLeft.getText().toString();
  72. Log.v("c",mPreferences);
  73. setPreferences("Left",mPreferences);
  74. }

  75. if (TextUtils.isEmpty(MRight.getText().toString())) {
  76. setPreferences("Right",DEFULT_PRES);
  77. } else {

  78. String mPreferences = MRight.getText().toString();
  79. Log.v("c",mPreferences);
  80. setPreferences("Right",mPreferences);
  81. }
  82. if (TextUtils.isEmpty(MStop.getText().toString())) {
  83. setPreferences("Stop",DEFULT_PRES);
  84. } else {

  85. String mPreferences = MStop.getText().toString();
  86. Log.v("4",mPreferences);
  87. setPreferences("Stop",mPreferences);
  88. }

  89. }
  90. private void setPreferences(String Key,String mPreferences){
  91. // set preference
  92. SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
  93. SharedPreferences.Editor editor = settings.edit();
  94. editor.putString(Key, mPreferences);
  95. editor.commit();
  96. }
  97. private void onShow() {
  98. // TODO Auto-generated method stub

  99. SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
  100. String mPreferences = settings.getString("Up", DEFULT_PRES);
  101. //Toast.makeText(Config.this,String.valueOf(mPreferences),Toast.LENGTH_SHORT).show();
  102. MUp.setText(mPreferences);

  103. mPreferences = settings.getString("Down", DEFULT_PRES);
  104. // Toast.makeText(Config.this,String.valueOf(mPreferences),Toast.LENGTH_SHORT).show();
  105. MDown.setText(mPreferences);

  106. mPreferences = settings.getString("Left", DEFULT_PRES);
  107. MLeft.setText(mPreferences);

  108. mPreferences = settings.getString("Right", DEFULT_PRES);
  109. MRight.setText(mPreferences);

  110. mPreferences = settings.getString("Stop", DEFULT_PRES);
  111. MStop.setText(mPreferences);

  112. }

  113. }
复制代码
DeviceListActivity.java


  1. package com.BluetoothCar.liuviking;

  2. import java.util.Set;

  3. import android.app.Activity;
  4. import android.bluetooth.BluetoothAdapter;
  5. import android.bluetooth.BluetoothDevice;
  6. import android.content.BroadcastReceiver;
  7. import android.content.Context;
  8. import android.content.Intent;
  9. import android.content.IntentFilter;
  10. import android.os.Bundle;
  11. import android.util.Log;
  12. import android.view.View;
  13. import android.view.Window;
  14. import android.view.View.OnClickListener;
  15. import android.widget.AdapterView;
  16. import android.widget.ArrayAdapter;
  17. import android.widget.Button;
  18. import android.widget.ListView;
  19. import android.widget.TextView;
  20. import android.widget.AdapterView.OnItemClickListener;

  21. /**
  22. * 此活动将作为一个对话框出现。 它列出了配对的所有设备和
  23. * 在区域中的后发现中检测到的设备。 当选择一个设备
  24. * 通过在的用户设备的 MAC 地址发送回父
  25. * Activity in the result Intent.。
  26. */
  27. public class DeviceListActivity extends Activity {
  28. // Debugging
  29. private static final String TAG = "DeviceListActivity";
  30. private static final boolean D = true;

  31. // Return Intent extra
  32. public static String EXTRA_DEVICE_ADDRESS = "device_address";

  33. // Member fields
  34. private BluetoothAdapter mBtAdapter;
  35. private ArrayAdapter<String> mPairedDevicesArrayAdapter;
  36. private ArrayAdapter<String> mNewDevicesArrayAdapter;

  37. @Override
  38. protected void onCreate(Bundle savedInstanceState) {
  39. super.onCreate(savedInstanceState);

  40. // Setup the window
  41. requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
  42. setContentView(R.layout.device_list);

  43. // Set result CANCELED incase the user backs out
  44. setResult(Activity.RESULT_CANCELED);

  45. // Initialize the button to perform device discovery
  46. Button scanButton = (Button) findViewById(R.id.button_scan);
  47. scanButton.setOnClickListener(new OnClickListener() {
  48. public void onClick(View v) {
  49. doDiscovery();
  50. v.setVisibility(View.GONE);
  51. }
  52. });

  53. // 一个Adapter是已配对的,一个是未配对的
  54. mPairedDevicesArrayAdapter = new ArrayAdapter<String>(this, R.layout.device_name);
  55. mNewDevicesArrayAdapter = new ArrayAdapter<String>(this, R.layout.device_name);

  56. // 把已配对设备放到ListView
  57. ListView pairedListView = (ListView) findViewById(R.id.paired_devices);
  58. pairedListView.setAdapter(mPairedDevicesArrayAdapter);
  59. pairedListView.setOnItemClickListener(mDeviceClickListener);

  60. //把新发现的设备放到 ListView
  61. ListView newDevicesListView = (ListView) findViewById(R.id.new_devices);
  62. newDevicesListView.setAdapter(mNewDevicesArrayAdapter);
  63. newDevicesListView.setOnItemClickListener(mDeviceClickListener);

  64. // Register for broadcasts when a device is discovered
  65. IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
  66. this.registerReceiver(mReceiver, filter);

  67. // Register for broadcasts when discovery has finished
  68. filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
  69. this.registerReceiver(mReceiver, filter);

  70. // Get the local Bluetooth adapter
  71. mBtAdapter = BluetoothAdapter.getDefaultAdapter();

  72. // Get a set of currently paired devices
  73. Set<BluetoothDevice> pairedDevices = mBtAdapter.getBondedDevices();

  74. // If there are paired devices, add each one to the ArrayAdapter
  75. if (pairedDevices.size() > 0) {
  76. findViewById(R.id.title_paired_devices).setVisibility(View.VISIBLE);
  77. for (BluetoothDevice device : pairedDevices) {
  78. mPairedDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());
  79. }
  80. } else {
  81. String noDevices = getResources().getText(R.string.none_paired).toString();
  82. mPairedDevicesArrayAdapter.add(noDevices);
  83. }
  84. }

  85. @Override
  86. protected void onDestroy() {
  87. super.onDestroy();

  88. // Make sure we're not doing discovery anymore
  89. if (mBtAdapter != null) {
  90. mBtAdapter.cancelDiscovery();
  91. }

  92. // Unregister broadcast listeners
  93. this.unregisterReceiver(mReceiver);
  94. }

  95. /**
  96. * Start device discover with the BluetoothAdapter
  97. */
  98. private void doDiscovery() {
  99. if (D) Log.d(TAG, "doDiscovery()");

  100. // Indicate scanning in the title
  101. setProgressBarIndeterminateVisibility(true);
  102. setTitle(R.string.scanning);

  103. // Turn on sub-title for new devices
  104. findViewById(R.id.title_new_devices).setVisibility(View.VISIBLE);

  105. // If we're already discovering, stop it
  106. if (mBtAdapter.isDiscovering()) {
  107. mBtAdapter.cancelDiscovery();
  108. }

  109. // Request discover from BluetoothAdapter
  110. mBtAdapter.startDiscovery();
  111. }

  112. // The on-click listener for all devices in the ListViews
  113. private OnItemClickListener mDeviceClickListener = new OnItemClickListener() {
  114. public void onItemClick(AdapterView<?> av, View v, int arg2, long arg3) {
  115. // 取消搜索,准备选择设备进行连接
  116. mBtAdapter.cancelDiscovery();

  117. // 获取设备的MAC地址
  118. String info = ((TextView) v).getText().toString();
  119. String address = info.substring(info.length() - 17);

  120. // 把MAC address用Intent回传到主Activity
  121. Intent intent = new Intent();
  122. intent.putExtra(EXTRA_DEVICE_ADDRESS, address);

  123. // 结束当前Activity并回传MAC
  124. setResult(Activity.RESULT_OK, intent);
  125. finish();
  126. }
  127. };

  128. //BroadcastReceiver监听设备,当设备发现后,重新设置TITLE
  129. private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
  130. @Override
  131. public void onReceive(Context context, Intent intent) {
  132. String action = intent.getAction();

  133. // When discovery finds a device
  134. if (BluetoothDevice.ACTION_FOUND.equals(action)) {
  135. // Get the BluetoothDevice object from the Intent
  136. BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
  137. // If it's already paired, skip it, because it's been listed already
  138. if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
  139. mNewDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());
  140. }
  141. // When discovery is finished, change the Activity title
  142. } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
  143. setProgressBarIndeterminateVisibility(false);
  144. setTitle(R.string.select_device);
  145. if (mNewDevicesArrayAdapter.getCount() == 0) {
  146. String noDevices = getResources().getText(R.string.none_found).toString();
  147. mNewDevicesArrayAdapter.add(noDevices);
  148. }
  149. }
  150. }
  151. };

  152. }
复制代码

XML文件
main1.xml
  1. <?xml version="1.0" encoding="utf-8"?>

  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:orientation="vertical"
  4. android:layout_width="fill_parent"
  5. android:layout_height="fill_parent"
  6. android:background="@drawable/background"
  7. >

  8. <RelativeLayout
  9. android:layout_width="fill_parent"
  10. android:layout_height="wrap_content"
  11. android:layout_weight="1" >
  12. <ListView android:id="@+id/in"
  13. android:layout_width="fill_parent"
  14. android:layout_height="fill_parent"
  15. android:stackFromBottom="true"
  16. android:transcriptMode="alwaysScroll"
  17. android:layout_weight="1"
  18. />
  19. <TextView android:layout_width="wrap_content"
  20. android:id="@+id/textView1"
  21. android:layout_height="wrap_content"
  22. android:layout_centerHorizontal="true"
  23. android:textSize="5pt"
  24. android:text="蓝牙版智能小车控制端 By liuviking"
  25. >
  26. </TextView>

  27. <TextView android:layout_width="wrap_content"
  28. android:id="@+id/textView2"
  29. android:layout_height="wrap_content"
  30. android:layout_centerHorizontal="true"
  31. android:textSize="6pt"
  32. android:text="机器人创意工作室www.wifi-robots.com"
  33. android:layout_below="@+id/textView1"
  34. >
  35. </TextView>

  36. <ImageButton
  37. android:layout_marginTop="50dip"
  38. android:layout_centerHorizontal="true"
  39. android:id="@+id/Forward"
  40. android:layout_width="35pt"
  41. android:layout_height="40pt"
  42. android:scaleType="fitXY"
  43. android:background="#00000000"
  44. android:src="@drawable/forward" >
  45. </ImageButton>

  46. <ImageButton
  47. android:layout_below="@+id/Forward"
  48. android:layout_toLeftOf="@+id/Stop"
  49. android:id="@+id/Left"
  50. android:layout_width="40pt"
  51. android:layout_height="35pt"
  52. android:background="#00000000"
  53. android:scaleType="fitXY"
  54. android:src="@drawable/left" >
  55. </ImageButton>


  56. <ImageButton
  57. android:layout_below="@+id/Forward"
  58. android:layout_centerHorizontal="true"
  59. android:id="@+id/Stop"
  60. android:layout_width="35pt"
  61. android:layout_height="35pt"
  62. android:background="#00000000"
  63. android:scaleType="fitXY"
  64. android:src="@drawable/stop" >
  65. </ImageButton>


  66. <ImageButton
  67. android:layout_below="@+id/Forward"
  68. android:layout_toRightOf="@+id/Stop"
  69. android:id="@+id/Right"
  70. android:layout_width="40pt"
  71. android:layout_height="35pt"
  72. android:background="#00000000"
  73. android:scaleType="fitXY"
  74. android:src="@drawable/right" >
  75. </ImageButton>

  76. <ImageButton
  77. android:layout_below="@+id/Stop"
  78. android:layout_centerHorizontal="true"
  79. android:id="@+id/Back"
  80. android:layout_width="35pt"
  81. android:layout_height="40pt"
  82. android:background="#00000000"
  83. android:scaleType="fitXY"
  84. android:src="@drawable/back" >
  85. </ImageButton>

  86. </RelativeLayout>
  87. </LinearLayout>
复制代码

message.xml
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <TextView xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="fill_parent"
  4. android:layout_height="wrap_content"
  5. android:textSize="18sp"
  6. android:padding="5dp"
  7. />
复制代码

device_name.xml
  1. <?xml version="1.0" encoding="utf-8"?>

  2. <TextView xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="fill_parent"
  4. android:layout_height="wrap_content"
  5. android:textSize="18sp"
  6. android:padding="5dp"
  7. />
复制代码

device_list.xml
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:orientation="vertical"
  4. android:layout_width="fill_parent"
  5. android:layout_height="fill_parent"
  6. >
  7. <TextView android:id="@+id/title_paired_devices"
  8. android:layout_width="fill_parent"
  9. android:layout_height="wrap_content"
  10. android:text="@string/title_paired_devices"
  11. android:visibility="gone"
  12. android:background="#666"
  13. android:textColor="#fff"
  14. android:paddingLeft="5dp"
  15. />
  16. <ListView android:id="@+id/paired_devices"
  17. android:layout_width="fill_parent"
  18. android:layout_height="wrap_content"
  19. android:stackFromBottom="true"
  20. android:layout_weight="1"
  21. />
  22. <TextView android:id="@+id/title_new_devices"
  23. android:layout_width="fill_parent"
  24. android:layout_height="wrap_content"
  25. android:text="@string/title_other_devices"
  26. android:visibility="gone"
  27. android:background="#666"
  28. android:textColor="#fff"
  29. android:paddingLeft="5dp"
  30. />
  31. <ListView android:id="@+id/new_devices"
  32. android:layout_width="fill_parent"
  33. android:layout_height="wrap_content"
  34. android:stackFromBottom="true"
  35. android:layout_weight="2"
  36. />
  37. <Button android:id="@+id/button_scan"
  38. android:layout_width="fill_parent"
  39. android:layout_height="wrap_content"
  40. android:text="@string/button_scan"
  41. />
  42. </LinearLayout>
复制代码

custom_title.xml
  1. <?xml version="1.0" encoding="utf-8"?>

  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="fill_parent"
  4. android:layout_height="fill_parent"
  5. android:gravity="center_vertical"
  6. >
  7. <TextView android:id="@+id/title_left_text"
  8. android:layout_alignParentLeft="true"
  9. android:ellipsize="end"
  10. android:singleLine="true"
  11. style="?android:attr/windowTitleStyle"
  12. android:layout_width="wrap_content"
  13. android:layout_height="fill_parent"
  14. android:layout_weight="1"
  15. />
  16. <TextView android:id="@+id/title_right_text"
  17. android:layout_alignParentRight="true"
  18. android:ellipsize="end"
  19. android:singleLine="true"
  20. android:layout_width="wrap_content"
  21. android:layout_height="fill_parent"
  22. android:textColor="#fff"
  23. android:layout_weight="1"
  24. />
  25. </RelativeLayout>
复制代码

configforcontrol.xml

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout
  3. xmlns:android="http://schemas.android.com/apk/res/android"
  4. android:layout_width="match_parent"
  5. android:layout_height="match_parent">
  6. <RelativeLayout
  7. android:layout_width="fill_parent"
  8. android:layout_height="wrap_content"
  9. android:layout_weight="1" >
  10. <TextView android:text="上" android:id="@+id/textViewup" android:layout_width="80px" android:layout_height="wrap_content" ></TextView>
  11. <EditText android:text="" android:id="@+id/editUp" android:layout_width="80px" android:layout_height="wrap_content" android:layout_below="@+id/textViewup"></EditText>
  12. <TextView android:text="下" android:id="@+id/textViewdown" android:layout_width="80px" android:layout_height="wrap_content" android:layout_toRightOf="@+id/textViewup"></TextView>
  13. <EditText android:text="" android:id="@+id/editDown" android:layout_width="80px" android:layout_height="wrap_content" android:layout_toRightOf="@+id/editUp" android:layout_below="@+id/textViewdown"></EditText>

  14. <TextView android:text="左" android:id="@+id/textViewleft" android:layout_width="80px" android:layout_height="wrap_content" android:layout_below="@+id/editUp" ></TextView>
  15. <EditText android:text="" android:id="@+id/editLeft" android:layout_width="80px" android:layout_height="wrap_content" android:layout_below="@+id/textViewleft"></EditText>

  16. <TextView android:text="右" android:id="@+id/textViewright" android:layout_width="80px" android:layout_height="wrap_content" android:layout_below="@+id/editDown" android:layout_toRightOf="@+id/textViewleft"></TextView>
  17. <EditText android:text="" android:id="@+id/editRight" android:layout_width="80px" android:layout_height="wrap_content" android:layout_below="@+id/textViewright" android:layout_toRightOf="@+id/editLeft"></EditText>

  18. <TextView android:text="停" android:id="@+id/textViewstop" android:layout_width="80px" android:layout_height="wrap_content" android:layout_below="@+id/editRight"></TextView>
  19. <EditText android:text="" android:id="@+id/editStop" android:layout_width="80px" android:layout_height="wrap_content" android:layout_below="@+id/textViewstop"></EditText>

  20. <Button android:text="保存" android:id="@+id/btnControlOK" android:layout_width="40pt" android:layout_height="wrap_content" android:layout_below="@+id/editStop"></Button>
  21. <Button android:text="取消" android:id="@+id/btnControlCancel" android:layout_width="40pt" android:layout_height="wrap_content" android:layout_toRightOf="@+id/btnControlOK" android:layout_below="@+id/editStop"></Button>
  22. </RelativeLayout>
  23. </LinearLayout>
复制代码

menu文件夹中,新建菜单xml文件
option_menu.xml
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <menu xmlns:android="http://schemas.android.com/apk/res/android">
  3. <item android:id="@+id/config"
  4. android:icon="@android:drawable/ic_menu_preferences"
  5. android:title="@string/config" />
  6. <item android:id="@+id/scan"
  7. android:icon="@android:drawable/ic_menu_search"
  8. android:title="@string/connect" />
  9. <item android:id="@+id/discoverable"
  10. android:icon="@android:drawable/ic_menu_mylocation"
  11. android:title="@string/discoverable" />
  12. </menu>
复制代码

values文件夹中,新建字符资源文件string.xml
string.xml
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <resources>
  3. <string name="app_name">智能小车控制蓝牙版V2.0 BY liuviking</string>

  4. <!-- BluetoothChat -->
  5. <string name="send">发送</string>
  6. <string name="not_connected">您没有连接到设备,请按菜单键进入设备搜索并连接设备。</string>
  7. <string name="bt_not_enabled_leaving">蓝牙未被启用.程序退出.</string>
  8. <string name="title_connecting">正在连接...</string>
  9. <string name="title_connected_to">已连接: </string>
  10. <string name="title_not_connected">没有连接</string>

  11. <!-- DeviceListActivity -->
  12. <string name="scanning">扫描设备中...</string>
  13. <string name="select_device">选择一个设备连接</string>
  14. <string name="none_paired">没有设备已配对</string>
  15. <string name="none_found">没有找到设备</string>
  16. <string name="title_paired_devices">已配对设备</string>
  17. <string name="title_other_devices">其他可用的设备</string>
  18. <string name="button_scan">扫描设备</string>

  19. <!-- Options Menu -->
  20. <string name="connect">连接设备</string>
  21. <string name="discoverable">使可发现</string>
  22. <string name="config">指令设置</string>
  23. </resources>
复制代码
程序用到的图片资源合集:
drawable.rar (120.72 KB, 下载次数: 713)

评分

参与人数 3金钱 +7 收起 理由
???? + 3
chenlingzhou + 1 赞一个!
赤龙之吼 + 3 很给力!

查看全部评分

回复

使用道具 举报

发表于 2012-7-29 12:54:47 | 显示全部楼层
什么时候发wifi版的啊???
急切需求中
回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-7-29 13:00:07 | 显示全部楼层
刘亚南 发表于 2012-7-29 12:54
什么时候发wifi版的啊???
急切需求中

安卓wifi小车源工程 http://www.wifi-robots.com/thread-1122-1-1.html
回复 支持 反对

使用道具 举报

发表于 2012-7-29 13:01:08 | 显示全部楼层
好贴
回复 支持 反对

使用道具 举报

发表于 2012-7-29 22:31:16 | 显示全部楼层
liuviking 发表于 2012-7-29 13:00
安卓wifi小车源工程 http://www.wifi-robots.com/thread-1122-1-1.html

他的这个我安装到手机上不能控制啊,你发布的这个能控制http://www.wifi-robots.com/thread-1180-1-1.html
回复 支持 反对

使用道具 举报

发表于 2012-7-29 22:32:02 | 显示全部楼层
回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-7-29 22:43:19 | 显示全部楼层
刘亚南 发表于 2012-7-29 22:31
他的这个我安装到手机上不能控制啊,你发布的这个能控制http://www.wifi-robots.com/thread-1180-1-1.htm ...

他的是单字符版,我的是数据包格式版,你只需把单字符修改成byte数据包即可。
回复 支持 反对

使用道具 举报

发表于 2012-7-30 10:46:30 | 显示全部楼层
private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb");
这一句后面的00001101-0000-1000-8000-00805f9b34fb是从哪里得到的,不知道这个有什么作用
回复 支持 反对

使用道具 举报

发表于 2012-7-30 13:53:21 | 显示全部楼层
冒个泡,老久没上了
回复 支持 反对

使用道具 举报

发表于 2012-7-30 13:58:15 | 显示全部楼层
liuviking 发表于 2012-7-29 22:43
他的是单字符版,我的是数据包格式版,你只需把单字符修改成byte数据包即可。

怎么改啊  举个例子呗   谢谢了啊
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

新品特惠推荐上一条 /2 下一条

QQ|QQ技术咨询1|QQ技术咨询2|商务合作微信1:xiaorgeek001|商务合作微信2:XiaoRGEEK|诚聘英才|Archiver|手机版|小R科技-WIFI机器人网·机器人创意工作室 ( 粤ICP备15000788号-6 )

GMT+8, 2024-11-22 19:32 , Processed in 1.128986 second(s), 26 queries .

Powered by XiaoR GEEK X3.4

© 2014-2021 XiaoR GEEK

快速回复 返回顶部 返回列表