└── BluetoothChatMulti
├── .classpath
├── .project
├── AndroidManifest.xml
├── bin
├── BluetoothChatMulti.apk
├── classes.dex
├── com
│ └── example
│ │ └── android
│ │ ├── BluetoothChat
│ │ ├── R$attr.class
│ │ ├── R$drawable.class
│ │ ├── R$id.class
│ │ ├── R$layout.class
│ │ ├── R$menu.class
│ │ ├── R$string.class
│ │ └── R.class
│ │ └── BluetoothChatMulti
│ │ ├── BluetoothChat$1.class
│ │ ├── BluetoothChat$2.class
│ │ ├── BluetoothChat$3.class
│ │ ├── BluetoothChat.class
│ │ ├── BluetoothChatService$AcceptThread.class
│ │ ├── BluetoothChatService$ConnectThread.class
│ │ ├── BluetoothChatService$ConnectedThread.class
│ │ ├── BluetoothChatService.class
│ │ ├── DeviceListActivity$1.class
│ │ ├── DeviceListActivity$2.class
│ │ ├── DeviceListActivity$3.class
│ │ ├── DeviceListActivity.class
│ │ ├── R$attr.class
│ │ ├── R$drawable.class
│ │ ├── R$id.class
│ │ ├── R$layout.class
│ │ ├── R$menu.class
│ │ ├── R$string.class
│ │ └── R.class
└── resources.ap_
├── default.properties
├── gen
└── com
│ └── example
│ └── android
│ ├── BluetoothChat
│ └── R.java
│ └── BluetoothChatMulti
│ └── R.java
├── res
├── drawable-hdpi
│ └── app_icon.png
├── drawable
│ └── app_icon.png
├── layout
│ ├── custom_title.xml
│ ├── device_list.xml
│ ├── device_name.xml
│ ├── main.xml
│ └── message.xml
├── menu
│ └── option_menu.xml
└── values
│ └── strings.xml
└── src
└── com
└── example
└── android
└── BluetoothChatMulti
├── BluetoothChat.java
├── BluetoothChatService.java
└── DeviceListActivity.java
/BluetoothChatMulti/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/BluetoothChatMulti/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | BluetoothChatMulti
4 |
5 |
6 |
7 |
8 |
9 | com.android.ide.eclipse.adt.ResourceManagerBuilder
10 |
11 |
12 |
13 |
14 | com.android.ide.eclipse.adt.PreCompilerBuilder
15 |
16 |
17 |
18 |
19 | org.eclipse.jdt.core.javabuilder
20 |
21 |
22 |
23 |
24 | com.android.ide.eclipse.adt.ApkBuilder
25 |
26 |
27 |
28 |
29 |
30 | com.android.ide.eclipse.adt.AndroidNature
31 | org.eclipse.jdt.core.javanature
32 |
33 |
34 |
--------------------------------------------------------------------------------
/BluetoothChatMulti/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
20 |
21 |
22 |
23 |
24 |
26 |
29 |
30 |
31 |
32 |
33 |
34 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/BluetoothChatMulti/bin/BluetoothChatMulti.apk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/polyclef/BluetoothChatMulti/f50d9895b6a685f41019dd92067691dbefeffa9a/BluetoothChatMulti/bin/BluetoothChatMulti.apk
--------------------------------------------------------------------------------
/BluetoothChatMulti/bin/classes.dex:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/polyclef/BluetoothChatMulti/f50d9895b6a685f41019dd92067691dbefeffa9a/BluetoothChatMulti/bin/classes.dex
--------------------------------------------------------------------------------
/BluetoothChatMulti/bin/com/example/android/BluetoothChat/R$attr.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/polyclef/BluetoothChatMulti/f50d9895b6a685f41019dd92067691dbefeffa9a/BluetoothChatMulti/bin/com/example/android/BluetoothChat/R$attr.class
--------------------------------------------------------------------------------
/BluetoothChatMulti/bin/com/example/android/BluetoothChat/R$drawable.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/polyclef/BluetoothChatMulti/f50d9895b6a685f41019dd92067691dbefeffa9a/BluetoothChatMulti/bin/com/example/android/BluetoothChat/R$drawable.class
--------------------------------------------------------------------------------
/BluetoothChatMulti/bin/com/example/android/BluetoothChat/R$id.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/polyclef/BluetoothChatMulti/f50d9895b6a685f41019dd92067691dbefeffa9a/BluetoothChatMulti/bin/com/example/android/BluetoothChat/R$id.class
--------------------------------------------------------------------------------
/BluetoothChatMulti/bin/com/example/android/BluetoothChat/R$layout.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/polyclef/BluetoothChatMulti/f50d9895b6a685f41019dd92067691dbefeffa9a/BluetoothChatMulti/bin/com/example/android/BluetoothChat/R$layout.class
--------------------------------------------------------------------------------
/BluetoothChatMulti/bin/com/example/android/BluetoothChat/R$menu.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/polyclef/BluetoothChatMulti/f50d9895b6a685f41019dd92067691dbefeffa9a/BluetoothChatMulti/bin/com/example/android/BluetoothChat/R$menu.class
--------------------------------------------------------------------------------
/BluetoothChatMulti/bin/com/example/android/BluetoothChat/R$string.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/polyclef/BluetoothChatMulti/f50d9895b6a685f41019dd92067691dbefeffa9a/BluetoothChatMulti/bin/com/example/android/BluetoothChat/R$string.class
--------------------------------------------------------------------------------
/BluetoothChatMulti/bin/com/example/android/BluetoothChat/R.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/polyclef/BluetoothChatMulti/f50d9895b6a685f41019dd92067691dbefeffa9a/BluetoothChatMulti/bin/com/example/android/BluetoothChat/R.class
--------------------------------------------------------------------------------
/BluetoothChatMulti/bin/com/example/android/BluetoothChatMulti/BluetoothChat$1.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/polyclef/BluetoothChatMulti/f50d9895b6a685f41019dd92067691dbefeffa9a/BluetoothChatMulti/bin/com/example/android/BluetoothChatMulti/BluetoothChat$1.class
--------------------------------------------------------------------------------
/BluetoothChatMulti/bin/com/example/android/BluetoothChatMulti/BluetoothChat$2.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/polyclef/BluetoothChatMulti/f50d9895b6a685f41019dd92067691dbefeffa9a/BluetoothChatMulti/bin/com/example/android/BluetoothChatMulti/BluetoothChat$2.class
--------------------------------------------------------------------------------
/BluetoothChatMulti/bin/com/example/android/BluetoothChatMulti/BluetoothChat$3.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/polyclef/BluetoothChatMulti/f50d9895b6a685f41019dd92067691dbefeffa9a/BluetoothChatMulti/bin/com/example/android/BluetoothChatMulti/BluetoothChat$3.class
--------------------------------------------------------------------------------
/BluetoothChatMulti/bin/com/example/android/BluetoothChatMulti/BluetoothChat.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/polyclef/BluetoothChatMulti/f50d9895b6a685f41019dd92067691dbefeffa9a/BluetoothChatMulti/bin/com/example/android/BluetoothChatMulti/BluetoothChat.class
--------------------------------------------------------------------------------
/BluetoothChatMulti/bin/com/example/android/BluetoothChatMulti/BluetoothChatService$AcceptThread.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/polyclef/BluetoothChatMulti/f50d9895b6a685f41019dd92067691dbefeffa9a/BluetoothChatMulti/bin/com/example/android/BluetoothChatMulti/BluetoothChatService$AcceptThread.class
--------------------------------------------------------------------------------
/BluetoothChatMulti/bin/com/example/android/BluetoothChatMulti/BluetoothChatService$ConnectThread.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/polyclef/BluetoothChatMulti/f50d9895b6a685f41019dd92067691dbefeffa9a/BluetoothChatMulti/bin/com/example/android/BluetoothChatMulti/BluetoothChatService$ConnectThread.class
--------------------------------------------------------------------------------
/BluetoothChatMulti/bin/com/example/android/BluetoothChatMulti/BluetoothChatService$ConnectedThread.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/polyclef/BluetoothChatMulti/f50d9895b6a685f41019dd92067691dbefeffa9a/BluetoothChatMulti/bin/com/example/android/BluetoothChatMulti/BluetoothChatService$ConnectedThread.class
--------------------------------------------------------------------------------
/BluetoothChatMulti/bin/com/example/android/BluetoothChatMulti/BluetoothChatService.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/polyclef/BluetoothChatMulti/f50d9895b6a685f41019dd92067691dbefeffa9a/BluetoothChatMulti/bin/com/example/android/BluetoothChatMulti/BluetoothChatService.class
--------------------------------------------------------------------------------
/BluetoothChatMulti/bin/com/example/android/BluetoothChatMulti/DeviceListActivity$1.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/polyclef/BluetoothChatMulti/f50d9895b6a685f41019dd92067691dbefeffa9a/BluetoothChatMulti/bin/com/example/android/BluetoothChatMulti/DeviceListActivity$1.class
--------------------------------------------------------------------------------
/BluetoothChatMulti/bin/com/example/android/BluetoothChatMulti/DeviceListActivity$2.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/polyclef/BluetoothChatMulti/f50d9895b6a685f41019dd92067691dbefeffa9a/BluetoothChatMulti/bin/com/example/android/BluetoothChatMulti/DeviceListActivity$2.class
--------------------------------------------------------------------------------
/BluetoothChatMulti/bin/com/example/android/BluetoothChatMulti/DeviceListActivity$3.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/polyclef/BluetoothChatMulti/f50d9895b6a685f41019dd92067691dbefeffa9a/BluetoothChatMulti/bin/com/example/android/BluetoothChatMulti/DeviceListActivity$3.class
--------------------------------------------------------------------------------
/BluetoothChatMulti/bin/com/example/android/BluetoothChatMulti/DeviceListActivity.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/polyclef/BluetoothChatMulti/f50d9895b6a685f41019dd92067691dbefeffa9a/BluetoothChatMulti/bin/com/example/android/BluetoothChatMulti/DeviceListActivity.class
--------------------------------------------------------------------------------
/BluetoothChatMulti/bin/com/example/android/BluetoothChatMulti/R$attr.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/polyclef/BluetoothChatMulti/f50d9895b6a685f41019dd92067691dbefeffa9a/BluetoothChatMulti/bin/com/example/android/BluetoothChatMulti/R$attr.class
--------------------------------------------------------------------------------
/BluetoothChatMulti/bin/com/example/android/BluetoothChatMulti/R$drawable.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/polyclef/BluetoothChatMulti/f50d9895b6a685f41019dd92067691dbefeffa9a/BluetoothChatMulti/bin/com/example/android/BluetoothChatMulti/R$drawable.class
--------------------------------------------------------------------------------
/BluetoothChatMulti/bin/com/example/android/BluetoothChatMulti/R$id.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/polyclef/BluetoothChatMulti/f50d9895b6a685f41019dd92067691dbefeffa9a/BluetoothChatMulti/bin/com/example/android/BluetoothChatMulti/R$id.class
--------------------------------------------------------------------------------
/BluetoothChatMulti/bin/com/example/android/BluetoothChatMulti/R$layout.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/polyclef/BluetoothChatMulti/f50d9895b6a685f41019dd92067691dbefeffa9a/BluetoothChatMulti/bin/com/example/android/BluetoothChatMulti/R$layout.class
--------------------------------------------------------------------------------
/BluetoothChatMulti/bin/com/example/android/BluetoothChatMulti/R$menu.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/polyclef/BluetoothChatMulti/f50d9895b6a685f41019dd92067691dbefeffa9a/BluetoothChatMulti/bin/com/example/android/BluetoothChatMulti/R$menu.class
--------------------------------------------------------------------------------
/BluetoothChatMulti/bin/com/example/android/BluetoothChatMulti/R$string.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/polyclef/BluetoothChatMulti/f50d9895b6a685f41019dd92067691dbefeffa9a/BluetoothChatMulti/bin/com/example/android/BluetoothChatMulti/R$string.class
--------------------------------------------------------------------------------
/BluetoothChatMulti/bin/com/example/android/BluetoothChatMulti/R.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/polyclef/BluetoothChatMulti/f50d9895b6a685f41019dd92067691dbefeffa9a/BluetoothChatMulti/bin/com/example/android/BluetoothChatMulti/R.class
--------------------------------------------------------------------------------
/BluetoothChatMulti/bin/resources.ap_:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/polyclef/BluetoothChatMulti/f50d9895b6a685f41019dd92067691dbefeffa9a/BluetoothChatMulti/bin/resources.ap_
--------------------------------------------------------------------------------
/BluetoothChatMulti/default.properties:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by Android Tools.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must be checked in Version Control Systems.
5 | #
6 | # To customize properties used by the Ant build system use,
7 | # "build.properties", and override values to adapt the script to your
8 | # project structure.
9 |
10 | # Project target.
11 | target=android-7
12 |
--------------------------------------------------------------------------------
/BluetoothChatMulti/gen/com/example/android/BluetoothChat/R.java:
--------------------------------------------------------------------------------
1 | /* AUTO-GENERATED FILE. DO NOT MODIFY.
2 | *
3 | * This class was automatically generated by the
4 | * aapt tool from the resource data it found. It
5 | * should not be modified by hand.
6 | */
7 |
8 | package com.example.android.BluetoothChat;
9 |
10 | public final class R {
11 | public static final class attr {
12 | }
13 | public static final class drawable {
14 | public static final int app_icon=0x7f020000;
15 | }
16 | public static final class id {
17 | public static final int button_scan=0x7f060006;
18 | public static final int button_send=0x7f060009;
19 | public static final int discoverable=0x7f06000b;
20 | public static final int edit_text_out=0x7f060008;
21 | public static final int in=0x7f060007;
22 | public static final int new_devices=0x7f060005;
23 | public static final int paired_devices=0x7f060003;
24 | public static final int scan=0x7f06000a;
25 | public static final int title_left_text=0x7f060000;
26 | public static final int title_new_devices=0x7f060004;
27 | public static final int title_paired_devices=0x7f060002;
28 | public static final int title_right_text=0x7f060001;
29 | }
30 | public static final class layout {
31 | public static final int custom_title=0x7f030000;
32 | public static final int device_list=0x7f030001;
33 | public static final int device_name=0x7f030002;
34 | public static final int main=0x7f030003;
35 | public static final int message=0x7f030004;
36 | }
37 | public static final class menu {
38 | public static final int option_menu=0x7f050000;
39 | }
40 | public static final class string {
41 | public static final int app_name=0x7f040000;
42 | public static final int bt_not_enabled_leaving=0x7f040003;
43 | public static final int button_scan=0x7f04000d;
44 | /** Options Menu
45 | */
46 | public static final int connect=0x7f04000e;
47 | public static final int discoverable=0x7f04000f;
48 | public static final int none_found=0x7f04000a;
49 | public static final int none_paired=0x7f040009;
50 | public static final int not_connected=0x7f040002;
51 | /** DeviceListActivity
52 | */
53 | public static final int scanning=0x7f040007;
54 | public static final int select_device=0x7f040008;
55 | /** BluetoothChat
56 | */
57 | public static final int send=0x7f040001;
58 | public static final int title_connected_to=0x7f040005;
59 | public static final int title_connecting=0x7f040004;
60 | public static final int title_not_connected=0x7f040006;
61 | public static final int title_other_devices=0x7f04000c;
62 | public static final int title_paired_devices=0x7f04000b;
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/BluetoothChatMulti/gen/com/example/android/BluetoothChatMulti/R.java:
--------------------------------------------------------------------------------
1 | /* AUTO-GENERATED FILE. DO NOT MODIFY.
2 | *
3 | * This class was automatically generated by the
4 | * aapt tool from the resource data it found. It
5 | * should not be modified by hand.
6 | */
7 |
8 | package com.example.android.BluetoothChatMulti;
9 |
10 | public final class R {
11 | public static final class attr {
12 | }
13 | public static final class drawable {
14 | public static final int app_icon=0x7f020000;
15 | }
16 | public static final class id {
17 | public static final int button_scan=0x7f060006;
18 | public static final int button_send=0x7f060009;
19 | public static final int discoverable=0x7f06000b;
20 | public static final int edit_text_out=0x7f060008;
21 | public static final int in=0x7f060007;
22 | public static final int new_devices=0x7f060005;
23 | public static final int paired_devices=0x7f060003;
24 | public static final int scan=0x7f06000a;
25 | public static final int title_left_text=0x7f060000;
26 | public static final int title_new_devices=0x7f060004;
27 | public static final int title_paired_devices=0x7f060002;
28 | public static final int title_right_text=0x7f060001;
29 | }
30 | public static final class layout {
31 | public static final int custom_title=0x7f030000;
32 | public static final int device_list=0x7f030001;
33 | public static final int device_name=0x7f030002;
34 | public static final int main=0x7f030003;
35 | public static final int message=0x7f030004;
36 | }
37 | public static final class menu {
38 | public static final int option_menu=0x7f050000;
39 | }
40 | public static final class string {
41 | public static final int app_name=0x7f040000;
42 | public static final int bt_not_enabled_leaving=0x7f040003;
43 | public static final int button_scan=0x7f04000d;
44 | /** Options Menu
45 | */
46 | public static final int connect=0x7f04000e;
47 | public static final int discoverable=0x7f04000f;
48 | public static final int none_found=0x7f04000a;
49 | public static final int none_paired=0x7f040009;
50 | public static final int not_connected=0x7f040002;
51 | /** DeviceListActivity
52 | */
53 | public static final int scanning=0x7f040007;
54 | public static final int select_device=0x7f040008;
55 | /** BluetoothChat
56 | */
57 | public static final int send=0x7f040001;
58 | public static final int title_connected_to=0x7f040005;
59 | public static final int title_connecting=0x7f040004;
60 | public static final int title_not_connected=0x7f040006;
61 | public static final int title_other_devices=0x7f04000c;
62 | public static final int title_paired_devices=0x7f04000b;
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/BluetoothChatMulti/res/drawable-hdpi/app_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/polyclef/BluetoothChatMulti/f50d9895b6a685f41019dd92067691dbefeffa9a/BluetoothChatMulti/res/drawable-hdpi/app_icon.png
--------------------------------------------------------------------------------
/BluetoothChatMulti/res/drawable/app_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/polyclef/BluetoothChatMulti/f50d9895b6a685f41019dd92067691dbefeffa9a/BluetoothChatMulti/res/drawable/app_icon.png
--------------------------------------------------------------------------------
/BluetoothChatMulti/res/layout/custom_title.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
21 |
30 |
39 |
--------------------------------------------------------------------------------
/BluetoothChatMulti/res/layout/device_list.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
21 |
30 |
36 |
45 |
51 |
56 |
--------------------------------------------------------------------------------
/BluetoothChatMulti/res/layout/device_name.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
--------------------------------------------------------------------------------
/BluetoothChatMulti/res/layout/main.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
17 |
22 |
29 |
34 |
40 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/BluetoothChatMulti/res/layout/message.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
--------------------------------------------------------------------------------
/BluetoothChatMulti/res/menu/option_menu.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
24 |
--------------------------------------------------------------------------------
/BluetoothChatMulti/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
17 |
18 | Bluetooth Chat Multi
19 |
20 |
21 | Send
22 | You are not connected to a device
23 | Bluetooth was not enabled. Leaving Bluetooth Chat.
24 | connecting...
25 | connected:
26 | not connected
27 |
28 |
29 | scanning for devices...
30 | select a device to connect
31 | No devices have been paired
32 | No devices found
33 | Paired Devices
34 | Other Available Devices
35 | Scan for devices
36 |
37 |
38 | Connect a device
39 | Make discoverable
40 |
41 |
--------------------------------------------------------------------------------
/BluetoothChatMulti/src/com/example/android/BluetoothChatMulti/BluetoothChat.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2009 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.example.android.BluetoothChatMulti;
18 |
19 | import android.app.Activity;
20 | import android.bluetooth.BluetoothAdapter;
21 | import android.bluetooth.BluetoothDevice;
22 | import android.content.Intent;
23 | import android.os.Bundle;
24 | import android.os.Handler;
25 | import android.os.Message;
26 | import android.util.Log;
27 | import android.view.KeyEvent;
28 | import android.view.Menu;
29 | import android.view.MenuInflater;
30 | import android.view.MenuItem;
31 | import android.view.View;
32 | import android.view.Window;
33 | import android.view.View.OnClickListener;
34 | import android.view.inputmethod.EditorInfo;
35 | import android.widget.ArrayAdapter;
36 | import android.widget.Button;
37 | import android.widget.EditText;
38 | import android.widget.ListView;
39 | import android.widget.TextView;
40 | import android.widget.Toast;
41 |
42 | /**
43 | * This is the main Activity that displays the current chat session.
44 | */
45 | public class BluetoothChat extends Activity {
46 | // Debugging
47 | private static final String TAG = "BluetoothChat";
48 | private static final boolean D = true;
49 |
50 | // Message types sent from the BluetoothChatService Handler
51 | public static final int MESSAGE_STATE_CHANGE = 1;
52 | public static final int MESSAGE_READ = 2;
53 | public static final int MESSAGE_WRITE = 3;
54 | public static final int MESSAGE_DEVICE_NAME = 4;
55 | public static final int MESSAGE_TOAST = 5;
56 |
57 | // Key names received from the BluetoothChatService Handler
58 | public static final String DEVICE_NAME = "device_name";
59 | public static final String TOAST = "toast";
60 |
61 | // Intent request codes
62 | private static final int REQUEST_CONNECT_DEVICE = 1;
63 | private static final int REQUEST_ENABLE_BT = 2;
64 |
65 | // Layout Views
66 | private TextView mTitle;
67 | private ListView mConversationView;
68 | private EditText mOutEditText;
69 | private Button mSendButton;
70 |
71 | // Name of the connected device
72 | private String mConnectedDeviceName = null;
73 | // Array adapter for the conversation thread
74 | private ArrayAdapter mConversationArrayAdapter;
75 | // String buffer for outgoing messages
76 | private StringBuffer mOutStringBuffer;
77 | // Local Bluetooth adapter
78 | private BluetoothAdapter mBluetoothAdapter = null;
79 | // Member object for the chat services
80 | private BluetoothChatService mChatService = null;
81 |
82 |
83 | @Override
84 | public void onCreate(Bundle savedInstanceState) {
85 | super.onCreate(savedInstanceState);
86 | if(D) Log.e(TAG, "+++ ON CREATE +++");
87 |
88 | // Set up the window layout
89 | requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
90 | setContentView(R.layout.main);
91 | getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.custom_title);
92 |
93 | // Set up the custom title
94 | mTitle = (TextView) findViewById(R.id.title_left_text);
95 | mTitle.setText(R.string.app_name);
96 | mTitle = (TextView) findViewById(R.id.title_right_text);
97 |
98 | // Get local Bluetooth adapter
99 | mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
100 |
101 | // If the adapter is null, then Bluetooth is not supported
102 | if (mBluetoothAdapter == null) {
103 | Toast.makeText(this, "Bluetooth is not available", Toast.LENGTH_LONG).show();
104 | finish();
105 | return;
106 | }
107 | }
108 |
109 | @Override
110 | public void onStart() {
111 | super.onStart();
112 | if(D) Log.e(TAG, "++ ON START ++");
113 |
114 | // If BT is not on, request that it be enabled.
115 | // setupChat() will then be called during onActivityResult
116 | if (!mBluetoothAdapter.isEnabled()) {
117 | Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
118 | startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
119 | // Otherwise, setup the chat session
120 | } else {
121 | if (mChatService == null) setupChat();
122 | }
123 | }
124 |
125 | @Override
126 | public synchronized void onResume() {
127 | super.onResume();
128 | if(D) Log.e(TAG, "+ ON RESUME +");
129 |
130 | // Performing this check in onResume() covers the case in which BT was
131 | // not enabled during onStart(), so we were paused to enable it...
132 | // onResume() will be called when ACTION_REQUEST_ENABLE activity returns.
133 | if (mChatService != null) {
134 | // Only if the state is STATE_NONE, do we know that we haven't started already
135 | if (mChatService.getState() == BluetoothChatService.STATE_NONE) {
136 | // Start the Bluetooth chat services
137 | mChatService.start();
138 | }
139 | }
140 | }
141 |
142 | private void setupChat() {
143 | Log.d(TAG, "setupChat()");
144 |
145 | // Initialize the array adapter for the conversation thread
146 | mConversationArrayAdapter = new ArrayAdapter(this, R.layout.message);
147 | mConversationView = (ListView) findViewById(R.id.in);
148 | mConversationView.setAdapter(mConversationArrayAdapter);
149 |
150 | // Initialize the compose field with a listener for the return key
151 | mOutEditText = (EditText) findViewById(R.id.edit_text_out);
152 | mOutEditText.setOnEditorActionListener(mWriteListener);
153 |
154 | // Initialize the send button with a listener that for click events
155 | mSendButton = (Button) findViewById(R.id.button_send);
156 | mSendButton.setOnClickListener(new OnClickListener() {
157 | public void onClick(View v) {
158 | // Send a message using content of the edit text widget
159 | TextView view = (TextView) findViewById(R.id.edit_text_out);
160 | String message = view.getText().toString();
161 | sendMessage(message);
162 | }
163 | });
164 |
165 | // Initialize the BluetoothChatService to perform bluetooth connections
166 | mChatService = new BluetoothChatService(this, mHandler);
167 |
168 | // Initialize the buffer for outgoing messages
169 | mOutStringBuffer = new StringBuffer("");
170 | }
171 |
172 | @Override
173 | public synchronized void onPause() {
174 | super.onPause();
175 | if(D) Log.e(TAG, "- ON PAUSE -");
176 | }
177 |
178 | @Override
179 | public void onStop() {
180 | super.onStop();
181 | if(D) Log.e(TAG, "-- ON STOP --");
182 | }
183 |
184 | @Override
185 | public void onDestroy() {
186 | super.onDestroy();
187 | // Stop the Bluetooth chat services
188 | if (mChatService != null) mChatService.stop();
189 | if(D) Log.e(TAG, "--- ON DESTROY ---");
190 | }
191 |
192 | private void ensureDiscoverable() {
193 | if(D) Log.d(TAG, "ensure discoverable");
194 | if (mBluetoothAdapter.getScanMode() !=
195 | BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
196 | Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
197 | discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
198 | startActivity(discoverableIntent);
199 | }
200 | }
201 |
202 | /**
203 | * Sends a message.
204 | * @param message A string of text to send.
205 | */
206 | private void sendMessage(String message) {
207 | // Check that we're actually connected before trying anything
208 | if (mChatService.getState() != BluetoothChatService.STATE_CONNECTED) {
209 | Toast.makeText(this, R.string.not_connected, Toast.LENGTH_SHORT).show();
210 | return;
211 | }
212 |
213 | // Check that there's actually something to send
214 | if (message.length() > 0) {
215 | // Get the message bytes and tell the BluetoothChatService to write
216 | byte[] send = message.getBytes();
217 | mChatService.write(send);
218 |
219 | // Reset out string buffer to zero and clear the edit text field
220 | mOutStringBuffer.setLength(0);
221 | mOutEditText.setText(mOutStringBuffer);
222 | }
223 | }
224 |
225 | // The action listener for the EditText widget, to listen for the return key
226 | private TextView.OnEditorActionListener mWriteListener =
227 | new TextView.OnEditorActionListener() {
228 | public boolean onEditorAction(TextView view, int actionId, KeyEvent event) {
229 | // If the action is a key-up event on the return key, send the message
230 | if (actionId == EditorInfo.IME_NULL && event.getAction() == KeyEvent.ACTION_UP) {
231 | String message = view.getText().toString();
232 | sendMessage(message);
233 | }
234 | if(D) Log.i(TAG, "END onEditorAction");
235 | return true;
236 | }
237 | };
238 |
239 | // The Handler that gets information back from the BluetoothChatService
240 | private final Handler mHandler = new Handler() {
241 | @Override
242 | public void handleMessage(Message msg) {
243 | switch (msg.what) {
244 | case MESSAGE_STATE_CHANGE:
245 | if(D) Log.i(TAG, "MESSAGE_STATE_CHANGE: " + msg.arg1);
246 | switch (msg.arg1) {
247 | case BluetoothChatService.STATE_CONNECTED:
248 | mTitle.setText(R.string.title_connected_to);
249 | mTitle.append(mConnectedDeviceName);
250 | mConversationArrayAdapter.clear();
251 | break;
252 | case BluetoothChatService.STATE_CONNECTING:
253 | mTitle.setText(R.string.title_connecting);
254 | break;
255 | case BluetoothChatService.STATE_LISTEN:
256 | case BluetoothChatService.STATE_NONE:
257 | mTitle.setText(R.string.title_not_connected);
258 | break;
259 | }
260 | break;
261 | case MESSAGE_WRITE:
262 | byte[] writeBuf = (byte[]) msg.obj;
263 | // construct a string from the buffer
264 | String writeMessage = new String(writeBuf);
265 | mConversationArrayAdapter.add("Me: " + writeMessage);
266 | break;
267 | case MESSAGE_READ:
268 | byte[] readBuf = (byte[]) msg.obj;
269 | // construct a string from the valid bytes in the buffer
270 | String readMessage = new String(readBuf, 0, msg.arg1);
271 | if (readMessage.length() > 0) {
272 | mConversationArrayAdapter.add(mConnectedDeviceName+": " + readMessage);
273 | }
274 | break;
275 | case MESSAGE_DEVICE_NAME:
276 | // save the connected device's name
277 | mConnectedDeviceName = msg.getData().getString(DEVICE_NAME);
278 | Toast.makeText(getApplicationContext(), "Connected to "
279 | + mConnectedDeviceName, Toast.LENGTH_SHORT).show();
280 | break;
281 | case MESSAGE_TOAST:
282 | //if (!msg.getData().getString(TOAST).contains("Unable to connect device")) {
283 | Toast.makeText(getApplicationContext(), msg.getData().getString(TOAST),
284 | Toast.LENGTH_SHORT).show();
285 | //}
286 | break;
287 | }
288 | }
289 | };
290 |
291 | public void onActivityResult(int requestCode, int resultCode, Intent data) {
292 | if(D) Log.d(TAG, "onActivityResult " + resultCode);
293 | switch (requestCode) {
294 | case REQUEST_CONNECT_DEVICE:
295 | // When DeviceListActivity returns with a device to connect
296 | if (resultCode == Activity.RESULT_OK) {
297 | // Get the device MAC address
298 | String address = data.getExtras()
299 | .getString(DeviceListActivity.EXTRA_DEVICE_ADDRESS);
300 | // Get the BLuetoothDevice object
301 | BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
302 | // Attempt to connect to the device
303 | mChatService.connect(device);
304 | }
305 | break;
306 | case REQUEST_ENABLE_BT:
307 | // When the request to enable Bluetooth returns
308 | if (resultCode == Activity.RESULT_OK) {
309 | // Bluetooth is now enabled, so set up a chat session
310 | setupChat();
311 | } else {
312 | // User did not enable Bluetooth or an error occured
313 | Log.d(TAG, "BT not enabled");
314 | Toast.makeText(this, R.string.bt_not_enabled_leaving, Toast.LENGTH_SHORT).show();
315 | finish();
316 | }
317 | }
318 | }
319 |
320 | @Override
321 | public boolean onCreateOptionsMenu(Menu menu) {
322 | MenuInflater inflater = getMenuInflater();
323 | inflater.inflate(R.menu.option_menu, menu);
324 | return true;
325 | }
326 |
327 | @Override
328 | public boolean onOptionsItemSelected(MenuItem item) {
329 | switch (item.getItemId()) {
330 | case R.id.scan:
331 | // Launch the DeviceListActivity to see devices and do scan
332 | Intent serverIntent = new Intent(this, DeviceListActivity.class);
333 | startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE);
334 | return true;
335 | case R.id.discoverable:
336 | // Ensure this device is discoverable by others
337 | ensureDiscoverable();
338 | return true;
339 | }
340 | return false;
341 | }
342 |
343 | }
--------------------------------------------------------------------------------
/BluetoothChatMulti/src/com/example/android/BluetoothChatMulti/BluetoothChatService.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2009 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.example.android.BluetoothChatMulti;
18 |
19 | import java.io.IOException;
20 | import java.io.InputStream;
21 | import java.io.OutputStream;
22 | import java.util.ArrayList;
23 | import java.util.UUID;
24 |
25 | import android.bluetooth.BluetoothAdapter;
26 | import android.bluetooth.BluetoothDevice;
27 | import android.bluetooth.BluetoothServerSocket;
28 | import android.bluetooth.BluetoothSocket;
29 | import android.content.Context;
30 | import android.os.Bundle;
31 | import android.os.Handler;
32 | import android.os.Message;
33 | import android.util.Log;
34 |
35 | public class BluetoothChatService {
36 | // Debugging
37 | private static final String TAG = "BluetoothChatService";
38 | private static final boolean D = true;
39 |
40 | // Name for the SDP record when creating server socket
41 | private static final String NAME = "BluetoothChatMulti";
42 |
43 | // Member fields
44 | private final BluetoothAdapter mAdapter;
45 | private final Handler mHandler;
46 | private AcceptThread mAcceptThread;
47 | private ConnectThread mConnectThread;
48 | private ConnectedThread mConnectedThread;
49 | private int mState;
50 |
51 | private ArrayList mDeviceAddresses;
52 | private ArrayList mConnThreads;
53 | private ArrayList mSockets;
54 | /**
55 | * A bluetooth piconet can support up to 7 connections. This array holds 7 unique UUIDs.
56 | * When attempting to make a connection, the UUID on the client must match one that the server
57 | * is listening for. When accepting incoming connections server listens for all 7 UUIDs.
58 | * When trying to form an outgoing connection, the client tries each UUID one at a time.
59 | */
60 | private ArrayList mUuids;
61 |
62 | // Constants that indicate the current connection state
63 | public static final int STATE_NONE = 0; // we're doing nothing
64 | public static final int STATE_LISTEN = 1; // now listening for incoming connections
65 | public static final int STATE_CONNECTING = 2; // now initiating an outgoing connection
66 | public static final int STATE_CONNECTED = 3; // now connected to a remote device
67 |
68 | /**
69 | * Constructor. Prepares a new BluetoothChat session.
70 | * @param context The UI Activity Context
71 | * @param handler A Handler to send messages back to the UI Activity
72 | */
73 | public BluetoothChatService(Context context, Handler handler) {
74 | mAdapter = BluetoothAdapter.getDefaultAdapter();
75 | mState = STATE_NONE;
76 | mHandler = handler;
77 | mDeviceAddresses = new ArrayList();
78 | mConnThreads = new ArrayList();
79 | mSockets = new ArrayList();
80 | mUuids = new ArrayList();
81 | // 7 randomly-generated UUIDs. These must match on both server and client.
82 | mUuids.add(UUID.fromString("b7746a40-c758-4868-aa19-7ac6b3475dfc"));
83 | mUuids.add(UUID.fromString("2d64189d-5a2c-4511-a074-77f199fd0834"));
84 | mUuids.add(UUID.fromString("e442e09a-51f3-4a7b-91cb-f638491d1412"));
85 | mUuids.add(UUID.fromString("a81d6504-4536-49ee-a475-7d96d09439e4"));
86 | mUuids.add(UUID.fromString("aa91eab1-d8ad-448e-abdb-95ebba4a9b55"));
87 | mUuids.add(UUID.fromString("4d34da73-d0a4-4f40-ac38-917e0a9dee97"));
88 | mUuids.add(UUID.fromString("5e14d4df-9c8a-4db7-81e4-c937564c86e0"));
89 | }
90 |
91 | /**
92 | * Set the current state of the chat connection
93 | * @param state An integer defining the current connection state
94 | */
95 | private synchronized void setState(int state) {
96 | if (D) Log.d(TAG, "setState() " + mState + " -> " + state);
97 | mState = state;
98 |
99 | // Give the new state to the Handler so the UI Activity can update
100 | mHandler.obtainMessage(BluetoothChat.MESSAGE_STATE_CHANGE, state, -1).sendToTarget();
101 | }
102 |
103 | /**
104 | * Return the current connection state. */
105 | public synchronized int getState() {
106 | return mState;
107 | }
108 |
109 | /**
110 | * Start the chat service. Specifically start AcceptThread to begin a
111 | * session in listening (server) mode. Called by the Activity onResume() */
112 | public synchronized void start() {
113 | if (D) Log.d(TAG, "start");
114 |
115 | // Cancel any thread attempting to make a connection
116 | if (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;}
117 |
118 | // Cancel any thread currently running a connection
119 | if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;}
120 |
121 | // Start the thread to listen on a BluetoothServerSocket
122 | if (mAcceptThread == null) {
123 | mAcceptThread = new AcceptThread();
124 | mAcceptThread.start();
125 | }
126 | setState(STATE_LISTEN);
127 | }
128 |
129 | /**
130 | * Start the ConnectThread to initiate a connection to a remote device.
131 | * @param device The BluetoothDevice to connect
132 | */
133 | public synchronized void connect(BluetoothDevice device) {
134 | if (D) Log.d(TAG, "connect to: " + device);
135 |
136 | // Cancel any thread attempting to make a connection
137 | if (mState == STATE_CONNECTING) {
138 | if (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;}
139 | }
140 |
141 | // Cancel any thread currently running a connection
142 | if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;}
143 |
144 | // Create a new thread and attempt to connect to each UUID one-by-one.
145 | for (int i = 0; i < 7; i++) {
146 | try {
147 | mConnectThread = new ConnectThread(device, mUuids.get(i));
148 | mConnectThread.start();
149 | setState(STATE_CONNECTING);
150 | } catch (Exception e) {
151 | }
152 | }
153 | }
154 |
155 | /**
156 | * Start the ConnectedThread to begin managing a Bluetooth connection
157 | * @param socket The BluetoothSocket on which the connection was made
158 | * @param device The BluetoothDevice that has been connected
159 | */
160 | public synchronized void connected(BluetoothSocket socket, BluetoothDevice device) {
161 | if (D) Log.d(TAG, "connected");
162 |
163 | //Commented out all the cancellations of existing threads, since we want multiple connections.
164 | /*
165 | // Cancel the thread that completed the connection
166 | if (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;}
167 |
168 | // Cancel any thread currently running a connection
169 | if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;}
170 |
171 | // Cancel the accept thread because we only want to connect to one device
172 | if (mAcceptThread != null) {mAcceptThread.cancel(); mAcceptThread = null;}
173 | */
174 |
175 | // Start the thread to manage the connection and perform transmissions
176 | mConnectedThread = new ConnectedThread(socket);
177 | mConnectedThread.start();
178 | // Add each connected thread to an array
179 | mConnThreads.add(mConnectedThread);
180 |
181 | // Send the name of the connected device back to the UI Activity
182 | Message msg = mHandler.obtainMessage(BluetoothChat.MESSAGE_DEVICE_NAME);
183 | Bundle bundle = new Bundle();
184 | bundle.putString(BluetoothChat.DEVICE_NAME, device.getName());
185 | msg.setData(bundle);
186 | mHandler.sendMessage(msg);
187 |
188 | setState(STATE_CONNECTED);
189 | }
190 |
191 | /**
192 | * Stop all threads
193 | */
194 | public synchronized void stop() {
195 | if (D) Log.d(TAG, "stop");
196 | if (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;}
197 | if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;}
198 | if (mAcceptThread != null) {mAcceptThread.cancel(); mAcceptThread = null;}
199 | setState(STATE_NONE);
200 | }
201 |
202 | /**
203 | * Write to the ConnectedThread in an unsynchronized manner
204 | * @param out The bytes to write
205 | * @see ConnectedThread#write(byte[])
206 | */
207 | public void write(byte[] out) {
208 | // When writing, try to write out to all connected threads
209 | for (int i = 0; i < mConnThreads.size(); i++) {
210 | try {
211 | // Create temporary object
212 | ConnectedThread r;
213 | // Synchronize a copy of the ConnectedThread
214 | synchronized (this) {
215 | if (mState != STATE_CONNECTED) return;
216 | r = mConnThreads.get(i);
217 | }
218 | // Perform the write unsynchronized
219 | r.write(out);
220 | } catch (Exception e) {
221 | }
222 | }
223 | }
224 |
225 | /**
226 | * Indicate that the connection attempt failed and notify the UI Activity.
227 | */
228 | private void connectionFailed() {
229 | setState(STATE_LISTEN);
230 | // Commented out, because when trying to connect to all 7 UUIDs, failures will occur
231 | // for each that was tried and unsuccessful, resulting in multiple failure toasts.
232 | /*
233 | // Send a failure message back to the Activity
234 | Message msg = mHandler.obtainMessage(BluetoothChat.MESSAGE_TOAST);
235 | Bundle bundle = new Bundle();
236 | bundle.putString(BluetoothChat.TOAST, "Unable to connect device");
237 | msg.setData(bundle);
238 | mHandler.sendMessage(msg);
239 | */
240 | }
241 |
242 | /**
243 | * Indicate that the connection was lost and notify the UI Activity.
244 | */
245 | private void connectionLost() {
246 | setState(STATE_LISTEN);
247 |
248 | // Send a failure message back to the Activity
249 | Message msg = mHandler.obtainMessage(BluetoothChat.MESSAGE_TOAST);
250 | Bundle bundle = new Bundle();
251 | bundle.putString(BluetoothChat.TOAST, "Device connection was lost");
252 | msg.setData(bundle);
253 | mHandler.sendMessage(msg);
254 | }
255 |
256 | /**
257 | * This thread runs while listening for incoming connections. It behaves
258 | * like a server-side client. It runs until a connection is accepted
259 | * (or until cancelled).
260 | */
261 | private class AcceptThread extends Thread {
262 | BluetoothServerSocket serverSocket = null;
263 |
264 | public AcceptThread() {
265 | }
266 |
267 | public void run() {
268 | if (D) Log.d(TAG, "BEGIN mAcceptThread" + this);
269 | setName("AcceptThread");
270 | BluetoothSocket socket = null;
271 | try {
272 | // Listen for all 7 UUIDs
273 | for (int i = 0; i < 7; i++) {
274 | serverSocket = mAdapter.listenUsingRfcommWithServiceRecord(NAME, mUuids.get(i));
275 | socket = serverSocket.accept();
276 | if (socket != null) {
277 | String address = socket.getRemoteDevice().getAddress();
278 | mSockets.add(socket);
279 | mDeviceAddresses.add(address);
280 | connected(socket, socket.getRemoteDevice());
281 | }
282 | }
283 | } catch (IOException e) {
284 | Log.e(TAG, "accept() failed", e);
285 | }
286 | if (D) Log.i(TAG, "END mAcceptThread");
287 | }
288 |
289 | public void cancel() {
290 | if (D) Log.d(TAG, "cancel " + this);
291 | try {
292 | serverSocket.close();
293 | } catch (IOException e) {
294 | Log.e(TAG, "close() of server failed", e);
295 | }
296 | }
297 | }
298 |
299 |
300 | /**
301 | * This thread runs while attempting to make an outgoing connection
302 | * with a device. It runs straight through; the connection either
303 | * succeeds or fails.
304 | */
305 | private class ConnectThread extends Thread {
306 | private final BluetoothSocket mmSocket;
307 | private final BluetoothDevice mmDevice;
308 | private UUID tempUuid;
309 |
310 | public ConnectThread(BluetoothDevice device, UUID uuidToTry) {
311 | mmDevice = device;
312 | BluetoothSocket tmp = null;
313 | tempUuid = uuidToTry;
314 |
315 | // Get a BluetoothSocket for a connection with the
316 | // given BluetoothDevice
317 | try {
318 | tmp = device.createRfcommSocketToServiceRecord(uuidToTry);
319 | } catch (IOException e) {
320 | Log.e(TAG, "create() failed", e);
321 | }
322 | mmSocket = tmp;
323 | }
324 |
325 | public void run() {
326 | Log.i(TAG, "BEGIN mConnectThread");
327 | setName("ConnectThread");
328 |
329 | // Always cancel discovery because it will slow down a connection
330 | mAdapter.cancelDiscovery();
331 |
332 | // Make a connection to the BluetoothSocket
333 | try {
334 | // This is a blocking call and will only return on a
335 | // successful connection or an exception
336 | mmSocket.connect();
337 | } catch (IOException e) {
338 | if (tempUuid.toString().contentEquals(mUuids.get(6).toString())) {
339 | connectionFailed();
340 | }
341 | // Close the socket
342 | try {
343 | mmSocket.close();
344 | } catch (IOException e2) {
345 | Log.e(TAG, "unable to close() socket during connection failure", e2);
346 | }
347 | // Start the service over to restart listening mode
348 | BluetoothChatService.this.start();
349 | return;
350 | }
351 |
352 | // Reset the ConnectThread because we're done
353 | synchronized (BluetoothChatService.this) {
354 | mConnectThread = null;
355 | }
356 |
357 | // Start the connected thread
358 | connected(mmSocket, mmDevice);
359 | }
360 |
361 | public void cancel() {
362 | try {
363 | mmSocket.close();
364 | } catch (IOException e) {
365 | Log.e(TAG, "close() of connect socket failed", e);
366 | }
367 | }
368 | }
369 |
370 | /**
371 | * This thread runs during a connection with a remote device.
372 | * It handles all incoming and outgoing transmissions.
373 | */
374 | private class ConnectedThread extends Thread {
375 | private final BluetoothSocket mmSocket;
376 | private final InputStream mmInStream;
377 | private final OutputStream mmOutStream;
378 |
379 | public ConnectedThread(BluetoothSocket socket) {
380 | Log.d(TAG, "create ConnectedThread");
381 | mmSocket = socket;
382 | InputStream tmpIn = null;
383 | OutputStream tmpOut = null;
384 |
385 | // Get the BluetoothSocket input and output streams
386 | try {
387 | tmpIn = socket.getInputStream();
388 | tmpOut = socket.getOutputStream();
389 | } catch (IOException e) {
390 | Log.e(TAG, "temp sockets not created", e);
391 | }
392 |
393 | mmInStream = tmpIn;
394 | mmOutStream = tmpOut;
395 | }
396 |
397 | public void run() {
398 | Log.i(TAG, "BEGIN mConnectedThread");
399 | byte[] buffer = new byte[1024];
400 | int bytes;
401 |
402 | // Keep listening to the InputStream while connected
403 | while (true) {
404 | try {
405 | // Read from the InputStream
406 | bytes = mmInStream.read(buffer);
407 |
408 | // Send the obtained bytes to the UI Activity
409 | mHandler.obtainMessage(BluetoothChat.MESSAGE_READ, bytes, -1, buffer)
410 | .sendToTarget();
411 | } catch (IOException e) {
412 | Log.e(TAG, "disconnected", e);
413 | connectionLost();
414 | break;
415 | }
416 | }
417 | }
418 |
419 | /**
420 | * Write to the connected OutStream.
421 | * @param buffer The bytes to write
422 | */
423 | public void write(byte[] buffer) {
424 | try {
425 | mmOutStream.write(buffer);
426 |
427 | // Share the sent message back to the UI Activity
428 | mHandler.obtainMessage(BluetoothChat.MESSAGE_WRITE, -1, -1, buffer)
429 | .sendToTarget();
430 | } catch (IOException e) {
431 | Log.e(TAG, "Exception during write", e);
432 | }
433 | }
434 |
435 | public void cancel() {
436 | try {
437 | mmSocket.close();
438 | } catch (IOException e) {
439 | Log.e(TAG, "close() of connect socket failed", e);
440 | }
441 | }
442 | }
443 | }
444 |
--------------------------------------------------------------------------------
/BluetoothChatMulti/src/com/example/android/BluetoothChatMulti/DeviceListActivity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2009 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.example.android.BluetoothChatMulti;
18 |
19 | import java.util.Set;
20 |
21 | import android.app.Activity;
22 | import android.bluetooth.BluetoothAdapter;
23 | import android.bluetooth.BluetoothDevice;
24 | import android.content.BroadcastReceiver;
25 | import android.content.Context;
26 | import android.content.Intent;
27 | import android.content.IntentFilter;
28 | import android.os.Bundle;
29 | import android.util.Log;
30 | import android.view.View;
31 | import android.view.Window;
32 | import android.view.View.OnClickListener;
33 | import android.widget.AdapterView;
34 | import android.widget.ArrayAdapter;
35 | import android.widget.Button;
36 | import android.widget.ListView;
37 | import android.widget.TextView;
38 | import android.widget.AdapterView.OnItemClickListener;
39 |
40 | /**
41 | * This Activity appears as a dialog. It lists any paired devices and
42 | * devices detected in the area after discovery. When a device is chosen
43 | * by the user, the MAC address of the device is sent back to the parent
44 | * Activity in the result Intent.
45 | */
46 | public class DeviceListActivity extends Activity {
47 | // Debugging
48 | private static final String TAG = "DeviceListActivity";
49 | private static final boolean D = true;
50 |
51 | // Return Intent extra
52 | public static String EXTRA_DEVICE_ADDRESS = "device_address";
53 |
54 | // Member fields
55 | private BluetoothAdapter mBtAdapter;
56 | private ArrayAdapter mPairedDevicesArrayAdapter;
57 | private ArrayAdapter mNewDevicesArrayAdapter;
58 |
59 | @Override
60 | protected void onCreate(Bundle savedInstanceState) {
61 | super.onCreate(savedInstanceState);
62 |
63 | // Setup the window
64 | requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
65 | setContentView(R.layout.device_list);
66 |
67 | // Set result CANCELED incase the user backs out
68 | setResult(Activity.RESULT_CANCELED);
69 |
70 | // Initialize the button to perform device discovery
71 | Button scanButton = (Button) findViewById(R.id.button_scan);
72 | scanButton.setOnClickListener(new OnClickListener() {
73 | public void onClick(View v) {
74 | doDiscovery();
75 | v.setVisibility(View.GONE);
76 | }
77 | });
78 |
79 | // Initialize array adapters. One for already paired devices and
80 | // one for newly discovered devices
81 | mPairedDevicesArrayAdapter = new ArrayAdapter(this, R.layout.device_name);
82 | mNewDevicesArrayAdapter = new ArrayAdapter(this, R.layout.device_name);
83 |
84 | // Find and set up the ListView for paired devices
85 | ListView pairedListView = (ListView) findViewById(R.id.paired_devices);
86 | pairedListView.setAdapter(mPairedDevicesArrayAdapter);
87 | pairedListView.setOnItemClickListener(mDeviceClickListener);
88 |
89 | // Find and set up the ListView for newly discovered devices
90 | ListView newDevicesListView = (ListView) findViewById(R.id.new_devices);
91 | newDevicesListView.setAdapter(mNewDevicesArrayAdapter);
92 | newDevicesListView.setOnItemClickListener(mDeviceClickListener);
93 |
94 | // Register for broadcasts when a device is discovered
95 | IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
96 | this.registerReceiver(mReceiver, filter);
97 |
98 | // Register for broadcasts when discovery has finished
99 | filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
100 | this.registerReceiver(mReceiver, filter);
101 |
102 | // Get the local Bluetooth adapter
103 | mBtAdapter = BluetoothAdapter.getDefaultAdapter();
104 |
105 | // Get a set of currently paired devices
106 | Set pairedDevices = mBtAdapter.getBondedDevices();
107 |
108 | // If there are paired devices, add each one to the ArrayAdapter
109 | if (pairedDevices.size() > 0) {
110 | findViewById(R.id.title_paired_devices).setVisibility(View.VISIBLE);
111 | for (BluetoothDevice device : pairedDevices) {
112 | mPairedDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());
113 | }
114 | } else {
115 | String noDevices = getResources().getText(R.string.none_paired).toString();
116 | mPairedDevicesArrayAdapter.add(noDevices);
117 | }
118 | }
119 |
120 | @Override
121 | protected void onDestroy() {
122 | super.onDestroy();
123 |
124 | // Make sure we're not doing discovery anymore
125 | if (mBtAdapter != null) {
126 | mBtAdapter.cancelDiscovery();
127 | }
128 |
129 | // Unregister broadcast listeners
130 | this.unregisterReceiver(mReceiver);
131 | }
132 |
133 | /**
134 | * Start device discover with the BluetoothAdapter
135 | */
136 | private void doDiscovery() {
137 | if (D) Log.d(TAG, "doDiscovery()");
138 |
139 | // Indicate scanning in the title
140 | setProgressBarIndeterminateVisibility(true);
141 | setTitle(R.string.scanning);
142 |
143 | // Turn on sub-title for new devices
144 | findViewById(R.id.title_new_devices).setVisibility(View.VISIBLE);
145 |
146 | // If we're already discovering, stop it
147 | if (mBtAdapter.isDiscovering()) {
148 | mBtAdapter.cancelDiscovery();
149 | }
150 |
151 | // Request discover from BluetoothAdapter
152 | mBtAdapter.startDiscovery();
153 | }
154 |
155 | // The on-click listener for all devices in the ListViews
156 | private OnItemClickListener mDeviceClickListener = new OnItemClickListener() {
157 | public void onItemClick(AdapterView> av, View v, int arg2, long arg3) {
158 | // Cancel discovery because it's costly and we're about to connect
159 | mBtAdapter.cancelDiscovery();
160 |
161 | // Get the device MAC address, which is the last 17 chars in the View
162 | String info = ((TextView) v).getText().toString();
163 | String address = info.substring(info.length() - 17);
164 |
165 | // Create the result Intent and include the MAC address
166 | Intent intent = new Intent();
167 | intent.putExtra(EXTRA_DEVICE_ADDRESS, address);
168 |
169 | // Set result and finish this Activity
170 | setResult(Activity.RESULT_OK, intent);
171 | finish();
172 | }
173 | };
174 |
175 | // The BroadcastReceiver that listens for discovered devices and
176 | // changes the title when discovery is finished
177 | private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
178 | @Override
179 | public void onReceive(Context context, Intent intent) {
180 | String action = intent.getAction();
181 |
182 | // When discovery finds a device
183 | if (BluetoothDevice.ACTION_FOUND.equals(action)) {
184 | // Get the BluetoothDevice object from the Intent
185 | BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
186 | // If it's already paired, skip it, because it's been listed already
187 | if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
188 | mNewDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());
189 | }
190 | // When discovery is finished, change the Activity title
191 | } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
192 | setProgressBarIndeterminateVisibility(false);
193 | setTitle(R.string.select_device);
194 | if (mNewDevicesArrayAdapter.getCount() == 0) {
195 | String noDevices = getResources().getText(R.string.none_found).toString();
196 | mNewDevicesArrayAdapter.add(noDevices);
197 | }
198 | }
199 | }
200 | };
201 |
202 | }
203 |
--------------------------------------------------------------------------------