I am created a bluetooth service using the code in this link (written by Kapil Vats):
How to move Bluetooth activity into a Service
I Know how to send data to blutooth module but I don't know how to receive data from bluetooth module.
my code in the service almost is the same as the code in the above link.
this is my service:
public class PrinterService extends Service {
private BluetoothAdapter mBluetoothAdapter;
public static final String BT_DEVICE = "btdevice";
public static final String SPP_UUID = "00001101-0000-1000-8000-00805F9B34FB";
public static final int STATE_NONE = 0;
public static final int STATE_LISTEN = 1;
public static final int STATE_CONNECTING = 2;
public static final int STATE_CONNECTED = 3;
private ConnectThread mConnectThread;
private static ConnectedThread mConnectedThread;
private static Handler mHandler = null;
public static int mState = STATE_NONE;
public static String deviceName;
public Vector<Byte> packdata = new Vector<Byte>(2048);
private BluetoothDevice[] btArray;
public static BluetoothDevice device = null;
int notificationId=0;
NotificationManager manager;
static int started=0;
static int finished=0;
@Override
public void onCreate() {
Log.d("PrinterService", "Service started");
super.onCreate();
}
@Override
public void unbindService(ServiceConnection conn) {
unbindService(conn);
}
@Override
public IBinder onBind(Intent intent) {
mHandler = ((MyAplication) getApplication()).getHandler();
return mBinder;
}
public class LocalBinder extends Binder {
PrinterService getService() {
return PrinterService.this;
}
}
private final IBinder mBinder = new LocalBinder();
@RequiresApi(api = Build.VERSION_CODES.N)
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
createNotificationChannel();
Intent intent1=new Intent(this,MainActivityOrig.class);
PendingIntent pendingIntent=PendingIntent.getActivity(this,0,intent1,0);
Notification notification=new NotificationCompat.Builder(this,"ChannelId1").setContentTitle("WACO")
.setContentText("WACO is running now.").setSmallIcon(R.drawable.ic_waco).setContentIntent(pendingIntent).build();
notificationId = ( int ) System. currentTimeMillis () ;
Log.d("PrinterService", "Onstart Command");
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter != null) {
deviceName=intent.getStringExtra("deviceName");
Set<BluetoothDevice> bt=mBluetoothAdapter.getBondedDevices();
Log.i("3","thread id:\n"+"service CONNECTED"+" "+ bt.size());
if (bt.size()>0){
for (BluetoothDevice device:bt){
if(device.getName().equals(deviceName)){
String macAddress=device.getAddress();
if (macAddress != null && macAddress.length() > 0) {
connectToDevice(macAddress);
Log.i("3","thread id:\n"+"service CONNECTED");
} else {
stopSelf();
if (notificationId!=0){
notificationId=0;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
stopForeground(notificationId);
}
}
}
}
}
}
else {
stopSelf();
if (notificationId!=0){
notificationId=0;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
stopForeground(notificationId);
}
}
}
}
else {
if (notificationId!=0){
notificationId=0;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
stopForeground(notificationId);
}
}
stopSelf();
}
if(notificationId!=0) {
startForeground(1, notification);
started=1;
finished=1;
}
return START_NOT_STICKY;
}
private void createNotificationChannel() {
if(Build.VERSION.SDK_INT>Build.VERSION_CODES.O){
NotificationChannel notificationChannel=new NotificationChannel("ChannelId1","Foreground notification", NotificationManager.IMPORTANCE_DEFAULT);
manager=getSystemService(NotificationManager.class);
manager.createNotificationChannel(notificationChannel);
}
}
private synchronized void connectToDevice(String macAddress) {
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(macAddress);
if (mState == STATE_CONNECTING) {
if (mConnectThread != null) {
mConnectThread.cancel();
mConnectThread = null;
}
}
if (mConnectedThread != null) {
mConnectedThread.cancel();
mConnectedThread = null;
}
mConnectThread = new ConnectThread(device);
mConnectThread.start();
setState(STATE_CONNECTING);
}
private void setState(int state) {
PrinterService.mState = state;
if (mHandler != null) {
mHandler.obtainMessage(MainActivityOrig.MESSAGE_STATE_CHANGE, state, -1).sendToTarget();
}
}
public synchronized void stop() {
setState(STATE_NONE);
if (mConnectThread != null) {
mConnectThread.cancel();
mConnectThread = null;
}
if (mConnectedThread != null) {
mConnectedThread.cancel();
mConnectedThread = null;
}
if (mBluetoothAdapter != null) {
mBluetoothAdapter.cancelDiscovery();
}
stopSelf();
}
@Override
public boolean stopService(Intent name) {
setState(STATE_NONE);
if (mConnectThread != null) {
mConnectThread.cancel();
mConnectThread = null;
}
if (mConnectedThread != null) {
mConnectedThread.cancel();
mConnectedThread = null;
}
mBluetoothAdapter.cancelDiscovery();
return super.stopService(name);
}
private void connectionFailed() {
PrinterService.this.stop();
Message msg = mHandler.obtainMessage(MainActivityOrig.MESSAGE_TOAST);
Bundle bundle = new Bundle();
bundle.putString(MainActivityOrig.TOAST, getString(R.string.error_connect_failed));
msg.setData(bundle);
mHandler.sendMessage(msg);
}
private void connectionLost() {
PrinterService.this.stop();
Message msg = mHandler.obtainMessage(MainActivityOrig.MESSAGE_TOAST);
Bundle bundle = new Bundle();
bundle.putString(MainActivityOrig.TOAST, getString(R.string.error_connect_lost));
msg.setData(bundle);
mHandler.sendMessage(msg);
}
private static Object obj = new Object();
public static void write(byte[] out) {
ConnectedThread r;
synchronized (obj) {
if (mState != STATE_CONNECTED)
return;
r = mConnectedThread;
}
r.write(out);
}
private synchronized void connected(BluetoothSocket mmSocket, BluetoothDevice mmDevice) {
if (mConnectThread != null) {
mConnectThread.cancel();
mConnectThread = null;
}
// Cancel any thread currently running a connection
if (mConnectedThread != null) {
mConnectedThread.cancel();
mConnectedThread = null;
}
mConnectedThread = new ConnectedThread(mmSocket);
mConnectedThread.start();
setState(STATE_CONNECTED);
}
private class ConnectThread extends Thread {
private final BluetoothSocket mmSocket;
private final BluetoothDevice mmDevice;
public ConnectThread(BluetoothDevice device) {
this.mmDevice = device;
BluetoothSocket tmp = null;
try {
tmp = device.createRfcommSocketToServiceRecord(UUID.fromString(SPP_UUID));
Log.i("3","thread id:\n"+"service connected1");
} catch (IOException e) {
e.printStackTrace();
}
mmSocket = tmp;
}
@Override
public void run() {
setName("ConnectThread");
mBluetoothAdapter.cancelDiscovery();
try {
mmSocket.connect();
} catch (IOException e) {
try {
mmSocket.close();
} catch (IOException e1) {
e1.printStackTrace();
}
connectionFailed();
return;
}
synchronized (PrinterService.this) {
mConnectThread = null;
}
connected(mmSocket, mmDevice);
}
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) {
Log.e("PrinterService", "close() of connect socket failed", e);
}
}
}
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
public ConnectedThread(BluetoothSocket socket) {
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) {
Log.e("Printer Service", "temp sockets not created", e);
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
@Override
public void run() {
byte[] buffer=new byte[1024];
int bytes;
while (true){
try {
if (mmInStream==null){
mState = STATE_NONE;
connectionLost();
break;
} else {
bytes = mmInStream.read(buffer);
mHandler.obtainMessage(MainActivityOrig.MESSAGE_READ, bytes, -1, buffer).sendToTarget();
Log.i("7", "thread id:\n" + "recieve");
}
} catch (IOException e) {
e.printStackTrace();
connectionLost();
PrinterService.this.stop();
break;
}
}
}
private byte[] btBuff;
public void write(byte[] buffer) {
try {
mmOutStream.write(buffer);
Log.i("3","thread id:\n"+"send3");
} catch (IOException e) {
Log.e("PrinterService", "Exception during write", e);
}
}
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) {
Log.e("PrinterService", "close() of connect socket failed", e);
}
}
}
public void sendingData(String data){
mConnectedThread.write((data.getBytes()));
Log.i("3","thread id:\n"+"send2");
}
public void trace(String msg) {
Log.d("AbstractActivity", msg);
toast(msg);
}
public void toast(String msg) {
Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_SHORT).show();
}
@Override
public void onDestroy() {
stop();
stopForeground(true);
stopSelf();
Log.d("Printer Service", "Destroyed");
super.onDestroy();
}
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {//
if (!Thread.currentThread().isInterrupted()) {
switch (msg.what) {
case MainActivityOrig.WRITE_TO:
mConnectedThread.write(((String)msg.obj).getBytes());
Log.i("3","thread id:\n"+"send2");
break;
case 4:
break;
case -1:
break;
}
}
super.handleMessage(msg);
}
};
public Handler getHandler() {
return handler;
}
}
and also this is "MyAplication" class is here:
public class MyAplication extends Application {
public static final String TOAST = "toast";
public static final int MESSAGE_TOAST = 2;
public static final int MESSAGE_WRITE = 3;
public static final int MESSAGE_READ = 4;
public static final int MESSAGE_STATE_CHANGE=1;
public static final int WRITE_TO=5;
private String recieve;
Handler.Callback realCallback = null;
Handler handler = new Handler() {
public void handleMessage(android.os.Message msg) {
if (realCallback != null) {
switch (msg.what){
case MESSAGE_STATE_CHANGE:
break;
case MESSAGE_TOAST:
break;
case MESSAGE_WRITE:
break;
case MESSAGE_READ:
byte[] byteBuff=(byte[])msg.obj;
String tempMsg=new String(byteBuff,0,msg.arg1);
recieve=tempMsg;
Log.i("5","thread id:\n"+"recieve"+recieve);
break;
case WRITE_TO:
break;
}
realCallback.handleMessage(msg);
}
};
};
public Handler getHandler() {
return handler;
}
public void setCallBack(Handler.Callback callback) {
this.realCallback = callback;
}
public String getInfoRecieved(){
return recieve;
}
in the code above, MESSAGE_READ tag is the tag for receiving data.