7 package com.google.appinventor.components.runtime;
23 import android.os.Handler;
24 import android.util.Log;
26 import java.io.IOException;
27 import java.util.UUID;
28 import java.util.concurrent.atomic.AtomicReference;
36 @DesignerComponent(version = YaVersion.BLUETOOTHSERVER_COMPONENT_VERSION,
37 description =
"Bluetooth server component",
38 category = ComponentCategory.CONNECTIVITY,
40 iconName =
"images/bluetooth.png")
42 @UsesPermissions(permissionNames =
43 "android.permission.BLUETOOTH, " +
44 "android.permission.BLUETOOTH_ADMIN")
46 private static final String SPP_UUID =
"00001101-0000-1000-8000-00805F9B34FB";
48 private final Handler androidUIHandler;
50 private final AtomicReference<Object> arBluetoothServerSocket;
56 super(container,
"BluetoothServer");
57 androidUIHandler =
new Handler();
58 arBluetoothServerSocket =
new AtomicReference<Object>();
64 @
SimpleFunction(description =
"Accept an incoming connection with the Serial Port " +
66 public
void AcceptConnection(String serviceName) {
67 accept(
"AcceptConnection", serviceName, SPP_UUID);
73 @
SimpleFunction(description =
"Accept an incoming connection with a specific UUID.")
74 public
void AcceptConnectionWithUUID(String serviceName, String uuid) {
75 accept(
"AcceptConnectionWithUUID", serviceName, uuid);
78 private void accept(
final String functionName, String name, String uuidString) {
80 if (bluetoothAdapter ==
null) {
81 form.dispatchErrorOccurredEvent(
this, functionName,
86 if (!BluetoothReflection.isBluetoothEnabled(bluetoothAdapter)) {
87 form.dispatchErrorOccurredEvent(
this, functionName,
88 ErrorMessages.ERROR_BLUETOOTH_NOT_ENABLED);
94 uuid = UUID.fromString(uuidString);
95 }
catch (IllegalArgumentException e) {
96 form.dispatchErrorOccurredEvent(
this, functionName,
97 ErrorMessages.ERROR_BLUETOOTH_INVALID_UUID, uuidString);
102 Object bluetoothServerSocket;
103 if (!secure && SdkLevel.getLevel() >= SdkLevel.LEVEL_GINGERBREAD_MR1) {
105 bluetoothServerSocket = BluetoothReflection.listenUsingInsecureRfcommWithServiceRecord(
106 bluetoothAdapter, name, uuid);
108 bluetoothServerSocket = BluetoothReflection.listenUsingRfcommWithServiceRecord(
109 bluetoothAdapter, name, uuid);
111 arBluetoothServerSocket.set(bluetoothServerSocket);
112 }
catch (IOException e) {
113 form.dispatchErrorOccurredEvent(
this, functionName,
114 ErrorMessages.ERROR_BLUETOOTH_UNABLE_TO_LISTEN);
118 AsynchUtil.runAsynchronously(
new Runnable() {
120 Object acceptedBluetoothSocket =
null;
122 Object bluetoothServerSocket = arBluetoothServerSocket.get();
123 if (bluetoothServerSocket !=
null) {
126 acceptedBluetoothSocket = BluetoothReflection.accept(bluetoothServerSocket);
127 }
catch (IOException e) {
128 androidUIHandler.post(
new Runnable() {
130 form.dispatchErrorOccurredEvent(BluetoothServer.this, functionName,
131 ErrorMessages.ERROR_BLUETOOTH_UNABLE_TO_ACCEPT);
141 if (acceptedBluetoothSocket !=
null) {
143 final Object bluetoothSocket = acceptedBluetoothSocket;
144 androidUIHandler.post(
new Runnable() {
147 setConnection(bluetoothSocket);
148 }
catch (IOException e) {
150 form.dispatchErrorOccurredEvent(BluetoothServer.this, functionName,
151 ErrorMessages.ERROR_BLUETOOTH_UNABLE_TO_ACCEPT);
155 ConnectionAccepted();
167 @SimpleProperty(category = PropertyCategory.BEHAVIOR)
168 public final
boolean IsAccepting() {
169 return (arBluetoothServerSocket.get() !=
null);
175 @
SimpleFunction(description =
"Stop accepting an incoming connection.")
176 public
void StopAccepting() {
177 Object bluetoothServerSocket = arBluetoothServerSocket.getAndSet(
null);
178 if (bluetoothServerSocket !=
null) {
181 }
catch (IOException e) {
182 Log.w(logTag,
"Error while closing bluetooth server socket: " + e.getMessage());
190 @
SimpleEvent(description =
"Indicates that a bluetooth connection has been accepted.")
191 public
void ConnectionAccepted() {
192 Log.i(logTag,
"Successfullly accepted bluetooth connection.");