I make a POS in android. I want to make a printing in my apps. To do printing I'm using bluetooth printer. Then, I had success make the bluetooth connection and I make it in one fragment. But every time I move to another fragment the bluetooth connction will be disconnected. How can I prevent bluetooth disconnect when moving fragment?
SettingFragment.Java
/**
* A simple {#link Fragment} subclass.
*/
public class SettingFragment extends Fragment {
public static final int MESSAGE_STATE_CHANGE = 1;
public static final int MESSAGE_READ = 2;
public static final int MESSAGE_WRITE = 3;
public static final int MESSAGE_DEVICE_NAME = 4;
public static final int MESSAGE_TOAST = 5;
public static final int MESSAGE_CONNECTION_LOST = 6;
public static final int MESSAGE_UNABLE_CONNECT = 7;
private String mConnectedDeviceName = null;
// Key names received from the BluetoothService Handler
public static final String DEVICE_NAME = "device_name";
public static final String TOAST = "toast";
// Intent request codes
private static final int REQUEST_CONNECT_DEVICE = 1;
private static final int REQUEST_ENABLE_BT = 2;
private BluetoothAdapter mBluetoothAdapter = null;
private BluetoothService mService = null;
private static final String CHINESE = "GBK";
SessionManagement sessionManagement;
DatabaseHandler db;
TextView tvConnected;
Button btnScan;
Button btnTest;
public SettingFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootview = inflater.inflate(R.layout.fragment_setting, container, false);
getActivity().setTitle("Setting");
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
btnScan = (Button)rootview.findViewById(R.id.btnScan);
btnTest = (Button) rootview.findViewById(R.id.btnTest);
tvConnected = (TextView) rootview.findViewById(R.id.tvPrinterConnect);
if (!mBluetoothAdapter.isEnabled()) {
Intent enableIntent = new Intent(
BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
// Otherwise, setup the session
} else {
if (mService == null)
KeyListenerInit();
}
return rootview;
}
#SuppressLint("HandlerLeak")
private final Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MESSAGE_STATE_CHANGE:
if (DEBUG)
Log.i(TAG, "MESSAGE_STATE_CHANGE: " + msg.arg1);
switch (msg.arg1) {
case BluetoothService.STATE_CONNECTED:
//btnScan.setText(getText(R.string.Connecting));
btnScan.setEnabled(false);
break;
case BluetoothService.STATE_CONNECTING:
Toast.makeText((MainActivity)getContext(),R.string.title_connecting,Toast.LENGTH_SHORT).show();
break;
case BluetoothService.STATE_LISTEN:
case BluetoothService.STATE_NONE:
Toast.makeText((MainActivity)getContext(),R.string.title_not_connected,Toast.LENGTH_SHORT).show();
break;
}
break;
case MESSAGE_WRITE:
break;
case MESSAGE_READ:
break;
case MESSAGE_DEVICE_NAME:
// save the connected device's name
mConnectedDeviceName = msg.getData().getString(DEVICE_NAME);
Toast.makeText(getActivity(),
"Connected to " + mConnectedDeviceName,
Toast.LENGTH_SHORT).show();
tvConnected.setText("Connected to "+mConnectedDeviceName );
break;
case MESSAGE_TOAST:
Toast.makeText(getActivity(),
msg.getData().getString(TOAST), Toast.LENGTH_SHORT)
.show();
break;
case MESSAGE_CONNECTION_LOST:
Toast.makeText(getActivity(), "Device connection was lost",
Toast.LENGTH_SHORT).show();
tvConnected.setText("Not Connect to Any Device");
// editText.setEnabled(false);
// sendButton.setEnabled(false);
break;
case MESSAGE_UNABLE_CONNECT:
Toast.makeText(getActivity(), "Unable to connect device",
Toast.LENGTH_SHORT).show();
break;
}
}
};
#Override
public void onStart() {
super.onStart();
// If Bluetooth is not on, request that it be enabled.
// setupChat() will then be called during onActivityResult
if (!mBluetoothAdapter.isEnabled()) {
Intent enableIntent = new Intent(
BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
// Otherwise, setup the session
} else {
if (mService == null)
KeyListenerInit();
}
}
#Override
public synchronized void onResume() {
super.onResume();
if (mService != null) {
if (mService.getState() == BluetoothService.STATE_NONE) {
// Start the Bluetooth services
mService.start();
}
}
}
#Override
public synchronized void onPause() {
super.onPause();
if (DEBUG)
Log.e(TAG, "- ON PAUSE -");
}
#Override
public void onStop() {
super.onStop();
if (DEBUG)
Log.e(TAG, "-- ON STOP --");
}
#Override
public void onDestroy() {
super.onDestroy();
// Stop the Bluetooth services
if (mService != null)
mService.stop();
if (DEBUG)
Log.e(TAG, "--- ON DESTROY ---");
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (DEBUG)
Log.d(TAG, "onActivityResult " + resultCode);
switch (requestCode) {
case REQUEST_CONNECT_DEVICE:{
// When DeviceListActivity returns with a device to connect
if (resultCode == Activity.RESULT_OK) {
// Get the device MAC address
String address = data.getExtras().getString(
DeviceListActivity.EXTRA_DEVICE_ADDRESS);
// Get the BLuetoothDevice object
if (BluetoothAdapter.checkBluetoothAddress(address)) {
BluetoothDevice device = mBluetoothAdapter
.getRemoteDevice(address);
// Attempt to connect to the device
mService.connect(device);
}
}
break;
}
case REQUEST_ENABLE_BT:{
// When the request to enable Bluetooth returns
if (resultCode == Activity.RESULT_OK) {
// Bluetooth is now enabled, so set up a session
KeyListenerInit();
} else {
// User did not enable Bluetooth or an error occured
Log.d(TAG, "BT not enabled");
Toast.makeText(getActivity(), R.string.bt_not_enabled_leaving,
Toast.LENGTH_SHORT).show();
getActivity().onBackPressed();
}
break;
}
}
}
private void KeyListenerInit() {
btnScan.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent serverIntent = new Intent(getActivity(), DeviceListActivity.class);
startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE);
}
});
mService = new BluetoothService(getActivity(), mHandler);
}
}
BluetoothService.JAVA
public class BluetoothService {
// Debugging
private static final String TAG = "BluetoothService";
private static final boolean DEBUG = true;
// Name for the SDP record when creating server socket
private static final String NAME = "ZJPrinter";
//UUID must be this
// Unique UUID for this application
private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
// Member fields
private BluetoothAdapter mAdapter;
private Handler mHandler;
private AcceptThread mAcceptThread;
private ConnectThread mConnectThread;
private ConnectedThread mConnectedThread;
private int mState;
// Constants that indicate the current connection state
public static final int STATE_NONE = 0; // we're doing nothing
public static final int STATE_LISTEN = 1; // now listening for incoming connections
public static final int STATE_CONNECTING = 2; // now initiating an outgoing connection
public static final int STATE_CONNECTED = 3; // now connected to a remote device
public static String ErrorMessage = "No_Error_Message";
/**
* Constructor. Prepares a new BTPrinter session.
* #param context The UI Activity Context
* #param handler A Handler to send messages back to the UI Activity
*/
public BluetoothService(Context context, Handler handler) {
mAdapter = BluetoothAdapter.getDefaultAdapter();
mState = STATE_NONE;
mHandler = handler;
}
/**
* Set the current state of the connection
* #param state An integer defining the current connection state
*/
private synchronized void setState(int state) {
if (DEBUG) Log.d(TAG, "setState() " + mState + " -> " + state);
mState = state;
// Give the new state to the Handler so the UI Activity can update
mHandler.obtainMessage(SettingFragment.MESSAGE_STATE_CHANGE, state, -1).sendToTarget();
}
/**
* Return the current connection state. */
public synchronized int getState() {
return mState;
}
/**
* Start the service. Specifically start AcceptThread to begin a
* session in listening (server) mode. Called by the Activity onResume() */
public synchronized void start() {
if (DEBUG) Log.d(TAG, "start");
// Cancel any thread attempting to make a connection
if (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;}
// Cancel any thread currently running a connection
if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;}
// Start the thread to listen on a BluetoothServerSocket
if (mAcceptThread == null) {
mAcceptThread = new AcceptThread();
mAcceptThread.start();
}
setState(STATE_LISTEN);
}
/**
* Start the ConnectThread to initiate a connection to a remote device.
* #param device The BluetoothDevice to connect
*/
public synchronized void connect(BluetoothDevice device) {
if (DEBUG) Log.d(TAG, "connect to: " + device);
// Cancel any thread attempting to make a connection
if (mState == STATE_CONNECTING) {
if (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;}
}
// Cancel any thread currently running a connection
if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;}
// Start the thread to connect with the given device
mConnectThread = new ConnectThread(device);
mConnectThread.start();
setState(STATE_CONNECTING);
}
/**
* Start the ConnectedThread to begin managing a Bluetooth connection
* #param socket The BluetoothSocket on which the connection was made
* #param device The BluetoothDevice that has been connected
*/
public synchronized void connected(BluetoothSocket socket, BluetoothDevice device) {
if (DEBUG) Log.d(TAG, "connected");
// Cancel the thread that completed the connection
if (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;}
// Cancel any thread currently running a connection
if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;}
// Cancel the accept thread because we only want to connect to one device
if (mAcceptThread != null) {mAcceptThread.cancel(); mAcceptThread = null;}
// Start the thread to manage the connection and perform transmissions
mConnectedThread = new ConnectedThread(socket);
mConnectedThread.start();
// Send the name of the connected device back to the UI Activity
Message msg = mHandler.obtainMessage(SettingFragment.MESSAGE_DEVICE_NAME);
Bundle bundle = new Bundle();
bundle.putString(SettingFragment.DEVICE_NAME, device.getName());
msg.setData(bundle);
mHandler.sendMessage(msg);
setState(STATE_CONNECTED);
}
/**
* Stop all threads
*/
public synchronized void stop() {
if (DEBUG) Log.d(TAG, "stop");
setState(STATE_NONE);
if (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;}
if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;}
if (mAcceptThread != null) {mAcceptThread.cancel(); mAcceptThread = null;}
}
/**
* Write to the ConnectedThread in an unsynchronized manner
* #param out The bytes to write
* #see ConnectedThread#write(byte[])
*/
public void write(byte[] out) {
// Create temporary object
ConnectedThread r;
// Synchronize a copy of the ConnectedThread
synchronized (this) {
if (mState != STATE_CONNECTED) return;
r = mConnectedThread;
}
r.write(out);
}
/**
* Indicate that the connection attempt failed and notify the UI Activity.
*/
private void connectionFailed() {
setState(STATE_LISTEN);
// Send a failure message back to the Activity
Message msg = mHandler.obtainMessage(SettingFragment.MESSAGE_TOAST);
Bundle bundle = new Bundle();
bundle.putString(SettingFragment.TOAST, "Unable to connect device");
msg.setData(bundle);
mHandler.sendMessage(msg);
}
/**
* Indicate that the connection was lost and notify the UI Activity.
*/
private void connectionLost() {
//setState(STATE_LISTEN);
// Send a failure message back to the Activity
Message msg = mHandler.obtainMessage(SettingFragment.MESSAGE_TOAST);
Bundle bundle = new Bundle();
bundle.putString(SettingFragment.TOAST, "Device connection was lost");
msg.setData(bundle);
mHandler.sendMessage(msg);
}
/**
* This thread runs while listening for incoming connections. It behaves
* like a server-side client. It runs until a connection is accepted
* (or until cancelled).
*/
private class AcceptThread extends Thread {
// The local server socket
private final BluetoothServerSocket mmServerSocket;
public AcceptThread() {
BluetoothServerSocket tmp = null;
// Create a new listening server socket
try {
tmp = mAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);
} catch (IOException e) {
Log.e(TAG, "listen() failed", e);
}
mmServerSocket = tmp;
}
#Override
public void run() {
if (DEBUG) Log.d(TAG, "BEGIN mAcceptThread" + this);
setName("AcceptThread");
BluetoothSocket socket = null;
// Listen to the server socket if we're not connected
while (mState != STATE_CONNECTED) {
try {
// This is a blocking call and will only return on a
// successful connection or an exception
socket = mmServerSocket.accept();
} catch (IOException e) {
Log.e(TAG, "accept() failed", e);
break;
}
// If a connection was accepted
if (socket != null) {
synchronized (BluetoothService.this) {
switch (mState) {
case STATE_LISTEN:
case STATE_CONNECTING:
// Situation normal. Start the connected thread.
connected(socket, socket.getRemoteDevice());
break;
case STATE_NONE:
case STATE_CONNECTED:
// Either not ready or already connected. Terminate new socket.
try {
socket.close();
} catch (IOException e) {
Log.e(TAG, "Could not close unwanted socket", e);
}
break;
}
}
}
}
if (DEBUG) Log.i(TAG, "END mAcceptThread");
}
public void cancel() {
if (DEBUG) Log.d(TAG, "cancel " + this);
try {
mmServerSocket.close();
} catch (IOException e) {
Log.e(TAG, "close() of server failed", e);
}
}
}
/**
* This thread runs while attempting to make an outgoing connection
* with a device. It runs straight through; the connection either
* succeeds or fails.
*/
private class ConnectThread extends Thread {
private final BluetoothSocket mmSocket;
private final BluetoothDevice mmDevice;
public ConnectThread(BluetoothDevice device) {
mmDevice = device;
BluetoothSocket tmp = null;
// Get a BluetoothSocket for a connection with the
// given BluetoothDevice
try {
tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e) {
Log.e(TAG, "create() failed", e);
}
mmSocket = tmp;
}
#Override
public void run() {
Log.i(TAG, "BEGIN mConnectThread");
setName("ConnectThread");
// Always cancel discovery because it will slow down a connection
mAdapter.cancelDiscovery();
// Make a connection to the BluetoothSocket
try {
// This is a blocking call and will only return on a
// successful connection or an exception
mmSocket.connect();
} catch (IOException e) {
connectionFailed();
// Close the socket
try {
mmSocket.close();
} catch (IOException e2) {
Log.e(TAG, "unable to close() socket during connection failure", e2);
}
// Start the service over to restart listening mode
BluetoothService.this.start();
return;
}
// Reset the ConnectThread because we're done
synchronized (BluetoothService.this) {
mConnectThread = null;
}
// Start the connected thread
connected(mmSocket, mmDevice);
}
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) {
Log.e(TAG, "close() of connect socket failed", e);
}
}
}
/**
* This thread runs during a connection with a remote device.
* It handles all incoming and outgoing transmissions.
*/
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
public ConnectedThread(BluetoothSocket socket) {
Log.d(TAG, "create ConnectedThread");
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
// Get the BluetoothSocket input and output streams
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) {
Log.e(TAG, "temp sockets not created", e);
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
#Override
public void run() {
Log.i(TAG, "BEGIN mConnectedThread");
int bytes;
// Keep listening to the InputStream while connected
while (true) {
try {
byte[] buffer = new byte[256];
// Read from the InputStream
bytes = mmInStream.read(buffer);
if(bytes>0)
{
// Send the obtained bytes to the UI Activity
mHandler.obtainMessage(SettingFragment.MESSAGE_READ, bytes, -1, buffer)
.sendToTarget();
}
else
{
Log.e(TAG, "disconnected");
connectionLost();
//add by chongqing jinou
if(mState != STATE_NONE)
{
Log.e(TAG, "disconnected");
// Start the service over to restart listening mode
BluetoothService.this.start();
}
break;
}
} catch (IOException e) {
Log.e(TAG, "disconnected", e);
connectionLost();
//add by chongqing jinou
if(mState != STATE_NONE)
{
// Start the service over to restart listening mode
BluetoothService.this.start();
}
break;
}
}
}
/**
* Write to the connected OutStream.
* #param buffer The bytes to write
*/
public void write(byte[] buffer) {
try {
mmOutStream.write(buffer);
mmOutStream.flush();//清空缓存
/* if (buffer.length > 3000) //
{
byte[] readata = new byte[1];
SPPReadTimeout(readata, 1, 5000);
}*/
Log.i("BTPWRITE", new String(buffer,"GBK"));
// Share the sent message back to the UI Activity
mHandler.obtainMessage(SettingFragment.MESSAGE_WRITE, -1, -1, buffer)
.sendToTarget();
} catch (IOException e) {
Log.e(TAG, "Exception during write", e);
}
}
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) {
Log.e(TAG, "close() of connect socket failed", e);
}
}
}
}
Related
I am developing an app which sends data to the android with Bluetooth. I can send data and see from the ardunio side. I can connect the device but when I go to the another activity in the app connection has been lost. How can I keep connection open? In the Second class I can connected the device and send the data, if I have another activity how can i use active Bluetooth connection and send data?
private String mConnectedDeviceName = null;
private StringBuffer mOutStringBuffer;
private BluetoothAdapter mBluetoothAdapter = null;
private BluetoothChatService mChatService = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
// Get local Bluetooth adapter
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
// If the adapter is null, then Bluetooth is not supported
FragmentActivity activity = getActivity();
if (mBluetoothAdapter == null && activity != null) {
Toast.makeText(activity, "Bluetooth is not available", Toast.LENGTH_LONG).show();
activity.finish();
}
}
#Override
public void onStart() {
super.onStart();
if (mBluetoothAdapter == null) {
return;
}
// If BT is not on, request that it be enabled.
// setupChat() will then be called during onActivityResult
if (!mBluetoothAdapter.isEnabled()) {
Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
// Otherwise, setup the chat session
} else if (mChatService == null) {
setupChat();
}
}
#Override
public void onDestroy() {
super.onDestroy();
if (mChatService != null) {
mChatService.stop();
}
}
#Override
public void onResume() {
super.onResume();
if (mChatService != null) {
// Only if the state is STATE_NONE, do we know that we haven't started already
if (mChatService.getState() == BluetoothChatService.STATE_NONE) {
// Start the Bluetooth chat services
mChatService.start();
}
}
}
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container,
#Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_bluetooth_chat, container, false);
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
rad_saat = view.findViewById(R.id.rad_saat);
rad_Co2 = view.findViewById(R.id.rad_CO2);
rad_sicaklik = view.findViewById(R.id.rad_sicaklik);
rad_Manuel = view.findViewById(R.id.rad_manuel);
opn_spinner = view.findViewById(R.id.spn_options);
radioGroup = view.findViewById(R.id.radioGroup);
spnCrd_Options = view.findViewById(R.id.spnCrd_Options);
crd_GonderButton = view.findViewById(R.id.crd_GonderButton);
txt_GonderButton = view.findViewById(R.id.txt_GonderButton);
rad_saat.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
checkButton();
}
});
rad_Co2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
checkButton();
}
});
rad_sicaklik.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
checkButton();
}
});
rad_Manuel.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
checkButton();
}
});
radioGroup.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
checkButton();
}
});
crd_GonderButton.setOnClickListener(new View.OnClickListener() {
#RequiresApi(api = Build.VERSION_CODES.O)
#Override
public void onClick(View v) {
sendButton();
}
});
txt_GonderButton.setOnClickListener(new View.OnClickListener() {
#RequiresApi(api = Build.VERSION_CODES.O)
#Override
public void onClick(View v) {
sendButton();
}
});
}
private void setupChat() {
Log.d(TAG, "setupChat()");
// Initialize the array adapter for the conversation thread
FragmentActivity activity = getActivity();
if (activity == null) {
return;
}
// Initialize the BluetoothChatService to perform bluetooth connections
mChatService = new BluetoothChatService(activity, mHandler);
// Initialize the buffer for outgoing messages
mOutStringBuffer = new StringBuffer();
}
private void ensureDiscoverable() {
if (mBluetoothAdapter.getScanMode() !=
BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
startActivity(discoverableIntent);
}
}
public void sendMessage(String message) {
// Check that we're actually connected before trying anything
if (mChatService.getState() != BluetoothChatService.STATE_CONNECTED) {
Toast.makeText(getActivity(), R.string.not_connected, Toast.LENGTH_SHORT).show();
return;
}
// Check that there's actually something to send
if (message.length() > 0) {
// Get the message bytes and tell the BluetoothChatService to write
byte[] send = message.getBytes();
mChatService.write(send);
// Reset out string buffer to zero and clear the edit text field
mOutStringBuffer.setLength(0);
}
}
private TextView.OnEditorActionListener mWriteListener
= new TextView.OnEditorActionListener() {
public boolean onEditorAction(TextView view, int actionId, KeyEvent event) {
// If the action is a key-up event on the return key, send the message
if (actionId == EditorInfo.IME_NULL && event.getAction() == KeyEvent.ACTION_UP) {
String message = view.getText().toString();
sendMessage(message);
}
return true;
}
};
private void setStatus(int resId) {
FragmentActivity activity = getActivity();
if (null == activity) {
return;
}
final ActionBar actionBar = activity.getActionBar();
if (null == actionBar) {
return;
}
actionBar.setSubtitle(resId);
}
private void setStatus(CharSequence subTitle) {
FragmentActivity activity = getActivity();
if (null == activity) {
return;
}
final ActionBar actionBar = activity.getActionBar();
if (null == actionBar) {
return;
}
actionBar.setSubtitle(subTitle);
}
private void messageHandler()
{
}
public void checkButton(){
saatList = new ArrayList<String>(Arrays.asList(new String[]{"00:00 - 03:00","03:00 -06:00 ","06:00 - 09:00","09:00 - 12:00","12:00 - 15:00","15:00 - 18:00","18:00 - 21:00","21:00 - 00:00"}));
manuelList = new ArrayList<String>(Arrays.asList(new String[]{"KAPALI","AÇIK"}));
if(rad_saat.isChecked()){
atananList = saatList;
spnCrd_Options.setVisibility(View.VISIBLE);
opn_spinner.setVisibility(View.VISIBLE);
}
if(rad_Manuel.isChecked()){
atananList = manuelList;
spnCrd_Options.setVisibility(View.VISIBLE);
opn_spinner.setVisibility(View.VISIBLE);
}
if(rad_Co2.isChecked()){
opn_spinner.setVisibility(View.GONE);
spnCrd_Options.setVisibility(View.GONE);
}
if(rad_sicaklik.isChecked()){
opn_spinner.setVisibility(View.GONE);
spnCrd_Options.setVisibility(View.GONE);
}
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getContext(), android.R.layout.simple_spinner_item, atananList);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
opn_spinner.setAdapter(adapter);
}
#RequiresApi(api = Build.VERSION_CODES.O)
public void sendButton() {
System.out.println("1. Bluettoth adapter" + mBluetoothAdapter);
modelClass = new ModelClass();
modelClass.setmBluetoothAdapter(mBluetoothAdapter);
modelClass.setmChatService(mChatService);
modelClass.setmConnectedDeviceName(mConnectedDeviceName);
modelClass.setmOutStringBuffer(mOutStringBuffer);
Intent intent = new Intent(getActivity(), SendCordinates.class);
startActivity(intent);
}
/**
* The Handler that gets information back from the BluetoothChatService
*/
private final Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
FragmentActivity activity = getActivity();
switch (msg.what) {
case Constants.MESSAGE_STATE_CHANGE:
switch (msg.arg1) {
case BluetoothChatService.STATE_CONNECTED:
setStatus(getString(R.string.title_connected_to, mConnectedDeviceName));
//textViewReceived.setText("Received:");
break;
case BluetoothChatService.STATE_CONNECTING:
setStatus(R.string.title_connecting);
break;
case BluetoothChatService.STATE_LISTEN:
case BluetoothChatService.STATE_NONE:
setStatus(R.string.title_not_connected);
break;
}
break;
case Constants.MESSAGE_WRITE:
break;
case Constants.MESSAGE_READ:
byte[] readBuf = (byte[]) msg.obj;
// construct a string from the valid bytes in the buffer
String readMessage = new String(readBuf, 0, msg.arg1);
receiveBuffer += readMessage;
if(receiveBuffer.contains("\n")) {
receiveBuffer = receiveBuffer.substring(0, receiveBuffer.length() - 1);
messageHandler();
receiveBuffer = "";
}
break;
case Constants.MESSAGE_DEVICE_NAME:
// save the connected device's name
mConnectedDeviceName = msg.getData().getString(Constants.DEVICE_NAME);
if (null != activity) {
Toast.makeText(activity, "Connected to "
+ mConnectedDeviceName, Toast.LENGTH_SHORT).show();
}
break;
case Constants.MESSAGE_TOAST:
if (null != activity) {
Toast.makeText(activity, msg.getData().getString(Constants.TOAST),
Toast.LENGTH_SHORT).show();
}
break;
}
}
};
public void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case REQUEST_CONNECT_DEVICE_SECURE:
// When DeviceListActivity returns with a device to connect
if (resultCode == Activity.RESULT_OK) {
connectDevice(data, true);
}
break;
case REQUEST_CONNECT_DEVICE_INSECURE:
// When DeviceListActivity returns with a device to connect
if (resultCode == Activity.RESULT_OK) {
connectDevice(data, false);
}
break;
case REQUEST_ENABLE_BT:
// When the request to enable Bluetooth returns
if (resultCode == Activity.RESULT_OK) {
// Bluetooth is now enabled, so set up a chat session
setupChat();
} else {
// User did not enable Bluetooth or an error occurred
Log.d(TAG, "BT not enabled");
FragmentActivity activity = getActivity();
if (activity != null) {
Toast.makeText(activity, R.string.bt_not_enabled_leaving,
Toast.LENGTH_SHORT).show();
activity.finish();
}
}
}
}
private void connectDevice(Intent data, boolean secure) {
// Get the device MAC address
Bundle extras = data.getExtras();
if (extras == null) {
return;
}
String address = extras.getString(DeviceListActivity.EXTRA_DEVICE_ADDRESS);
// Get the BluetoothDevice object
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
// Attempt to connect to the device
mChatService.connect(device, secure);
}
#Override
public void onCreateOptionsMenu(#NonNull Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.bluetooth_chat, menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.secure_connect_scan: {
// Launch the DeviceListActivity to see devices and do scan
Intent serverIntent = new Intent(getActivity(), DeviceListActivity.class);
startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE_SECURE);
return true;
}
case R.id.discoverable: {
// Ensure this device is discoverable by others
ensureDiscoverable();
return true;
}
}
return false;
}
public class BluetoothChatService {
private static final String TAG = "BluetoothChatService";
private static final String NAME_SECURE = "BluetoothChatSecure";
private static final String NAME_INSECURE = "BluetoothChatInsecure";
private static final UUID MY_UUID_SECURE =
UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
private static final UUID MY_UUID_INSECURE =
UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
// Member fields
private final BluetoothAdapter mAdapter;
private final Handler mHandler;
private AcceptThread mSecureAcceptThread;
private AcceptThread mInsecureAcceptThread;
private ConnectThread mConnectThread;
private ConnectedThread mConnectedThread;
private int mState;
private int mNewState;
public static final int STATE_NONE = 0; // we're doing nothing
public static final int STATE_LISTEN = 1; // now listening for incoming connections
public static final int STATE_CONNECTING = 2; // now initiating an outgoing connection
public static final int STATE_CONNECTED = 3; // now connected to a remote device
public BluetoothChatService(Context context, Handler handler) {
mAdapter = BluetoothAdapter.getDefaultAdapter();
mState = STATE_NONE;
mNewState = mState;
mHandler = handler;
}
private synchronized void updateUserInterfaceTitle() {
mState = getState();
Log.d(TAG, "updateUserInterfaceTitle() " + mNewState + " -> " + mState);
mNewState = mState;
// Give the new state to the Handler so the UI Activity can update
mHandler.obtainMessage(Constants.MESSAGE_STATE_CHANGE, mNewState, -1).sendToTarget();
}
public synchronized int getState() {
return mState;
}
public synchronized void start() {
Log.d(TAG, "start");
// Cancel any thread attempting to make a connection
if (mConnectThread != null) {
mConnectThread.cancel();
mConnectThread = null;
}
// Cancel any thread currently running a connection
if (mConnectedThread != null) {
mConnectedThread.cancel();
mConnectedThread = null;
}
// Start the thread to listen on a BluetoothServerSocket
if (mSecureAcceptThread == null) {
mSecureAcceptThread = new AcceptThread(true);
mSecureAcceptThread.start();
}
if (mInsecureAcceptThread == null) {
mInsecureAcceptThread = new AcceptThread(false);
mInsecureAcceptThread.start();
}
// Update UI title
updateUserInterfaceTitle();
}
public synchronized void connect(BluetoothDevice device, boolean secure) {
Log.d(TAG, "connect to: " + device);
// Cancel any thread attempting to make a connection
if (mState == STATE_CONNECTING) {
if (mConnectThread != null) {
mConnectThread.cancel();
mConnectThread = null;
}
}
if (mConnectedThread != null) {
mConnectedThread.cancel();
mConnectedThread = null;
}
mConnectThread = new ConnectThread(device, secure);
mConnectThread.start();
// Update UI title
updateUserInterfaceTitle();
}
public synchronized void connected(BluetoothSocket socket, BluetoothDevice
device, final String socketType) {
Log.d(TAG, "connected, Socket Type:" + socketType);
// Cancel the thread that completed the connection
if (mConnectThread != null) {
mConnectThread.cancel();
mConnectThread = null;
}
if (mConnectedThread != null) {
mConnectedThread.cancel();
mConnectedThread = null;
}
if (mSecureAcceptThread != null) {
mSecureAcceptThread.cancel();
mSecureAcceptThread = null;
}
if (mInsecureAcceptThread != null) {
mInsecureAcceptThread.cancel();
mInsecureAcceptThread = null;
}
mConnectedThread = new ConnectedThread(socket, socketType);
mConnectedThread.start();
Message msg = mHandler.obtainMessage(Constants.MESSAGE_DEVICE_NAME);
Bundle bundle = new Bundle();
bundle.putString(Constants.DEVICE_NAME, device.getName());
msg.setData(bundle);
mHandler.sendMessage(msg);
// Update UI title
updateUserInterfaceTitle();
}
public synchronized void stop() {
Log.d(TAG, "stop");
if (mConnectThread != null) {
mConnectThread.cancel();
mConnectThread = null;
}
if (mConnectedThread != null) {
mConnectedThread.cancel();
mConnectedThread = null;
}
if (mSecureAcceptThread != null) {
mSecureAcceptThread.cancel();
mSecureAcceptThread = null;
}
if (mInsecureAcceptThread != null) {
mInsecureAcceptThread.cancel();
mInsecureAcceptThread = null;
}
mState = STATE_NONE;
// Update UI title
updateUserInterfaceTitle();
}
public void write(byte[] out) {
// Create temporary object
ConnectedThread r;
// Synchronize a copy of the ConnectedThread
synchronized (this) {
if (mState != STATE_CONNECTED) return;
r = mConnectedThread;
}
// Perform the write unsynchronized
r.write(out);
}
private void connectionFailed() {
// Send a failure message back to the Activity
Message msg = mHandler.obtainMessage(Constants.MESSAGE_TOAST);
Bundle bundle = new Bundle();
bundle.putString(Constants.TOAST, "Unable to connect device");
msg.setData(bundle);
mHandler.sendMessage(msg);
mState = STATE_NONE;
// Update UI title
updateUserInterfaceTitle();
// Start the service over to restart listening mode
BluetoothChatService.this.start();
}
private void connectionLost() {
// Send a failure message back to the Activity
Message msg = mHandler.obtainMessage(Constants.MESSAGE_TOAST);
Bundle bundle = new Bundle();
bundle.putString(Constants.TOAST, "Device connection was lost");
msg.setData(bundle);
mHandler.sendMessage(msg);
mState = STATE_NONE;
// Update UI title
updateUserInterfaceTitle();
// Start the service over to restart listening mode
BluetoothChatService.this.start();
}
private class AcceptThread extends Thread {
// The local server socket
private final BluetoothServerSocket mmServerSocket;
private String mSocketType;
public AcceptThread(boolean secure) {
BluetoothServerSocket tmp = null;
mSocketType = secure ? "Secure" : "Insecure";
try {
if (secure) {
tmp = mAdapter.listenUsingRfcommWithServiceRecord(NAME_SECURE,
MY_UUID_SECURE);
} else {
tmp = mAdapter.listenUsingInsecureRfcommWithServiceRecord(
NAME_INSECURE, MY_UUID_INSECURE);
}
} catch (IOException e) {
Log.e(TAG, "Socket Type: " + mSocketType + "listen() failed", e);
}
mmServerSocket = tmp;
mState = STATE_LISTEN;
}
public void run() {
Log.d(TAG, "Socket Type: " + mSocketType +
"BEGIN mAcceptThread" + this);
setName("AcceptThread" + mSocketType);
BluetoothSocket socket;
while (mState != STATE_CONNECTED) {
try {
// This is a blocking call and will only return on a
// successful connection or an exception
socket = mmServerSocket.accept();
} catch (IOException e) {
Log.e(TAG, "Socket Type: " + mSocketType + "accept() failed", e);
break;
}
if (socket != null) {
synchronized (BluetoothChatService.this) {
switch (mState) {
case STATE_LISTEN:
case STATE_CONNECTING:
// Situation normal. Start the connected thread.
connected(socket, socket.getRemoteDevice(),
mSocketType);
break;
case STATE_NONE:
case STATE_CONNECTED:
// Either not ready or already connected. Terminate new socket.
try {
socket.close();
} catch (IOException e) {
Log.e(TAG, "Could not close unwanted socket", e);
}
break;
}
}
}
}
Log.i(TAG, "END mAcceptThread, socket Type: " + mSocketType);
}
public void cancel() {
Log.d(TAG, "Socket Type" + mSocketType + "cancel " + this);
try {
mmServerSocket.close();
} catch (IOException e) {
Log.e(TAG, "Socket Type" + mSocketType + "close() of server failed", e);
}
}
}
private class ConnectThread extends Thread {
private final BluetoothSocket mmSocket;
private final BluetoothDevice mmDevice;
private String mSocketType;
public ConnectThread(BluetoothDevice device, boolean secure) {
mmDevice = device;
BluetoothSocket tmp = null;
mSocketType = secure ? "Secure" : "Insecure";
try {
if (secure) {
tmp = device.createRfcommSocketToServiceRecord(
MY_UUID_SECURE);
} else {
tmp = device.createInsecureRfcommSocketToServiceRecord(
MY_UUID_INSECURE);
}
} catch (IOException e) {
Log.e(TAG, "Socket Type: " + mSocketType + "create() failed", e);
}
mmSocket = tmp;
mState = STATE_CONNECTING;
}
public void run() {
Log.i(TAG, "BEGIN mConnectThread SocketType:" + mSocketType);
setName("ConnectThread" + mSocketType);
// Always cancel discovery because it will slow down a connection
mAdapter.cancelDiscovery();
// Make a connection to the BluetoothSocket
try {
// This is a blocking call and will only return on a
// successful connection or an exception
mmSocket.connect();
} catch (IOException e) {
// Close the socket
try {
mmSocket.close();
} catch (IOException e2) {
Log.e(TAG, "unable to close() " + mSocketType +
" socket during connection failure", e2);
}
connectionFailed();
return;
}
synchronized (BluetoothChatService.this) {
mConnectThread = null;
}
// Start the connected thread
connected(mmSocket, mmDevice, mSocketType);
}
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) {
Log.e(TAG, "close() of connect " + mSocketType + " socket failed", e);
}
}
}
/**
* This thread runs during a connection with a remote device.
* It handles all incoming and outgoing transmissions.
*/
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
public ConnectedThread(BluetoothSocket socket, String socketType) {
Log.d(TAG, "create ConnectedThread: " + socketType);
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
// Get the BluetoothSocket input and output streams
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) {
Log.e(TAG, "temp sockets not created", e);
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
mState = STATE_CONNECTED;
}
public void run() {
Log.i(TAG, "BEGIN mConnectedThread");
byte[] buffer = new byte[1024];
int bytes;
// Keep listening to the InputStream while connected
while (mState == STATE_CONNECTED) {
try {
// Read from the InputStream
bytes = mmInStream.read(buffer);
// Send the obtained bytes to the UI Activity
mHandler.obtainMessage(Constants.MESSAGE_READ, bytes, -1, buffer)
.sendToTarget();
} catch (IOException e) {
Log.e(TAG, "disconnected", e);
connectionLost();
break;
}
}
}
/**
* Write to the connected OutStream.
*
* #param buffer The bytes to write
*/
public void write(byte[] buffer) {
try {
mmOutStream.write(buffer);
// Share the sent message back to the UI Activity
mHandler.obtainMessage(Constants.MESSAGE_WRITE, -1, -1, buffer)
.sendToTarget();
} catch (IOException e) {
Log.e(TAG, "Exception during write", e);
}
}
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) {
Log.e(TAG, "close() of connect socket failed", e);
}
}
}
Create an actual service which can be bound from multiple activities.
class BluetoothService : Service() {
private val binder = LocalBinder()
override fun onBind(intent: Intent): IBinder? {
return binder
}
inner class LocalBinder : Binder() {
fun getService() : BluetoothService {
return this#BluetoothService
}
}
}
private var bluetoothService : BluetoothService? = null
private val serviceConnection: ServiceConnection = object : ServiceConnection {
override fun onServiceConnected(componentName: ComponentName, service:IBinder) {
bluetoothService = (service as LocalBinder).getService()
bluetoothService?.let { bluetooth ->
// ...
}
}
override fun onServiceDisconnected(componentName: ComponentName) {
bluetoothService = null
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val serviceIntent = Intent(this, BluetootService::class.java)
bindService(serviceIntent, serviceConnection, Context.BIND_AUTO_CREATE)
}
See BLE case for the inspiration.
Have you ever tried to use something like dagger? You can create a repository that you istantiate at the start of application.
Then if you need to use it in activity you can inject it with something like this:
#Inject lateinit var bluetoothRepository: BluetoothRepository
My Application contains 3 Activities -
MainActivity.java
Write.java
BluetoothConnectionService.java
BluetoothConnectionService.java
public class BluetoothConnectionService {
private static final String TAG = "BluetoothConnectionServ";
private static final String appName = "MYAPP";
private static final UUID MY_UUID_INSECURE =
UUID.fromString("8ce255c0-200a-11e0-ac64-0800200c9a66");
private final BluetoothAdapter mBluetoothAdapter;
Context mContext;
private AcceptThread mInsecureAcceptThread;
private ConnectThread mConnectThread;
private BluetoothDevice mmDevice;
private UUID deviceUUID;
ProgressDialog mProgressDialog;
private ConnectedThread mConnectedThread;
public BluetoothConnectionService(Context context) {
mContext = context;
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
//start();
}
/**
* This thread runs while listening for incoming connections. It behaves
* like a server-side client. It runs until a connection is accepted
* (or until cancelled).
*/
private class AcceptThread extends Thread {
// The local server socket
private final BluetoothServerSocket mmServerSocket;
public AcceptThread(){
BluetoothServerSocket tmp = null;
// Create a new listening server socket
try{
tmp = mBluetoothAdapter.listenUsingInsecureRfcommWithServiceRecord(appName, MY_UUID_INSECURE);
Log.d(TAG, "AcceptThread: Setting up Server using: " + MY_UUID_INSECURE);
}catch (IOException e){
Log.e(TAG, "AcceptThread: IOException: " + e.getMessage() );
}
mmServerSocket = tmp;
}
public void run(){
Log.d(TAG, "run: AcceptThread Running.");
BluetoothSocket socket = null;
try{
// This is a blocking call and will only return on a
// successful connection or an exception
Log.d(TAG, "run: RFCOM server socket start.....");
socket = mmServerSocket.accept();
Log.d(TAG, "run: RFCOM server socket accepted connection.");
}catch (IOException e){
Log.e(TAG, "AcceptThread: IOException: " + e.getMessage() );
}
if(socket != null){
connected(socket,mmDevice);
}
Log.i(TAG, "END mAcceptThread ");
}
public void cancel() {
Log.d(TAG, "cancel: Canceling AcceptThread.");
try {
mmServerSocket.close();
} catch (IOException e) {
Log.e(TAG, "cancel: Close of AcceptThread ServerSocket failed. " + e.getMessage() );
}
}
}
/**
* This thread runs while attempting to make an outgoing connection
* with a device. It runs straight through; the connection either
* succeeds or fails.
*/
private class ConnectThread extends Thread {
private BluetoothSocket mmSocket;
public ConnectThread(BluetoothDevice device, UUID uuid) {
Log.d(TAG, "ConnectThread: started.");
mmDevice = device;
deviceUUID = uuid;
}
public void run(){
BluetoothSocket tmp = null;
Log.i(TAG, "RUN mConnectThread ");
// Get a BluetoothSocket for a connection with the
// given BluetoothDevice
try {
Log.d(TAG, "ConnectThread: Trying to create InsecureRfcommSocket using UUID: "
+MY_UUID_INSECURE );
tmp = mmDevice.createRfcommSocketToServiceRecord(deviceUUID);
} catch (IOException e) {
Log.e(TAG, "ConnectThread: Could not create InsecureRfcommSocket " + e.getMessage());
}
mmSocket = tmp;
// Always cancel discovery because it will slow down a connection
mBluetoothAdapter.cancelDiscovery();
// Make a connection to the BluetoothSocket
try {
// This is a blocking call and will only return on a
// successful connection or an exception
mmSocket.connect();
Log.d(TAG, "run: ConnectThread connected.");
//mProgressDialog.cancel();
//Toast.makeText(mContext,"Connected", Toast.LENGTH_SHORT).show();
} catch (IOException e) {
// Close the socket
try {
mmSocket.close();
Log.d(TAG, "run: Closed Socket.");
} catch (IOException e1) {
Log.e(TAG, "mConnectThread: run: Unable to close connection in socket " + e1.getMessage());
}
Log.d(TAG, "run: ConnectThread: Could not connect to UUID: " + MY_UUID_INSECURE );
}
connected(mmSocket,mmDevice);
}
public void cancel() {
try {
Log.d(TAG, "cancel: Closing Client Socket.");
mmSocket.close();
} catch (IOException e) {
Log.e(TAG, "cancel: close() of mmSocket in Connectthread failed. " + e.getMessage());
}
}
}
private void connected(BluetoothSocket mmSocket, BluetoothDevice mmDevice) {
Log.d(TAG, "connected: Starting.");
// Start the thread to manage the connection and perform transmissions
mConnectedThread = new ConnectedThread(mmSocket);
mConnectedThread.start();
//start new activity
Intent intent = new Intent(mContext, Write.class);
mContext.startActivity(intent);
}
/**
Finally the ConnectedThread which is responsible for maintaining the BTConnection, Sending the data, and
receiving incoming data through input/output streams respectively.
**/
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
public ConnectedThread(BluetoothSocket socket) {
Log.d(TAG, "ConnectedThread: Starting.");
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
//dismiss the progress dialog when connection is established
try{
mProgressDialog.dismiss();
}catch (NullPointerException e){
e.printStackTrace();
}
try {
tmpIn = mmSocket.getInputStream();
tmpOut = mmSocket.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run(){
byte[] buffer = new byte[1024]; // buffer store for the stream
int bytes; // bytes returned from read()
// Keep listening to the InputStream until an exception occurs
while (true) {
// Read from the InputStream
try {
bytes = mmInStream.read(buffer);
String incomingMessage = new String(buffer, 0, bytes);
Log.d(TAG, "InputStream: " + incomingMessage);
Intent incomingMessageIntent = new Intent("incomingMessage");
incomingMessageIntent.putExtra("theMessage", incomingMessage);
LocalBroadcastManager.getInstance(mContext).sendBroadcast(incomingMessageIntent);
Log.d(TAG, "broadcast sent");
} catch (IOException e) {
Log.e(TAG, "write: Error reading Input Stream. " + e.getMessage() );
break;
}
}
}
//Call this from the main activity to send data to the remote device
/*public void write(byte[] bytes) {
String text = new String(bytes, Charset.defaultCharset());
Log.d(TAG, "write: Writing to outputstream: " + text);
try {
mmOutStream.write(bytes);
} catch (IOException e) {
Log.e(TAG, "write: Error writing to output stream. " + e.getMessage() );
}
}*/
public void write(String input) {
byte[] msgBuffer = input.getBytes(); //converts entered String into bytes
try {
mmOutStream.write(msgBuffer); //write bytes over BT connection via outstream
} catch (IOException e) {
//if you cannot write, close the application
Toast.makeText(mContext, "Connection Failure", Toast.LENGTH_LONG).show();
}
}
/* Call this from the main activity to shutdown the connection */
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) { }
}
}
public void start() {
Log.d(TAG, "start");
// Cancel any thread attempting to make a connection
if (mConnectThread != null) {
mConnectThread.cancel();
mConnectThread = null;
}
if (mInsecureAcceptThread == null) {
mInsecureAcceptThread = new AcceptThread();
mInsecureAcceptThread.start();
}
}
public void startClient(BluetoothDevice device,UUID uuid){
Log.d(TAG, "startClient: Started.");
//init progress dialog
mProgressDialog = ProgressDialog.show(mContext,"Connecting Bluetooth"
,"Please Wait...",true);
mConnectThread = new ConnectThread(device, uuid);
mConnectThread.start();
}
/**
* Write to the ConnectedThread in an unsynchronized manner
*
*/
public void write() {
// Create temporary object
//ConnectedThread r;
// Synchronize a copy of the ConnectedThread
Log.d(TAG, "write: Write Called.");
//perform the write
mConnectedThread.write("1");
}
}
PROBLEM:-
From the MainActivity, I created a BluetoothConnectionService object
BluetoothConnectionService mBluetoothConnection = new BluetoothConnectionService(MainActivity.this);
Then, I called startClient(device,uuid) method on mBluetoothConnection object
mBluetoothConnection.startClient(device,uuid);
Now, after successful connection is made, I can send out data to other devices by calling write() from the MainActivity
mBluetoothConnection.write();
But I don't want to send out data from MainActivity instead I want to use Write activity to send data out. How can I do that?
The Code you are using is provided by google Bluetooth chat application and they write using this:
In your Activity
private void sendMessage(String message) {
// Check that we're actually connected before trying anything
if (bluetoothConnectionService.getState() != BluetoothConnectionService.STATE_CONNECTED) {
Toast.makeText(MainActivity.this, R.string.not_connected, Toast.LENGTH_SHORT).show();
return;
}
// Check that there's actually something to send
if (message.length() > 0) {
// Get the message bytes and tell the BluetoothConnectionService to write
byte[] send = message.getBytes();
bluetoothConnectionService.write(send);
// Reset out string buffer to zero and clear the edit text field
mOutStringBuffer.setLength(0);
}
}
In the service add these two methods
/**
* Write to the ConnectedThread in an unsynchronized manner
*
* #param out The bytes to write
* #see ConnectedThread#write(byte[])
*/
public void write(byte[] out) {
// Create temporary object
ConnectedThread r;
// Synchronize a copy of the ConnectedThread
synchronized (this) {
if (mState != STATE_CONNECTED) return;
r = mConnectedThread;
}
// Perform the write unsynchronized
r.write(out);
}
/**
* Write to the connected OutStream.
*
* #param buffer The bytes to write
*/
public void write(byte[] buffer) {
try {
mmOutStream.write(buffer);
// Share the sent message back to the UI Activity
mHandler.obtainMessage(Constants.MESSAGE_WRITE, -1, -1, buffer)
.sendToTarget();
} catch (IOException e) {
Log.e(TAG, "Exception during write", e);
}
}
Am having great issues with building a client server model for my Bluetooth application. I run my Bluetooth server application on a mobile. Here is the code for that:
public class BlueSer extends Activity {
/** Called when the activity is first created. */
private BluetoothAdapter mBluetoothAdapter = null;
private static final UUID MY_UUID =
UUID.fromString("fa87c0d0-afac-11de-8a39-0800200c9a66");
private byte[] buffer = new byte[8192];
private ImageView image;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.blueserv);
image = (ImageView) findViewById(R.id.imageView1);
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter == null) {
Toast.makeText(this,
"Bluetooth is not available.",
Toast.LENGTH_LONG).show();
finish();
return;
}
if (!mBluetoothAdapter.isEnabled()) {
Toast.makeText(this,
"Please enable your BT and re-run this program.",
Toast.LENGTH_LONG).show();
finish();
return;
}
Log.w("Thread Started: ", "Thread ka start hai jani");
AcceptData acceptData = new AcceptData();
acceptData.start();
Bitmap bm1 = BitmapFactory.decodeByteArray(buffer, 0, buffer.length);
image.setImageBitmap(bm1);
}
class AcceptData extends Thread{
private final BluetoothServerSocket mmServerSocket;
private BluetoothSocket socket = null;
private InputStream mmInStream;
private String device;
public AcceptData() {
BluetoothServerSocket tmp = null;
try {
tmp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord("Bluetooth", MY_UUID);
} catch (IOException e) {
Log.w("Display Hona Chahye", "Kr dia na display Rami");
//
}
mmServerSocket = tmp;
try {
socket = mmServerSocket.accept();
} catch (IOException e) {
//
}
Log.w("iudfghiue", "yaiiii");
device = socket.getRemoteDevice().getName();
Toast.makeText(getBaseContext(), "Connected to " + device, Toast.LENGTH_SHORT).show();
InputStream tmpIn = null;
try {
tmpIn = socket.getInputStream();
} catch (IOException e) {
//
}
mmInStream = tmpIn;
int byteNo;
try {
byteNo = mmInStream.read(buffer);
if (byteNo != -1) {
//ensure DATAMAXSIZE Byte is read.
int byteNo2 = byteNo;
int bufferSize = 7340;
while(byteNo2 != bufferSize){
bufferSize = bufferSize - byteNo2;
byteNo2 = mmInStream.read(buffer,byteNo,bufferSize);
if(byteNo2 == -1){
break;
}
byteNo = byteNo+byteNo2;
}
}
if (socket != null) {
try {
mmServerSocket.close();
} catch (IOException e) {
//
}
}
}
catch (Exception e) {
// TODO: handle exception
}
}
}
}
The logcat is as follows:
12-23 01:32:34.292: D/ServiceManager(1264): The name of the service is bluetooth
12-23 01:32:34.293: W/Thread Started:(1264): Thread ka start hai jani
12-23 01:32:34.294: I/BluetoothSocket_MTK(1264): [JSR82] Bluetooth Socket Constructor
12-23 01:32:34.294: I/BluetoothSocket_MTK(1264): [JSR82] type=1 fd=-1 auth=true encrypt=true port=4
12-23 01:32:34.294: D/ServiceManager(1264): The name of the service is bluetooth_socket
**12-23 01:32:34.295: I/BluetoothSocket_MTK(1264): [JSR82] bindListen
12-23 01:32:34.296: D/BluetoothSocket_MTK(1264): [JSR82] bindListen: bindListen() failed.
12-23 01:32:34.298: I/BluetoothSocket_MTK(1264): [JSR82] accept().
12-23 01:32:34.299: I/BluetoothSocket_MTK(1264): [JSR82] accept: Connection is not created.**
12-23 01:32:34.299: W/iudfghiue(1264): yaiiii
12-23 01:32:34.299: D/AndroidRuntime(1264): Shutting down VM
12-23 01:32:34.299: W/dalvikvm(1264): threadid=1: thread exiting with uncaught exception (group=0x413ad9a8)
12-23 01:32:34.305: E/AndroidRuntime(1264): FATAL EXCEPTION: main
12-23 01:32:34.305: E/AndroidRuntime(1264): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.BlueSer/com.example.blueserv.BlueSer}: java.lang.NullPointerException
12-23 01:32:34.305: E/AndroidRuntime(1264): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2313)
12-23 01:32:34.305: E/AndroidRuntime(1264): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2365)
12-23 01:32:34.305: E/AndroidRuntime(1264): at android.app.ActivityThread.access$600(ActivityThread.java:156)
12-23 01:32:34.305: E/AndroidRuntime(1264): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
12-23 01:32:34.305: E/AndroidRuntime(1264): at android.os.Handler.dispatchMessage(Handler.java:99)
12-23 01:32:34.305: E/AndroidRuntime(1264): at android.os.Looper.loop(Looper.java:153)
12-23 01:32:34.305: E/AndroidRuntime(1264): at android.app.ActivityThread.main(ActivityThread.java:5336)
12-23 01:32:34.305: E/AndroidRuntime(1264): at java.lang.reflect.Method.invokeNative(Native Method)
12-23 01:32:34.305: E/AndroidRuntime(1264): at java.lang.reflect.Method.invoke(Method.java:511)
12-23 01:32:34.305: E/AndroidRuntime(1264): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:833)
Now if I focus at the logcat my program is throwing exception because it is not able to listen to some device. I have already paired that device with the other android device. Just cannot figure out what is the issue. Please help. These seem to be the troubling lines of the code:
tmp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord("Bluetooth", MY_UUID);
} catch (IOException e) {
Log.w("Display Hona Chahye", "Kr dia na display Rami");
//
}
mmServerSocket = tmp;
try {
socket = mmServerSocket.accept();
Where I have kept the UUID's string same in both the client and server code!
This works for me
Or you can reference this library for more details about the flow
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import com.example.android.common.logger.Log;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.UUID;
/**
* This class does all the work for setting up and managing Bluetooth
* connections with other devices. It has a thread that listens for
* incoming connections, a thread for connecting with a device, and a
* thread for performing data transmissions when connected.
*/
public class BluetoothChatService {
// Debugging
private static final String TAG = "BluetoothChatService";
// Name for the SDP record when creating server socket
private static final String NAME_SECURE = "BluetoothChatSecure";
private static final String NAME_INSECURE = "BluetoothChatInsecure";
// Unique UUID for this application
private static final UUID MY_UUID_SECURE =
UUID.fromString("fa87c0d0-afac-11de-8a39-0800200c9a66");
private static final UUID MY_UUID_INSECURE =
UUID.fromString("8ce255c0-200a-11e0-ac64-0800200c9a66");
// Member fields
private final BluetoothAdapter mAdapter;
private final Handler mHandler;
private AcceptThread mSecureAcceptThread;
private AcceptThread mInsecureAcceptThread;
private ConnectThread mConnectThread;
private ConnectedThread mConnectedThread;
private int mState;
// Constants that indicate the current connection state
public static final int STATE_NONE = 0; // we're doing nothing
public static final int STATE_LISTEN = 1; // now listening for incoming connections
public static final int STATE_CONNECTING = 2; // now initiating an outgoing connection
public static final int STATE_CONNECTED = 3; // now connected to a remote device
/**
* Constructor. Prepares a new BluetoothChat session.
*
* #param context The UI Activity Context
* #param handler A Handler to send messages back to the UI Activity
*/
public BluetoothChatService(Context context, Handler handler) {
mAdapter = BluetoothAdapter.getDefaultAdapter();
mState = STATE_NONE;
mHandler = handler;
}
/**
* Set the current state of the chat connection
*
* #param state An integer defining the current connection state
*/
private synchronized void setState(int state) {
Log.d(TAG, "setState() " + mState + " -> " + state);
mState = state;
// Give the new state to the Handler so the UI Activity can update
mHandler.obtainMessage(Constants.MESSAGE_STATE_CHANGE, state, -1).sendToTarget();
}
/**
* Return the current connection state.
*/
public synchronized int getState() {
return mState;
}
/**
* Start the chat service. Specifically start AcceptThread to begin a
* session in listening (server) mode. Called by the Activity onResume()
*/
public synchronized void start() {
Log.d(TAG, "start");
// Cancel any thread attempting to make a connection
if (mConnectThread != null) {
mConnectThread.cancel();
mConnectThread = null;
}
// Cancel any thread currently running a connection
if (mConnectedThread != null) {
mConnectedThread.cancel();
mConnectedThread = null;
}
setState(STATE_LISTEN);
// Start the thread to listen on a BluetoothServerSocket
if (mSecureAcceptThread == null) {
mSecureAcceptThread = new AcceptThread(true);
mSecureAcceptThread.start();
}
if (mInsecureAcceptThread == null) {
mInsecureAcceptThread = new AcceptThread(false);
mInsecureAcceptThread.start();
}
}
/**
* Start the ConnectThread to initiate a connection to a remote device.
*
* #param device The BluetoothDevice to connect
* #param secure Socket Security type - Secure (true) , Insecure (false)
*/
public synchronized void connect(BluetoothDevice device, boolean secure) {
Log.d(TAG, "connect to: " + device);
// Cancel any thread attempting to make a connection
if (mState == STATE_CONNECTING) {
if (mConnectThread != null) {
mConnectThread.cancel();
mConnectThread = null;
}
}
// Cancel any thread currently running a connection
if (mConnectedThread != null) {
mConnectedThread.cancel();
mConnectedThread = null;
}
// Start the thread to connect with the given device
mConnectThread = new ConnectThread(device, secure);
mConnectThread.start();
setState(STATE_CONNECTING);
}
/**
* Start the ConnectedThread to begin managing a Bluetooth connection
*
* #param socket The BluetoothSocket on which the connection was made
* #param device The BluetoothDevice that has been connected
*/
public synchronized void connected(BluetoothSocket socket, BluetoothDevice
device, final String socketType) {
Log.d(TAG, "connected, Socket Type:" + socketType);
// Cancel the thread that completed the connection
if (mConnectThread != null) {
mConnectThread.cancel();
mConnectThread = null;
}
// Cancel any thread currently running a connection
if (mConnectedThread != null) {
mConnectedThread.cancel();
mConnectedThread = null;
}
// Cancel the accept thread because we only want to connect to one device
if (mSecureAcceptThread != null) {
mSecureAcceptThread.cancel();
mSecureAcceptThread = null;
}
if (mInsecureAcceptThread != null) {
mInsecureAcceptThread.cancel();
mInsecureAcceptThread = null;
}
// Start the thread to manage the connection and perform transmissions
mConnectedThread = new ConnectedThread(socket, socketType);
mConnectedThread.start();
// Send the name of the connected device back to the UI Activity
Message msg = mHandler.obtainMessage(Constants.MESSAGE_DEVICE_NAME);
Bundle bundle = new Bundle();
bundle.putString(Constants.DEVICE_NAME, device.getName());
msg.setData(bundle);
mHandler.sendMessage(msg);
setState(STATE_CONNECTED);
}
/**
* Stop all threads
*/
public synchronized void stop() {
Log.d(TAG, "stop");
if (mConnectThread != null) {
mConnectThread.cancel();
mConnectThread = null;
}
if (mConnectedThread != null) {
mConnectedThread.cancel();
mConnectedThread = null;
}
if (mSecureAcceptThread != null) {
mSecureAcceptThread.cancel();
mSecureAcceptThread = null;
}
if (mInsecureAcceptThread != null) {
mInsecureAcceptThread.cancel();
mInsecureAcceptThread = null;
}
setState(STATE_NONE);
}
/**
* Write to the ConnectedThread in an unsynchronized manner
*
* #param out The bytes to write
* #see ConnectedThread#write(byte[])
*/
public void write(byte[] out) {
// Create temporary object
ConnectedThread r;
// Synchronize a copy of the ConnectedThread
synchronized (this) {
if (mState != STATE_CONNECTED) return;
r = mConnectedThread;
}
// Perform the write unsynchronized
r.write(out);
}
/**
* Indicate that the connection attempt failed and notify the UI Activity.
*/
private void connectionFailed() {
// Send a failure message back to the Activity
Message msg = mHandler.obtainMessage(Constants.MESSAGE_TOAST);
Bundle bundle = new Bundle();
bundle.putString(Constants.TOAST, "Unable to connect device");
msg.setData(bundle);
mHandler.sendMessage(msg);
// Start the service over to restart listening mode
BluetoothChatService.this.start();
}
/**
* Indicate that the connection was lost and notify the UI Activity.
*/
private void connectionLost() {
// Send a failure message back to the Activity
Message msg = mHandler.obtainMessage(Constants.MESSAGE_TOAST);
Bundle bundle = new Bundle();
bundle.putString(Constants.TOAST, "Device connection was lost");
msg.setData(bundle);
mHandler.sendMessage(msg);
// Start the service over to restart listening mode
BluetoothChatService.this.start();
}
/**
* This thread runs while listening for incoming connections. It behaves
* like a server-side client. It runs until a connection is accepted
* (or until cancelled).
*/
private class AcceptThread extends Thread {
// The local server socket
private final BluetoothServerSocket mmServerSocket;
private String mSocketType;
public AcceptThread(boolean secure) {
BluetoothServerSocket tmp = null;
mSocketType = secure ? "Secure" : "Insecure";
// Create a new listening server socket
try {
if (secure) {
tmp = mAdapter.listenUsingRfcommWithServiceRecord(NAME_SECURE,
MY_UUID_SECURE);
} else {
tmp = mAdapter.listenUsingInsecureRfcommWithServiceRecord(
NAME_INSECURE, MY_UUID_INSECURE);
}
} catch (IOException e) {
Log.e(TAG, "Socket Type: " + mSocketType + "listen() failed", e);
}
mmServerSocket = tmp;
}
public void run() {
Log.d(TAG, "Socket Type: " + mSocketType +
"BEGIN mAcceptThread" + this);
setName("AcceptThread" + mSocketType);
BluetoothSocket socket = null;
// Listen to the server socket if we're not connected
while (mState != STATE_CONNECTED) {
try {
// This is a blocking call and will only return on a
// successful connection or an exception
socket = mmServerSocket.accept();
} catch (IOException e) {
Log.e(TAG, "Socket Type: " + mSocketType + "accept() failed", e);
break;
}
// If a connection was accepted
if (socket != null) {
synchronized (BluetoothChatService.this) {
switch (mState) {
case STATE_LISTEN:
case STATE_CONNECTING:
// Situation normal. Start the connected thread.
connected(socket, socket.getRemoteDevice(),
mSocketType);
break;
case STATE_NONE:
case STATE_CONNECTED:
// Either not ready or already connected. Terminate new socket.
try {
socket.close();
} catch (IOException e) {
Log.e(TAG, "Could not close unwanted socket", e);
}
break;
}
}
}
}
Log.i(TAG, "END mAcceptThread, socket Type: " + mSocketType);
}
public void cancel() {
Log.d(TAG, "Socket Type" + mSocketType + "cancel " + this);
try {
mmServerSocket.close();
} catch (IOException e) {
Log.e(TAG, "Socket Type" + mSocketType + "close() of server failed", e);
}
}
}
/**
* This thread runs while attempting to make an outgoing connection
* with a device. It runs straight through; the connection either
* succeeds or fails.
*/
private class ConnectThread extends Thread {
private final BluetoothSocket mmSocket;
private final BluetoothDevice mmDevice;
private String mSocketType;
public ConnectThread(BluetoothDevice device, boolean secure) {
mmDevice = device;
BluetoothSocket tmp = null;
mSocketType = secure ? "Secure" : "Insecure";
// Get a BluetoothSocket for a connection with the
// given BluetoothDevice
try {
if (secure) {
tmp = device.createRfcommSocketToServiceRecord(
MY_UUID_SECURE);
} else {
tmp = device.createInsecureRfcommSocketToServiceRecord(
MY_UUID_INSECURE);
}
} catch (IOException e) {
Log.e(TAG, "Socket Type: " + mSocketType + "create() failed", e);
}
mmSocket = tmp;
}
public void run() {
Log.i(TAG, "BEGIN mConnectThread SocketType:" + mSocketType);
setName("ConnectThread" + mSocketType);
// Always cancel discovery because it will slow down a connection
mAdapter.cancelDiscovery();
// Make a connection to the BluetoothSocket
try {
// This is a blocking call and will only return on a
// successful connection or an exception
mmSocket.connect();
} catch (IOException e) {
// Close the socket
try {
mmSocket.close();
} catch (IOException e2) {
Log.e(TAG, "unable to close() " + mSocketType +
" socket during connection failure", e2);
}
connectionFailed();
return;
}
// Reset the ConnectThread because we're done
synchronized (BluetoothChatService.this) {
mConnectThread = null;
}
// Start the connected thread
connected(mmSocket, mmDevice, mSocketType);
}
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) {
Log.e(TAG, "close() of connect " + mSocketType + " socket failed", e);
}
}
}
/**
* This thread runs during a connection with a remote device.
* It handles all incoming and outgoing transmissions.
*/
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
public ConnectedThread(BluetoothSocket socket, String socketType) {
Log.d(TAG, "create ConnectedThread: " + socketType);
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
// Get the BluetoothSocket input and output streams
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) {
Log.e(TAG, "temp sockets not created", e);
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run() {
Log.i(TAG, "BEGIN mConnectedThread");
byte[] buffer = new byte[1024];
int bytes;
// Keep listening to the InputStream while connected
while (true) {
try {
// Read from the InputStream
bytes = mmInStream.read(buffer);
// Send the obtained bytes to the UI Activity
mHandler.obtainMessage(Constants.MESSAGE_READ, bytes, -1, buffer)
.sendToTarget();
} catch (IOException e) {
Log.e(TAG, "disconnected", e);
connectionLost();
// Start the service over to restart listening mode
BluetoothChatService.this.start();
break;
}
}
}
/**
* Write to the connected OutStream.
*
* #param buffer The bytes to write
*/
public void write(byte[] buffer) {
try {
mmOutStream.write(buffer);
// Share the sent message back to the UI Activity
mHandler.obtainMessage(Constants.MESSAGE_WRITE, -1, -1, buffer)
.sendToTarget();
} catch (IOException e) {
Log.e(TAG, "Exception during write", e);
}
}
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) {
Log.e(TAG, "close() of connect socket failed", e);
}
}
}
}
I am working on a project which makes use of an android tablet(iball 3G 7271) that runs on 4.1.2 and is made of MTK processor AND an RN42 bluetooth (chip on a PCB).These two modules communicate with each other to transfer data among them via bluetooth.
I am facing issues.wherein at certain instances I repeatedly get exceptions stating 'Connection is not created (failed or aborted)'.I have found the instances as described below:
I copied the relevant code from the BlueTerm app(from playstore) and made a sample app to test BT connectivity.Blueterm is an app to test bluetooth connectivity between a device and RN42.
1) I Connected/disconnected the app to RN42,and found that it was working all the time.Proper connection and disconnection was happening.
2) I Simulated power failure(by switching off just the RN42 module),I then disconnected & reconnected the BT connection between app and RN42 & found that the tablet was getting re-connected with RN42 without much issue.
3) Link between re-installation of the app and BT connectivity to the RN42
Test case 1:Before re-installation, the app was disconnected from RN42 ; result- after re-installation BT reconnection to RN42 in the re installed app works fine.
Test case 2:Before re-installation the app was in connected state to RN42;result- after re-installation BT reconnection to RN42 doesnt happen.
I traced that the exception that comes for Test case 2 is :
W/System.err(4603): java.io.IOException: [JSR82] connect: Connection is not created (failed or aborted).
W/System.err(4603): at android.bluetooth.BluetoothSocket.connect(BluetoothSocket.java:395)
This was the exception I was getting again and again few days back.So now I kinda know when this exception can get thrown.
NOTE: For 'Test case2' ,here even un-installing and re-installing the app and then trying to connect app to RN42 doesnt work.We need to reboot the tablet to make the app connect to BT again.Moreover,I even tried connecting the real BlueTerm app(in test case 2),but it also did not get connected.So then I tried switching OFF and ON the tablet's BT.I observed that by switching off and then switching ON the BT and then trying to establish BT connection between tablet and RN42 was happening .But now, I was not getting any input signals from RN42 to tablet,but was able to just send data from tablet to RN42.
Tesing on Samsung S2/grand/nexus devices:
For the above Test case2,on these devices the app does get connected to BT after re-installation,even if it was/was not connected to RN42 via BT prior to re-installation.
Below is the code of my app and the log cat exception:
BlueTerm.java
#SuppressLint("HandlerLeak")
public class BlueTerm extends Activity {
BluetoothSocket Socket;
OutputStream DataOut;
InputStream DataIn;
// Intent request codes
private static final int REQUEST_CONNECT_DEVICE = 1;
private static final int REQUEST_ENABLE_BT = 2;
private static TextView mTitle;
// Name of the connected device
private String mConnectedDeviceName = null;
/**
* Set to true to add debugging code and logging.
*/
public static final boolean DEBUG = true;
/**
* Set to true to log each character received from the remote process to the
* android log, which makes it easier to debug some kinds of problems with
* emulating escape sequences and control codes.
*/
public static final boolean LOG_CHARACTERS_FLAG = DEBUG && false;
/**
* Set to true to log unknown escape sequences.
*/
public static final boolean LOG_UNKNOWN_ESCAPE_SEQUENCES = DEBUG && false;
/**
* The tag we use when logging, so that our messages can be distinguished
* from other messages in the log. Public because it's used by several
* classes.
*/
public static final String LOG_TAG = "BlueTerm";
// Message types sent from the BluetoothReadService Handler
public static final int MESSAGE_STATE_CHANGE = 1;
public static final int MESSAGE_READ = 2;
public static final int MESSAGE_WRITE = 3;
public static final int MESSAGE_DEVICE_NAME = 4;
public static final int MESSAGE_TOAST = 5;
// Key names received from the BluetoothChatService Handler
public static final String DEVICE_NAME = "device_name";
public static final String TOAST = "toast";
private BluetoothAdapter mBluetoothAdapter = null;
private static BluetoothSerialService mSerialService = null;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (DEBUG)
Log.e(LOG_TAG, "+++ ON CREATE +++");
setContentView(R.layout.main);
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
mSerialService = new BluetoothSerialService(this, mHandlerBT);
Button buzzerOn = (Button) findViewById(R.id.button1);
buzzerOn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Log.v("BlueTerm","Buzzer button clicked");
//send("37".getBytes());
send(bigIntToByteArray(37));
}
});
Button buzzerOff = (Button) findViewById(R.id.button2);
buzzerOff.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Log.v("BlueTerm","Buzzer button clicked");
//send("37".getBytes());
send(bigIntToByteArray(30));
}
});
Button recon = (Button) findViewById(R.id.button3);
recon.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Log.v("BlueTerm","recon button clicked");
BluetoothAdapter iballAdapter = BluetoothAdapter.getDefaultAdapter();
BluetoothDevice RN42_Device = iballAdapter.getRemoteDevice("00:06:66:49:57:5F");
try {
Socket = RN42_Device.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));
DataOut = Socket.getOutputStream();
DataIn = Socket.getInputStream();
} catch (Exception e1) {
e1.printStackTrace();
}
if (DataIn != null) {
Log.d("AppFunctions","DataIn is not null,so making it NULL");
try {DataIn.close();} catch (Exception e) {}
DataIn = null;
}
Log.i("AppFunctions", "DataOut -" + DataOut);
if (DataOut != null) {
Log.d("AppFunctions","DataOut is not null,so making it NULL");
try {DataOut.close();} catch (Exception e) {}
DataOut = null;
}
Log.i("AppFunctions", "Socket -" + Socket);
if (Socket != null) {
Log.d("AppFunctions","Socket is not null,so making it NULL");
try {Socket.close();} catch (Exception e) {}
Socket = null;
}
try {
Socket = RN42_Device.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));
Socket.connect();
} catch (Exception e) {
e.printStackTrace();
}
if (mSerialService != null)
mSerialService.stop();
mSerialService.start();
}
});
if (DEBUG)
Log.e(LOG_TAG, "+++ DONE IN ON CREATE +++");
}
#Override
public void onStart() {
super.onStart();
if (DEBUG)
Log.e(LOG_TAG, "++ ON START ++");
mEnablingBT = false;
}
#Override
public synchronized void onResume() {
super.onResume();
if (DEBUG) {
Log.e(LOG_TAG, "+ ON RESUME +");
}
if (mSerialService != null) {
Log.v("BlueTerm","mSerialService is NOT null");
// Only if the state is STATE_NONE, do we know that we haven't started already
if (mSerialService.getState() == BluetoothSerialService.STATE_NONE) {
// Start the Bluetooth chat services
Log.v("BlueTerm","starting BT chat service");
mSerialService.start();
}
}
}
}
#Override
public synchronized void onPause() {
super.onPause();
if (DEBUG)
Log.e(LOG_TAG, "- ON PAUSE -");
}
#Override
public void onStop() {
super.onStop();
if(DEBUG)
Log.e(LOG_TAG, "-- ON STOP --");
}
#Override
public void onDestroy() {
super.onDestroy();
if (DEBUG)
Log.e(LOG_TAG, "--- ON DESTROY ---");
if (mSerialService != null)
mSerialService.stop();
}
public int getConnectionState() {
return mSerialService.getState();
}
public void send(byte[] out) {
mSerialService.write( out );
}
// The Handler that gets information back from the BluetoothService
private final Handler mHandlerBT = new Handler() {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MESSAGE_STATE_CHANGE:
if(DEBUG) Log.i(LOG_TAG, "MESSAGE_STATE_CHANGE: " + msg.arg1);
switch (msg.arg1) {
case BluetoothSerialService.STATE_CONNECTED:
break;
case BluetoothSerialService.STATE_CONNECTING:
break;
case BluetoothSerialService.STATE_LISTEN:
case BluetoothSerialService.STATE_NONE:
Log.d("BlueTerm","inside STATE_NONE in handler");
break;
}
break;
case MESSAGE_WRITE:
if (mLocalEcho) {
byte[] writeBuf = (byte[]) msg.obj;
}
break;
case MESSAGE_READ:
byte[] readBuf = (byte[]) msg.obj;
Log.d("incoming writebytes",""+readBuf.toString());
break;
case MESSAGE_DEVICE_NAME:
// save the connected device's name
mConnectedDeviceName = msg.getData().getString(DEVICE_NAME);
Toast.makeText(getApplicationContext(), "Connected to "
+ mConnectedDeviceName, Toast.LENGTH_SHORT).show();
break;
case MESSAGE_TOAST:
Toast.makeText(getApplicationContext(), msg.getData().getString(TOAST),
Toast.LENGTH_SHORT).show();
break;
}
}
};
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if(DEBUG) Log.d(LOG_TAG, "onActivityResult " + resultCode);
switch (requestCode) {
case REQUEST_CONNECT_DEVICE:
// When DeviceListActivity returns with a device to connect
if (resultCode == Activity.RESULT_OK) {
// Get the device MAC address
String address = "00:06:66:49:57:5F";
// Get the BLuetoothDevice object
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
// Attempt to connect to the device
mSerialService.connect(device);
}
break;
case REQUEST_ENABLE_BT:
// When the request to enable Bluetooth returns
if (resultCode == Activity.RESULT_OK) {
Log.d(LOG_TAG, "BT not enabled");
}
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.option_menu, menu);
mMenuItemConnect = menu.getItem(0);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.connect:
if (getConnectionState() == BluetoothSerialService.STATE_NONE) {
String address = "00:06:66:49:57:5F";
// Get the BLuetoothDevice object
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
Log.d("BlueTerm","device: " + device);
// Attempt to connect to the device
mSerialService.connect(device);
}
else
if (getConnectionState() == BluetoothSerialService.STATE_CONNECTED) {
mSerialService.stop();
mSerialService.start();
}
return true;
case R.id.preferences:
//doPreferences();
return true;
case R.id.menu_special_keys:
//doDocumentKeys();
return true;
}
return false;
}
private byte[] bigIntToByteArray( final int i ) {
BigInteger bigInt = BigInteger.valueOf(i);
return bigInt.toByteArray();
}
}
BluetoothService:
/**
* This class does all the work for setting up and managing Bluetooth
* connections with other devices. It has a thread that listens for
* incoming connections, a thread for connecting with a device, and a
* thread for performing data transmissions when connected.
*/
public class BluetoothSerialService {
// Debugging
private static final String TAG = "BluetoothReadService";
private static final boolean D = true;
private static final UUID SerialPortServiceClass_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
// Member fields
private final BluetoothAdapter mAdapter;
private final Handler mHandler;
private ConnectThread mConnectThread;
private ConnectedThread mConnectedThread;
private int mState;
// Constants that indicate the current connection state
public static final int STATE_NONE = 0; // we're doing nothing
public static final int STATE_LISTEN = 1; // now listening for incoming connections
public static final int STATE_CONNECTING = 2; // now initiating an outgoing connection
public static final int STATE_CONNECTED = 3; // now connected to a remote device
/**
* Constructor. Prepares a new BluetoothChat session.
* #param context The UI Activity Context
* #param handler A Handler to send messages back to the UI Activity
*/
public BluetoothSerialService(Context context, Handler handler) {
mAdapter = BluetoothAdapter.getDefaultAdapter();
mState = STATE_NONE;
mHandler = handler;
// mEmulatorView = emulatorView;
}
/**
* Set the current state of the chat connection
* #param state An integer defining the current connection state
*/
private synchronized void setState(int state) {
if (D) Log.d(TAG, "setState() " + mState + " -> " + state);
mState = state;
Log.d("BluetoothSerialService","state : " + state);
// Give the new state to the Handler so the UI Activity can update
mHandler.obtainMessage(BlueTerm.MESSAGE_STATE_CHANGE, state, -1).sendToTarget();
}
/**
* Return the current connection state. */
public synchronized int getState() {
return mState;
}
/**
* Start the chat service. Specifically start AcceptThread to begin a
* session in listening (server) mode. Called by the Activity onResume() */
public synchronized void start() {
if (D) Log.d(TAG, "start");
// Cancel any thread attempting to make a connection
if (mConnectThread != null) {
mConnectThread.cancel();
mConnectThread = null;
}
// Cancel any thread currently running a connection
if (mConnectedThread != null) {
mConnectedThread.cancel();
mConnectedThread = null;
}
setState(STATE_NONE);
}
/**
* Start the ConnectThread to initiate a connection to a remote device.
* #param device The BluetoothDevice to connect
*/
public synchronized void connect(BluetoothDevice device) {
if (D) Log.d(TAG, "connect to: " + device);
// Cancel any thread attempting to make a connection
if (mState == STATE_CONNECTING) {
if (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;}
}
// Cancel any thread currently running a connection
if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;}
// Start the thread to connect with the given device
mConnectThread = new ConnectThread(device);
mConnectThread.start();
setState(STATE_CONNECTING);
}
/**
* Start the ConnectedThread to begin managing a Bluetooth connection
* #param socket The BluetoothSocket on which the connection was made
* #param device The BluetoothDevice that has been connected
*/
public synchronized void connected(BluetoothSocket socket, BluetoothDevice device) {
if (D) Log.d(TAG, "connected");
// Cancel the thread that completed the connection
if (mConnectThread != null) {
mConnectThread.cancel();
mConnectThread = null;
}
// Cancel any thread currently running a connection
if (mConnectedThread != null) {
mConnectedThread.cancel();
mConnectedThread = null;
}
// Start the thread to manage the connection and perform transmissions
mConnectedThread = new ConnectedThread(socket);
mConnectedThread.start();
// Send the name of the connected device back to the UI Activity
Message msg = mHandler.obtainMessage(BlueTerm.MESSAGE_DEVICE_NAME);
Bundle bundle = new Bundle();
bundle.putString(BlueTerm.DEVICE_NAME, device.getName());
msg.setData(bundle);
mHandler.sendMessage(msg);
setState(STATE_CONNECTED);
}
/**
* Stop all threads
*/
public synchronized void stop() {
if (D) Log.d(TAG, "stop");
if (mConnectThread != null) {
mConnectThread.cancel();
mConnectThread = null;
}
if (mConnectedThread != null) {
mConnectedThread.cancel();
mConnectedThread = null;
}
setState(STATE_NONE);
}
/**
* Write to the ConnectedThread in an unsynchronized manner
* #param out The bytes to write
* #see ConnectedThread#write(byte[])
*/
public void write(byte[] out) {
Log.e("BluetoothSerialService","Inside write fn" + " :" + out.toString());
// Create temporary object
ConnectedThread r;
// Synchronize a copy of the ConnectedThread
synchronized (this) {
if (mState != STATE_CONNECTED) return;
r = mConnectedThread;
}
// Perform the write unsynchronized
r.write(out);
}
/**
* Indicate that the connection attempt failed and notify the UI Activity.
*/
private void connectionFailed() {
setState(STATE_NONE);
// Send a failure message back to the Activity
Message msg = mHandler.obtainMessage(BlueTerm.MESSAGE_TOAST);
Bundle bundle = new Bundle();
bundle.putString(BlueTerm.TOAST, "Unable to connect device");
msg.setData(bundle);
mHandler.sendMessage(msg);
}
/**
* Indicate that the connection was lost and notify the UI Activity.
*/
private void connectionLost() {
setState(STATE_NONE);
// Send a failure message back to the Activity
Message msg = mHandler.obtainMessage(BlueTerm.MESSAGE_TOAST);
Bundle bundle = new Bundle();
bundle.putString(BlueTerm.TOAST, "Device connection was lost");
msg.setData(bundle);
mHandler.sendMessage(msg);
}
/**
* This thread runs while attempting to make an outgoing connection
* with a device. It runs straight through; the connection either
* succeeds or fails.
*/
private class ConnectThread extends Thread {
private final BluetoothSocket mmSocket;
private final BluetoothDevice mmDevice;
public ConnectThread(BluetoothDevice device) {
mmDevice = device;
BluetoothSocket tmp = null;
// Get a BluetoothSocket for a connection with the
// given BluetoothDevice
try {
tmp = device.createRfcommSocketToServiceRecord(SerialPortServiceClass_UUID);
} catch (IOException e) {
Log.e(TAG, "create() failed", e);
}
mmSocket = tmp;
}
public void run() {
Log.e(TAG, "BEGIN mConnectThread");
setName("ConnectThread");
// Always cancel discovery because it will slow down a connection
mAdapter.cancelDiscovery();
// Make a connection to the BluetoothSocket
try {
// This is a blocking call and will only return on a
// successful connection or an exception
mmSocket.connect();
} catch (IOException e) {
connectionFailed();
// Close the socket
try {
mmSocket.close();
} catch (IOException e2) {
Log.e(TAG, "unable to close() socket during connection failure", e2);
}
// Start the service over to restart listening mode
//BluetoothSerialService.this.start();
return;
}
// Reset the ConnectThread because we're done
synchronized (BluetoothSerialService.this) {
mConnectThread = null;
}
// Start the connected thread
connected(mmSocket, mmDevice);
}
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) {
Log.e(TAG, "close() of connect socket failed", e);
}
}
}
/**
* This thread runs during a connection with a remote device.
* It handles all incoming and outgoing transmissions.
*/
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
public ConnectedThread(BluetoothSocket socket) {
Log.e(TAG, "create ConnectedThread");
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
// Get the BluetoothSocket input and output streams
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) {
Log.e(TAG, "temp sockets not created", e);
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run() {
Log.e(TAG, "BEGIN mConnectedThread");
byte[] buffer = new byte[1024];
int bytes;
// Keep listening to the InputStream while connected
Log.e(TAG, "Entering while");
while (true) {
Log.e(TAG, "Inside while");
try {
// Read from the InputStream
bytes = 0;
Log.d("incoming bytes",""+bytes);
Log.e("BT","Inputstream :" + mmInStream);
//bytes = mmInStream.read(buffer);
bytes = mmInStream.read();
Log.d("incoming bytes",""+bytes);
//mEmulatorView.write(buffer, bytes);
// Send the obtained bytes to the UI Activity
mHandler.obtainMessage(BlueTerm.MESSAGE_READ, bytes, -1, buffer).sendToTarget();
String a = buffer.toString();
a = "";
} catch (Exception e) {
Log.e(TAG, "disconnected", e);
connectionLost();
break;
}
bytes = 0;
}
//Log.e(TAG, "Outside while");
}
/**
* Write to the connected OutStream.
* #param buffer The bytes to write
*/
public void write(byte[] buffer) {
try {
Log.d("writing to outStream byte :", buffer.toString());
mmOutStream.write(buffer);
// Share the sent message back to the UI Activity
//mHandler.obtainMessage(BlueTerm.MESSAGE_WRITE, buffer.length, -1, buffer).sendToTarget();
} catch (IOException e) {
Log.e(TAG, "Exception during write", e);
}
}
public void cancel() {
try {
mmSocket.close();
} catch (Exception e) {
Log.e(TAG, "close() of connect socket failed", e);
}
}
}
}
Logcat error:
W/System.err(4603): java.io.IOException: [JSR82] connect: Connection is not created (failed or aborted).
W/System.err(4603): at android.bluetooth.BluetoothSocket.connect(BluetoothSocket.java:395)
I suspect that this error could be thrown because the app is not able to get access to the active BT port,in the above mentioned test case.Reason is because I read this site : https://code.google.com/p/android/issues/detail?id=5427 (See answer #19 by dknop)
I observe that none of this issue occur on samsung s2/grand/nexus devices which I tested on.My error could also be due to MTK processors/its BT firmware/iball custom android issue.(http://redacacia.me/2012/07/17/overcoming-android-bluetooth-blues-with-reflection-method/)
Has anyone faced a similar problem? Any help would be appreciated.Many thanks !
I've tested Bluetooth connectivity on dozens of different tablets, and I've seen some VERY flaky behavior. My apps always call createRfcommSocketToServiceRecord(...) in a loop because sometimes it will fail for no apparent reason, only to succeed on a later attempt. And the API doesn't let you distinguish between transient and permanent failures. Some tablets give you a clue in the text of the error message, but others don't.
I typically try to connect 100 times at 100ms intervals, and then stop and ask the user if the device they're trying to connect to is turned on and in range. On one particular tablet model I've tested, it's not unusual for the connection to fail more than 300 times... and then it will suddenly work like nothing was ever wrong.
I have used this piece of code to make my connectivity to Bluetooth device(i.e. Bluetooth printer) stable. Now it connect 9.9 times out of 10. If still some error occurred i reset my Bluetooth programmatically again call this piece of code then it connect 10 times out of 10.
public boolean connectToPrinter(String printerName) throws IOException
{
BluetoothAdapter.getDefaultAdapter().cancelDiscovery();
BluetoothDevice device = getPrinterByName(printerName);
if (bluetoothSocket != null)
{
bluetoothSocket.close();
}
try {
Method m=device.getClass().getMethod("createRfcommSocket", new Class[]{int.class});
bluetoothSocket= (BluetoothSocket) m.invoke(device, 1);
} catch (Exception e) {
e.printStackTrace();
}
if (bluetoothSocket == null)
return false;
bluetoothSocket.connect();
return true;
}
here is the code of getPrinterByName():
private BluetoothDevice getPrinterByName(String printerName)
{
Set<BluetoothDevice> pairedDevices = BluetoothAdapter.getDefaultAdapter().getBondedDevices();
for (BluetoothDevice device : pairedDevices)
{
Log.e("","device name: "+device.getName());
if (device.getName() == null)
continue;
if (device.getName().contains(printerName))
{
remoteDevice = device;
// pairPrinter(printerName);
return remoteDevice;
}
}
return null;
}
bluetoothSocket is the Object of BluetoothSocket class. and don't forget to run this code in thread otherwise this will block your Main Thread. :-)
hi friend just replace the code to connect to bluetoothsocket by the code using reflection to
establish connection.....
private BluetoothSocket createBluetoothSocket(BluetoothDevice device) throws IOException {
if(Build.VERSION.SDK_INT >= 10){
try {
final Method m = device.getClass().getMethod("createInsecureRfcommSocketToServiceRecord", new Class[] { UUID.class });
return (BluetoothSocket) m.invoke(device, MY_UUID);
} catch (Exception e) {
Log.e(TAG, "Could not create Insecure RFComm Connection",e);
}
}
return device.createRfcommSocketToServiceRecord(MY_UUID);
}
Quote: I observed that by switching off and then switching ON the BT and then trying to establish BT connection between tablet and RN42 was happening .But now, I was not getting any input signals from RN42 to tablet,but was able to just send data from tablet to RN42.
So, before reinstalling app it WAS possible to receive input signals from rn42?
I, will be asking how to combine/fuse 2 java files if,the outstring was initiated in the BluetoothcommandService.java file I will be editing my Post sir and post my MainActivity.java file and BluetoothCommandService.java file..I just doent know how to combine it..
this is the MainActivity.java
public class MainActivity extends Activity {
//public class MainActivity extends Activity implements OnClickListener {
BluetoothAdapter BTAdapter;
BluetoothDevice BTDevice;
private TextView title;
private static final int REQUEST_DEVICE_CONNECT = 1;
private static final int REQUEST_ENABLE_BLUETOOTH = 2;
private BluetoothCommandService commandService = null;
private String connectedDeviceName = null;
//Message types sent from the Handler
public static final int MESSAGE_STATE_CHANGE = 1;
public static final int MESSAGE_READ = 2;
public static final int MESSAGE_WRITE = 3;
public static final int MESSAGE_DEVICE_NAME = 4;
public static final int MESSAGE_TOAST = 5;
public static final int RECIEVE_MESSAGE = 6;
//Will be used in BluetoothCommandSrvice jave file
public static final String TOAST = "toast";
public static final String DEVICENAME = "device name";
//#######for the controller
public static final String tagStateCTRL = "Controller";
private OutputStream outStream = null;
private static final UUID myUUID = UUID.fromString("fa87c0d0-afac-11de-8a39-0800200c9a66");
private static String address = "00:00:00:00:00:00"; // Insert your bluetooth devices MAC address
private StringBuilder sb = new StringBuilder();
Button btn_d1_on, btn_d1_off;
//for changing the device_1 name
TextView device1;
Button change;
EditText renameDevice;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_main); gi move sa ubos sa request window
// Set up the window layout
requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
setContentView(R.layout.activity_main);
getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.custom_title);
title = (TextView) findViewById(R.id.title_left_text); // Set up the custom title
title.setText(R.string.app_name); // Set up the custom title
title = (TextView) findViewById(R.id.title_right_text); // Set up the custom title
//Button openButton = (Button)findViewById(R.id.open);
//##########for the controller
btn_d1_on = (Button) findViewById(R.id.device1_on);
btn_d1_off = (Button) findViewById(R.id.device1_off);
//########for changing the device_1 name
device1 = (TextView)findViewById(R.id.device1);
change = (Button)findViewById(R.id.buttonTest);
renameDevice = (EditText)findViewById(R.id.editTest);
change.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
String change_device1 = renameDevice.getText().toString();
device1.setText(change_device1);
}
});
// AUTO REQUEST OF ENABLING THE BLUETOOTH
BTAdapter = BluetoothAdapter.getDefaultAdapter();
//A code that will detect if BT is enabled otherwise will require it.
if (BTAdapter == null)
{
//Toast.makeText(context, text, duration)
Toast.makeText(this, "No Bluetooth adapter is available.", Toast.LENGTH_LONG).show();
finish();
return;
}
//##########for the controller
btn_d1_on.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
//sendData("1");
//Toast msg = Toast.makeText(getBaseContext(), "The device is now On", Toast.LENGTH_SHORT);
//msg.show()
btn_d1_on.setEnabled(false);
sendData("1");
}
});
//##########for the controller
btn_d1_off.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
//sendData("0");
//Toast msg = Toast.makeText(getBaseContext(), "The device is now On", Toast.LENGTH_SHORT);
//msg.show();
btn_d1_off.setEnabled(false);
sendData("0");
}
});
}
#Override
protected void onStart() {
super.onStart();
//Requesting Bluetooth automatically when its not yet enabled.
if (!BTAdapter.isEnabled())
{
Intent enableIntent = new Intent (BluetoothAdapter.ACTION_REQUEST_ENABLE);
//startActivityForResult(enableIntent, 0);
startActivityForResult(enableIntent, REQUEST_ENABLE_BLUETOOTH);
}
else
{
if (commandService == null)
setupCommand();
}
}
//if (BTAdapter.getScanMode() != BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE)
//{
//Intent discoverableIntent = new Intent (BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
//discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 500);
//startActivity(discoverableIntent);
//}
#Override
protected void onResume() {
super.onResume();
if (commandService != null)
{
if (commandService.getState() == BluetoothCommandService.stateNothing)
{
commandService.start();
}
}
}
private void setupCommand()
{
commandService = new BluetoothCommandService(this, bluetoothHandler);
}
#Override
protected void onDestroy()
{
super.onDestroy();
if (commandService != null)
commandService.stop();
}
private void ensureDiscoverable()
{
//Get the current Bluetooth scan mode of the local Bluetooth adapter. The Bluetooth scan mode determines if the local adapter is connectable and/or discoverable from remote Bluetooth devices.
if (BTAdapter.getScanMode() != BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE)
{
Intent ensureDiscoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
ensureDiscoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
startActivity(ensureDiscoverableIntent);
}
}
//This gets information back from the "BluetoothChatService"/"BluetoothCommandService"
//#SuppressLint("HandlerLeak")
//private final Handler bluetoothHandler = new Handler(new Handler.Callback()
#SuppressLint("HandlerLeak")
public final Handler bluetoothHandler = new Handler()
{
#Override
public void handleMessage(android.os.Message msg)
{
switch (msg.what)
{
case MESSAGE_STATE_CHANGE:
switch (msg.arg1)
{
case BluetoothCommandService.stateConnected:
title.setText(R.string.title_connectedTo);
title.append(connectedDeviceName);
break;
case BluetoothCommandService.stateConnecting:
title.setText(R.string.title_connecting);
break;
case BluetoothCommandService.stateListen:
case BluetoothCommandService.stateNothing:
title.setText(getString(R.string.title_notConnected));
break;
}
break;
case MESSAGE_DEVICE_NAME:
connectedDeviceName = msg.getData().getString(DEVICENAME);
Toast.makeText(getApplicationContext(), "Connected to " + connectedDeviceName, Toast.LENGTH_SHORT).show();
break;
case MESSAGE_TOAST:
Toast.makeText(getApplicationContext(), msg.getData().getString(TOAST), Toast.LENGTH_SHORT).show();
break;
case RECIEVE_MESSAGE: // if receive message
byte[] readBuf = (byte[]) msg.obj;
String strIncom = new String(readBuf, 0, msg.arg1); // create string from bytes array
sb.append(strIncom); // append string
int endOfLineIndex = sb.indexOf("\r\n"); // determine the end-of-line
if (endOfLineIndex > 0) { // if end-of-line,
//String sbprint = sb.substring(0, endOfLineIndex); // extract string
sb.delete(0, sb.length()); // and clear
//txtArduino.setText("Data from Arduino: " + sbprint); // update TextView
//1/4/14
btn_d1_on.setEnabled(true);
btn_d1_off.setEnabled(true);
}
//Log.d(TAG, "...String:"+ sb.toString() + "Byte:" + msg.arg1 + "...");
break;
}
//return false;
}
};
//});
public void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case REQUEST_DEVICE_CONNECT:
// When DeviceList Activity returns with a device to connect
if (resultCode == Activity.RESULT_OK) {
// Get the device MAC address
String address = data.getExtras()
.getString(DeviceList.EXTRA_DEVICE_MAC_ADDRESS);
// Get the BLuetoothDevice object
BluetoothDevice device = BTAdapter.getRemoteDevice(address);
// Attempt to connect to the device
commandService.connect(device);
}
break;
case REQUEST_ENABLE_BLUETOOTH:
// When the request to enable Bluetooth returns
if (resultCode == Activity.RESULT_OK) {
// Bluetooth is now enabled, so set up a chat session
setupCommand();
} else {
// User did not enable Bluetooth or an error occured
Toast.makeText(this, R.string.notEnabledBluetooth, Toast.LENGTH_SHORT).show();
finish();
}
}
}
#Override
//Creating an Option Menu for connectivity and discoverability of a BT device
public boolean onCreateOptionsMenu(Menu menu)
{
//MenuInflater is a class
MenuInflater OptionMenu = getMenuInflater();
//OptionMenu.inflate(menuRes, menu)
OptionMenu.inflate(R.menu.main, menu);
return true;
}
public boolean onOptionsItemSelected(MenuItem item)
{
switch (item.getItemId())
{
case R.id.connect:
Intent serverIntent = new Intent(this, DeviceList.class);
//this.startActivityForResult(serverIntent, REQUEST_DEVICE_CONNECT);
startActivityForResult(serverIntent, REQUEST_DEVICE_CONNECT);
return true;
case R.id.discoverable:
ensureDiscoverable();
return true;
//case R.id.abouts:
//Intent intentabouts = new Intent(this,abouts.class);
//return true;
//default:
//return super.onOptionsItemSelected(item);
}
return false;
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
if (keyCode == KeyEvent.KEYCODE_VOLUME_UP)
{
commandService.write(BluetoothCommandService.VOL_UP);
return true;
}
else if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN)
{
commandService.write(BluetoothCommandService.VOL_DOWN);
return true;
}
return super.onKeyDown(keyCode, event);
}
//#########################################
private void sendData(String message)
//public void sendData(String message)
{
byte[] msgBuffer = message.getBytes();
Log.d(tagStateCTRL, "...Sending data: " + message + "...");
try {
outStream.write(msgBuffer);
}
catch (IOException e){
String msg = "In onResume() and an exception occurred during write: " + e.getMessage();
if (address.equals("00:00:00:00:00:00"))
msg = msg + ".\n\nUpdate your server address from 00:00:00:00:00:00 to the correct address in the java code";
msg = msg + ".\n\nCheck that the SPP UUID: " + myUUID.toString() + " exists on server.\n\n";
errorExit("Fatal Error", msg);
}
}
private void errorExit(String title, String message){
Toast msg = Toast.makeText(getBaseContext(),
title + " - " + message, Toast.LENGTH_SHORT);
msg.show();
finish();
}
//#########################################
}
This is the BluetoothCommanService.java
public class BluetoothCommandService {
private final BluetoothAdapter BTAdapter;
private final Handler bluetoothHandler;
private int connectionState;
private ConnectThread connectThread;
//private ConnectedThread connectedThread;
public ConnectedThread connectedThread;
//***Added 12/27/13
private AcceptThread mainAcceptThread;
//connection states of the Bluetooth
public static final int stateNothing = 0; //doing nothing
public static final int stateListen = 1; //listening for incoming connections
public static final int stateConnecting = 2; //initiating an outgoing connection
public static final int stateConnected = 3;
//constants that indicate command to computer
public static final int exitCMD = -1;
public static final int VOL_UP = 1;
public static final int VOL_DOWN = 2;
private static final boolean D = true;
private static final String tagState = "BluetoothCommandService";
//universally unique identifier (UUID)
//The intent of UUIDs is to enable distributed systems to uniquely identify information without significant central coordination
//private static final UUID myUUID = UUID.fromString("04c6093b-0000-1000-8000-00805f9b34fb");
private static final UUID myUUID = UUID.fromString("fa87c0d0-afac-11de-8a39-0800200c9a66");
//Name for the SDP (don;t know what is it) record when creating server socket
private static final String name = "BluetoothCommand";
public BluetoothCommandService(Context context, Handler handler) { // context == UI Activity Context && handler == send message back to the UI Activity
BTAdapter = BluetoothAdapter.getDefaultAdapter();
connectionState = stateNothing;
bluetoothHandler = handler;
}
private synchronized void setState(int state) { // state == current connection state; an integer
if (D) Log.d(tagState, "setState() " + connectionState + " -> " + state);
connectionState = state;
//Give the new state to the Handler so that the UI Activity can update
//bluetoothHandler.obtainMessage(what, arg1, arg2)
bluetoothHandler.obtainMessage(MainActivity.MESSAGE_STATE_CHANGE, state, -1).sendToTarget();
}
public synchronized int getState() { //return the current connection state
return connectionState;
}
public synchronized void start() {
if (D) Log.d(tagState, "start");
// Cancel any thread attempting to make a connection
if (connectThread != null)
{
connectThread.cancel();
connectThread = null;
}
// Cancel any thread currently running a connection
if (connectedThread != null)
{
connectedThread.cancel();
connectedThread = null;
}
// Start the thread to listen on a BluetoothServerSocket
if (mainAcceptThread == null)
{
mainAcceptThread = new AcceptThread();
mainAcceptThread.start();
}
setState(stateListen);
}
//device == the BluetoothDevice to connect
public synchronized void connect(BluetoothDevice device) {
if (D) Log.d(tagState, "connect to: " + device);
// Cancel any thread attempting to make a connection
if (connectionState == stateConnecting) {
if (connectThread != null)
{
connectThread.cancel();
connectThread = null;
}
}
// Cancel any thread currently running a connection
if (connectedThread != null)
{
connectedThread.cancel();
connectedThread = null;
}
// Cancel the accept thread because we only want to connect to one device
if (mainAcceptThread != null)
{
mainAcceptThread.cancel();
mainAcceptThread = null;
}
// Start the thread to connect with the given device
connectThread = new ConnectThread(device);
connectThread.start();
setState(stateConnecting);
}
public synchronized void connected(BluetoothSocket socket, BluetoothDevice device) {
if (D) Log.d(tagState, "connected");
// Cancel the thread that completed the connection
if (connectThread != null)
{
connectThread.cancel();
connectThread = null;
}
// Cancel any thread currently running a connection
if (connectedThread != null)
{
connectedThread.cancel();
connectedThread = null;
}
if (mainAcceptThread != null)
{
mainAcceptThread.cancel();
mainAcceptThread = null;
}
// Start the thread to manage the connection and perform transmissions
connectedThread = new ConnectedThread(socket);
connectedThread.start();
Message msg = bluetoothHandler.obtainMessage(MainActivity.MESSAGE_DEVICE_NAME);
Bundle bundle = new Bundle();
bundle.putString(MainActivity.DEVICENAME, device.getName());
msg.setData(bundle);
bluetoothHandler.sendMessage(msg);
setState(stateConnected);
}
public synchronized void stop() {
if (D) Log.d(tagState, "stop");
if (connectThread != null)
{
connectThread.cancel();
connectThread = null;
}
if (connectedThread != null)
{
connectedThread.cancel();
connectedThread = null;
}
if (mainAcceptThread != null)
{
mainAcceptThread.cancel();
mainAcceptThread = null;
}
setState(stateNothing);
}
public void write(byte[] out) {
ConnectedThread r;
synchronized (this) {
if (connectionState != stateConnected) return;
r = connectedThread;
}
r.write(out);
}
public void write(int out) {
// Create temporary object
ConnectedThread r;
// Synchronize a copy of the ConnectedThread
synchronized (this) {
if (connectionState != stateConnected) return;
r = connectedThread;
}
// Perform the write unsynchronized
r.write(out);
}
private void connectionFailed() {
setState(stateListen);
// Send a failure message back to the Activity
Message msg = bluetoothHandler.obtainMessage(MainActivity.MESSAGE_TOAST);
Bundle bundle = new Bundle();
bundle.putString(MainActivity.TOAST, "Unable to connect device");
msg.setData(bundle);
bluetoothHandler.sendMessage(msg);
}
/**
* Indicate that the connection was lost and notify the UI Activity.
*/
private void connectionLost() {
setState(stateListen);
Message msg = bluetoothHandler.obtainMessage(MainActivity.MESSAGE_TOAST);
Bundle bundle = new Bundle();
bundle.putString(MainActivity.TOAST, "Device connection was lost");
msg.setData(bundle);
bluetoothHandler.sendMessage(msg);
}
private class ConnectThread extends Thread {
private final BluetoothSocket connectThread_socket;
private final BluetoothDevice connectThread_device;
public ConnectThread(BluetoothDevice device) {
connectThread_device = device;
BluetoothSocket tmp = null;
//Get a BluetoothSocket for a connection w/ the given BT device
//try {
//catch (IOException e) {
//Log.e(tag, msg, tr)
//Log.e(tagState, "create() failed", e);}
//Added 12/28/13
Method m;
try {
m = device.getClass().getMethod("createRfcommSocket", new Class[] {int.class});
tmp = (BluetoothSocket) m.invoke(device, 1);
} catch (SecurityException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (NoSuchMethodException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
connectThread_socket = tmp;
}
public void run() {
Log.i(tagState, "BEGIN ConnectThread");
setName("ConnectThread");
BTAdapter.cancelDiscovery();
// Make a connection to the BluetoothSocket
try {
connectThread_socket.connect();}
catch (IOException e) {
connectionFailed();
try {
connectThread_socket.close();
} catch (IOException e2) {
Log.e(tagState, "Unable to close() socket during connection failure", e2);
}
BluetoothCommandService.this.start();
return;
}
// Reset the ConnectThread because we're done
synchronized (BluetoothCommandService.this) {
connectThread = null;
}
// Start the connected thread
connected(connectThread_socket, connectThread_device); //ERROR: will still create "connected"
}
public void cancel() {
try {
connectThread_socket.close();
} catch (IOException e) {
Log.e(tagState, "close() of connect socket failed", e);
}
}
}
private class ConnectedThread extends Thread {
private final BluetoothSocket connectedThread_socket;
private final InputStream connectedThread_inStream;
private final OutputStream connectedThread_outStream;
public ConnectedThread(BluetoothSocket socket) {
Log.d(tagState, "create ConnectedThread");
connectedThread_socket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
// Get the BluetoothSocket input and output streams
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) {
Log.e(tagState, "temp sockets not created", e);
}
connectedThread_inStream = tmpIn;
connectedThread_outStream = tmpOut;
}
public void run() {
Log.i(tagState, "BEGIN ConnectedThread");
byte[] buffer = new byte[1024]; // WALA JUD KO KASABOT ANI MAN :D
while (true) {
try {
int bytes = connectedThread_inStream.read(buffer);
bluetoothHandler.obtainMessage(MainActivity.MESSAGE_READ, bytes, -1, buffer)
.sendToTarget();
} catch (IOException e) {
Log.e(tagState, "disconnected", e);
connectionLost(); //ERROR: will still create "private void CONNECTIONLOST"
break;
}
}
}
public void write(byte[] buffer) {
try {
connectedThread_outStream.write(buffer);
} catch (IOException e) {
Log.e(tagState, "Exception during write", e);
}
}
public void write(int out) {
try {
connectedThread_outStream.write(out);
} catch (IOException e) {
Log.e(tagState, "Exception during write", e);
}
}
public void cancel() {
try {
connectedThread_outStream.write(exitCMD);
connectedThread_socket.close();
} catch (IOException e) {
Log.e(tagState, "close() of connect socket failed", e);
}
}
}
private class AcceptThread extends Thread {
// The local server socket
private final BluetoothServerSocket acceptThread_ServerSocket;
public AcceptThread() {
BluetoothServerSocket tmp = null;
// Create a new listening server socket
try {
tmp = BTAdapter.listenUsingRfcommWithServiceRecord(name, myUUID);
} catch (IOException e) {
Log.e(tagState, "listen() failed", e);
}
acceptThread_ServerSocket = tmp;
}
public void run() {
if (D) Log.d(tagState, "BEGIN mainAcceptThread" + this);
setName("AcceptThread");
BluetoothSocket socket = null;
while (connectionState != stateConnected) {
try {
socket = acceptThread_ServerSocket.accept();
} catch (IOException e) {
Log.e(tagState, "accept() failed", e);
break;
}
if (socket != null) {
synchronized (BluetoothCommandService.this) {
switch (connectionState) {
case stateListen:
case stateConnecting:
connected(socket, socket.getRemoteDevice());
break;
case stateNothing:
case stateConnected:
try {
socket.close();
} catch (IOException e) {
Log.e(tagState, "Could not close unwanted socket", e);
}
break;
}
}
}
}
if (D) Log.i(tagState, "END mainAcceptThread");
}
public void cancel() {
if (D) Log.d(tagState, "cancel " + this);
try {
acceptThread_ServerSocket.close();
} catch (IOException e) {
Log.e(tagState, "close() of server failed", e);
}
}
}
}