I am working on the mobile android application and my phone successfully connects to the ESP32 microcontroller. The ESP32's bluetooth range is high and I want to disconnect my phone's bluetooth if the distance/range between the phone and the hardware is more than 10 meters. I cannot modify ESP32's code to reduce the power range, so is there any way I can reduce the bluetooth's range or make my phone disconnect automatically if it goes above a specific range? Please find my android studio code below that I have so far:
public class ConnectedDevice extends AppCompatActivity {
private BluetoothAdapter myBluetooth = null;
private BluetoothSocket btSocket = null;
private boolean isBtConnected = false;
private BluetoothDisconnect bluetoothDisconnect;
static final UUID myUUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_connected_device);
new ConnectBT().execute();
btnDis.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
DisconnectOnBtnClick();
}
});
bluetoothDisconnect = new BluetoothDisconnect();
IntentFilter intentFilter = new IntentFilter(BluetoothDevice.ACTION_ACL_DISCONNECTED);
registerReceiver(bluetoothDisconnect, intentFilter);
mButtonStop.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mCountDownTimer.cancel();
mTimerRunning = false;
mButtonStop.setVisibility(View.INVISIBLE);
Intent intent = new Intent(ConnectedDevice.this, PairedDevices.class);
startActivity(intent);
}
});
}
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(bluetoothDisconnect);
}
private void DisconnectOnBtnClick() {
if (mReadThread != null) {
mReadThread.stop();
do {
} while (mReadThread.isRunning());
mReadThread = null;
}
try {
btSocket.close();
}
catch(IOException e)
{
Toast.makeText(getApplicationContext(), "Could not disconnect", Toast.LENGTH_SHORT).show();
}
finish();
}
private void sendSMS() {
try {
message = brand + " " + model + " " + licensePlate;
SmsManager sms = SmsManager.getDefault();
sms.sendTextMessage("5089715596",null,message,null,null);
Toast.makeText(this,"Message Sent",Toast.LENGTH_SHORT).show();
}
catch (Exception e) {
Toast.makeText(this, "Could not send message",Toast.LENGTH_LONG).show();
e.printStackTrace();
}
}
private class BluetoothDisconnect extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
sendSMS();
startTimer();
try {
btSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private void startTimer() {
mCountDownTimer = new CountDownTimer(mTimeLeftInMillis, 1000) {
#Override
public void onTick(long millisUntilFinished) {
mTimeLeftInMillis = millisUntilFinished;
updateCountDownText();
mButtonStop.setVisibility(View.VISIBLE);
}
#Override
public void onFinish() {
mTimerRunning = false;
mButtonStop.setVisibility(View.INVISIBLE);
Toast.makeText(ConnectedDevice.this, "Calling", Toast.LENGTH_SHORT).show();
callNumber();
}
}.start();
mTimerRunning = true;
mButtonStop.setText("Stop");
}
#SuppressLint("MissingPermission")
private void callNumber()
{
Intent phoneIntent = new Intent(Intent.ACTION_CALL);
phoneIntent.setData(Uri.parse("tel:5088631994"));
startActivity(phoneIntent);
}
private void updateCountDownText() {
int minutes = (int) (mTimeLeftInMillis / 1000) / 60;
int seconds = (int) (mTimeLeftInMillis / 1000) % 60;
String timeLeftFormatted = String.format(Locale.getDefault(), "%02d:%02d", minutes, seconds);
mTextViewCountDown.setText(timeLeftFormatted);
}
private class ConnectBT extends AsyncTask<Void, Void, Void> {
private boolean ConnectSuccess = true;
#Override
protected void onPreExecute () {
progress = ProgressDialog.show(ConnectedDevice.this, "Connecting...", "Please Wait!!!");
}
#Override
protected Void doInBackground (Void... devices) {
try {
if ( btSocket==null || !isBtConnected ) {
myBluetooth = BluetoothAdapter.getDefaultAdapter();
remoteDevice = myBluetooth.getRemoteDevice(address);
btSocket = remoteDevice.createInsecureRfcommSocketToServiceRecord(myUUID);
BluetoothAdapter.getDefaultAdapter().cancelDiscovery();
btSocket.connect();
}
}
catch (IOException e) {
ConnectSuccess = false;
}
return null;
}
#Override
protected void onPostExecute (Void result) {
super.onPostExecute(result);
if (!ConnectSuccess) {
Toast.makeText(getApplicationContext(), "Connection Failed. Make sure your device is in range", Toast.LENGTH_SHORT).show();
finish();
}
else {
isBtConnected = true;
mReadThread = new ReadInput();
getCurrentData();
}
progress.dismiss();
}
}
}
Calculated using rssi intensity and power values
public double getDistance(int measuredPower, double rssi) {
if (rssi >= 0) {
return -1.0;
}
if (measuredPower == 0) {
return -1.0;
}
double ratio = rssi * 1.0 / measuredPower;
if (ratio < 1.0) {
return Math.pow(ratio, 10);
} else {
double distance= (0.42093) * Math.pow(ratio, 6.9476) + 0.54992;
return distance;
}
}
how to get power values?
in ScanResult call getTxPower (if your api > 26)
Note:rssi reliability is not 100%, it may be affected by environmental factors
short rssi = intent.getExtras().getShort(BluetoothDevice.EXTRA_RSSI);
int iRssi = abs(rssi);
// 将蓝牙信号强度换算为距离
double power = (iRssi - 59) / 25.0;
String mm = new Formatter().format("%.2f", pow(10, power)).toString();
private final BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
BluetoothDevice device = intent
.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
String aa = tvDevices.getText().toString() + "";
if (aa.contains(device.getAddress())) {
return;
} else {
if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
short rssi = intent.getExtras().getShort(
BluetoothDevice.EXTRA_RSSI);
int iRssi = abs(rssi);
double power = (iRssi - 59) / 25.0;
String mm = new Formatter().format("%.2f", pow(10, power)).toString();
// tvDevices.append(device.getName() + ":" + device.getAddress() + " :" + mm + "m" + "\n");
}else {
}
}
// search finished
} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED
.equals(action)) {
//TODO
}
}
};
Related
I have this app that connects to any model of Bluetooth Thermal Printer and prints a file with data about a product for an invoice.
When the user clicks to register a request for a product that file is created and the app opens a screen with 2 buttons: pair and print. When pair is clicked, a new Activity with a list of devices is opened and the user chooses a printer, it returns to the main 2 buttons activity and the connection is established.
It works because all this process is part of the Activity itself, the Bluetooth connection for example.
But, as you can imagine, if I connect to the printer and open another Activity, that connection is lost. I cant close the activity because the connection is bonded to it.
I need the app to maintain that Bluetooth connection between Activities so i can set a connection in a printer settings screen and just print the file when the register is done.
So I tried to create a Service, I created a Java class and just copy/pasted all this code into it, however, the StartActivityForResult() and onActivityResult() doesn't work on it (I need it to pass the selected device to the connection).
I don't know what to do, please help, I need this whole connection to work on the background.
This it the two buttons screen code:
public class MainActivity extends Activity implements Runnable {
protected static final String TAG = "MainActivity";
private static final int REQUEST_CONNECT_DEVICE = 1;
private static final int REQUEST_ENABLE_BT = 2;
Button mScan, mPrint;
Thread mBlutoothConnectThread;
BluetoothAdapter mBluetoothAdapter;
private UUID applicationUUID = UUID
.fromString("00001101-0000-1000-8000-00805F9B34FB");
private ProgressDialog mBluetoothConnectProgressDialog;
private BluetoothSocket mBluetoothSocket;
BluetoothDevice mBluetoothDevice;
TextView stat;
int printstat;
LinearLayout layout;
/* Get time and date */
Calendar c = Calendar.getInstance();
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd hh:mm a", Locale.US);
final String formattedDate = df.format(c.getTime());
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
stat = findViewById(R.id.bpstatus);
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
layout = findViewById(R.id.layout);
mScan = findViewById(R.id.Scan);
mScan.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View mView) {
if (mScan.getText().equals("Connect")) {
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter == null) {
Toast.makeText(MainActivity.this, "Message1", Toast.LENGTH_SHORT).show();
} else {
if (!mBluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(
BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent,
REQUEST_ENABLE_BT);
} else {
ListPairedDevices();
Intent connectIntent = new Intent(MainActivity.this,
DeviceListActivity.class);
startActivityForResult(connectIntent,
REQUEST_CONNECT_DEVICE);
}
}
} else if (mScan.getText().equals("Disconnect")) {
if (mBluetoothAdapter != null)
mBluetoothAdapter.disable();
stat.setText("");
stat.setText("Disconnected");
stat.setTextColor(Color.rgb(199, 59, 59));
mPrint.setEnabled(false);
mScan.setEnabled(true);
mScan.setText("Connect");
}
}
});
mPrint = findViewById(R.id.mPrint);
mPrint.setOnClickListener(new View.OnClickListener() {
public void onClick(View mView) {
p1();
/* 5000 ms (5 Seconds) */
int TIME = 10000;
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
/* print second copy */
p2();
printstat = 1;
}
}, TIME);
}
});
}
public void p1() {
Thread t = new Thread() {
public void run() {
try {
OutputStream os = mBluetoothSocket.getOutputStream();
String header = "";
String he = "";
he = " Test\n";
os.write(he.getBytes());
os.write(header.getBytes());
// Setting height
int gs = 29;
os.write(intToByteArray(gs));
int h = 150;
os.write(intToByteArray(h));
int n = 170;
os.write(intToByteArray(n));
// Setting Width
int gs_width = 29;
os.write(intToByteArray(gs_width));
int w = 119;
os.write(intToByteArray(w));
int n_width = 2;
os.write(intToByteArray(n_width));
} catch (Exception e) {
Log.e("PrintActivity", "Exe ", e);
}
}
};
t.start();
}
public void p2() {
Thread tt = new Thread() {
public void run() {
try {
OutputStream os = mBluetoothSocket.getOutputStream();
String header = "";
String he = "";
he = " Test\n";
os.write(he.getBytes());
os.write(header.getBytes());
// Setting height
int gs = 29;
os.write(intToByteArray(gs));
int h = 150;
os.write(intToByteArray(h));
int n = 170;
os.write(intToByteArray(n));
// Setting Width
int gs_width = 29;
os.write(intToByteArray(gs_width));
int w = 119;
os.write(intToByteArray(w));
int n_width = 2;
os.write(intToByteArray(n_width));
} catch (Exception e) {
Log.e("PrintActivity", "Exe ", e);
}
}
};
tt.start();
}
#Override
protected void onDestroy() {
super.onDestroy();
/* Terminate bluetooth connection and close all sockets opened */
try {
if (mBluetoothSocket != null)
mBluetoothSocket.close();
} catch (Exception e) {
Log.e("Tag", "Exe ", e);
}
}
public void onActivityResult(int mRequestCode, int mResultCode,
Intent mDataIntent) {
super.onActivityResult(mRequestCode, mResultCode, mDataIntent);
switch (mRequestCode) {
case REQUEST_CONNECT_DEVICE:
if (mResultCode == Activity.RESULT_OK) {
Bundle mExtra = mDataIntent.getExtras();
String mDeviceAddress = mExtra.getString("DeviceAddress");
Log.v(TAG, "Coming incoming address " + mDeviceAddress);
mBluetoothDevice = mBluetoothAdapter.getRemoteDevice(mDeviceAddress);
mBluetoothConnectProgressDialog = ProgressDialog.show(this,
"Connecting...", mBluetoothDevice.getName() + " : "
+ mBluetoothDevice.getAddress(), true, false);
mBlutoothConnectThread = new Thread(this);
mBlutoothConnectThread.start();
// pairToDevice(mBluetoothDevice); This method is replaced by
// progress dialog with thread
}
break;
case REQUEST_ENABLE_BT:
if (mResultCode == Activity.RESULT_OK) {
ListPairedDevices();
Intent connectIntent = new Intent(MainActivity.this,
DeviceListActivity.class);
startActivityForResult(connectIntent, REQUEST_CONNECT_DEVICE);
} else {
Toast.makeText(MainActivity.this, "Not connected to any device", Toast.LENGTH_SHORT).show();
}
break;
}
}
private void ListPairedDevices() {
Set<BluetoothDevice> mPairedDevices = mBluetoothAdapter
.getBondedDevices();
if (mPairedDevices.size() > 0) {
for (BluetoothDevice mDevice : mPairedDevices) {
Log.v(TAG, "PairedDevices: " + mDevice.getName() + " "
+ mDevice.getAddress());
}
}
}
public void run() {
try {
mBluetoothSocket = mBluetoothDevice.createRfcommSocketToServiceRecord(applicationUUID);
mBluetoothAdapter.cancelDiscovery();
mBluetoothSocket.connect();
mHandler.sendEmptyMessage(0);
} catch (IOException eConnectException) {
Log.d(TAG, "CouldNotConnectToSocket", eConnectException);
closeSocket(mBluetoothSocket);
return;
}
}
private void closeSocket(BluetoothSocket nOpenSocket) {
try {
nOpenSocket.close();
Log.d(TAG, "SocketClosed");
} catch (IOException ex) {
Log.d(TAG, "CouldNotCloseSocket");
}
}
#SuppressLint("HandlerLeak")
private Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
mBluetoothConnectProgressDialog.dismiss();
stat.setText("");
stat.setText("Connected");
stat.setTextColor(Color.rgb(97, 170, 74));
mPrint.setEnabled(true);
mScan.setText("Disconnect");
}
};
public static byte intToByteArray(int value) {
byte[] b = ByteBuffer.allocate(4).putInt(value).array();
for (int k = 0; k < b.length; k++) {
System.out.println("Selva [" + k + "] = " + "0x"
+ UnicodeFormatter.byteToHex(b[k]));
}
return b[3];
}
public void iThread(View view) {
startActivity(new Intent(this, MainActivity2.class));
}
}
This is the DeviceList class code:
public class DeviceListActivity extends Activity {
protected static final String TAG = "DeviceListActivity";
private BluetoothAdapter mBluetoothAdapter;
private ArrayAdapter<String> mPairedDevicesArrayAdapter;
#Override
protected void onCreate(Bundle mSavedInstanceState) {
super.onCreate(mSavedInstanceState);
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setContentView(R.layout.activity_device_list);
setResult(Activity.RESULT_CANCELED);
mPairedDevicesArrayAdapter = new ArrayAdapter<>(this, R.layout.device_name);
ListView mPairedListView = findViewById(R.id.paired_devices);
mPairedListView.setAdapter(mPairedDevicesArrayAdapter);
mPairedListView.setOnItemClickListener(mDeviceClickListener);
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
Set<BluetoothDevice> mPairedDevices = mBluetoothAdapter.getBondedDevices();
if (mPairedDevices.size() > 0) {
/* List of all paired devices */
findViewById(R.id.title_paired_devices).setVisibility(View.VISIBLE);
for (BluetoothDevice mDevice : mPairedDevices) {
mPairedDevicesArrayAdapter.add(mDevice.getName() + "\n" + mDevice.getAddress());
}
} else {
/* No paired device */
String mNoDevices = "None Paired";
mPairedDevicesArrayAdapter.add(mNoDevices);
}
}
#Override
protected void onDestroy() {
super.onDestroy();
/* Terminate bluetooth connection and close all sockets opened */
if (mBluetoothAdapter != null) {
mBluetoothAdapter.cancelDiscovery();
}
}
private OnItemClickListener mDeviceClickListener = new OnItemClickListener() {
public void onItemClick(AdapterView<?> mAdapterView, View mView, int mPosition, long mLong) {
try {
/* Attempt to connect to bluetooth device */
mBluetoothAdapter.cancelDiscovery();
String mDeviceInfo = ((TextView) mView).getText().toString();
String mDeviceAddress = mDeviceInfo.substring(mDeviceInfo.length() - 17);
Log.v(TAG, "Device_Address " + mDeviceAddress);
Bundle mBundle = new Bundle();
mBundle.putString("DeviceAddress", mDeviceAddress);
Intent mBackIntent = new Intent();
mBackIntent.putExtras(mBundle);
setResult(Activity.RESULT_OK, mBackIntent);
finish();
} catch (Exception ex) {
Log.v(TAG, "Error: " + ex);
}
}
};
}
Please help
I'm trying to recieve/send data to arduino board using bluetooth, and I can connect to board from one activity. I know that I can make my other activities connect with bluetooth using service but I don't know how to make bluetooth as service. and i don't know how to send and recieve from it.
my Paired Devices code:
public class BTConnect extends AppCompatActivity {
private static final String TAG = "BTConnect";
ListView IdLista;
public static String EXTRA_DEVICE_ADDRESS = "device_address";
private BluetoothAdapter mBtAdapter;
private ArrayAdapter<String> mPairedDevicesArrayAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_btconnect);
}
#Override
public void onResume()
{
super.onResume();
//---------------------------------
VerificarEstadoBT();
//
mPairedDevicesArrayAdapter = new ArrayAdapter<String>(this, R.layout.btconnect_nombre);
IdLista = (ListView)findViewById(R.id.Id2);
IdLista.setAdapter(mPairedDevicesArrayAdapter);
IdLista.setOnItemClickListener(mDeviceClickListener);
mBtAdapter = BluetoothAdapter.getDefaultAdapter();
Set<BluetoothDevice> pairedDevices = mBtAdapter.getBondedDevices();
if (pairedDevices.size() > 0)
{
for (BluetoothDevice device: pairedDevices) {
mPairedDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());
}
}
}
private AdapterView.OnItemClickListener mDeviceClickListener = new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView av, View v, int arg2, long arg3) {
String info = ((TextView) v).getText().toString();
String address = info.substring(info.length() - 17);
Intent i = new Intent(BTConnect.this, device.class);
i.putExtra(EXTRA_DEVICE_ADDRESS, address);
startActivity(i);
}
};
private void VerificarEstadoBT() {
mBtAdapter= BluetoothAdapter.getDefaultAdapter();
if(mBtAdapter==null) {
Toast.makeText(getBaseContext(), "the device can't connect to BT", Toast.LENGTH_SHORT).show();
} else {
if (mBtAdapter.isEnabled()) {
Log.d(TAG, "...Bluetooth Activation...");
} else {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, 1);
}
}
}}
And my first activity 'device' :
public class device extends AppCompatActivity {
Button IdEncender, IdApagar,IdDesconectar,IdReset;
ArrayList<String> addArray = new ArrayList<String>();
ListView show;
//-------------------------------------------
Handler bluetoothIn;
final int handlerState = 0;
private BluetoothAdapter btAdapter = null;
private BluetoothSocket btSocket = null;
private StringBuilder DataStringIN = new StringBuilder();
private ConnectedThread MyConexionBT;
// Identificador unico de servicio - SPP UUID
private static final UUID BTMODULEUUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
// String para la direccion MAC
private static String address = null;
//-------------------------------------------
#SuppressLint("HandlerLeak")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_device);
IdEncender = (Button) findViewById(R.id.IdEncender);
IdApagar = (Button) findViewById(R.id.IdApagar);
IdDesconectar = (Button) findViewById(R.id.IdDisconectar);
show = (ListView) findViewById(R.id.LIST1) ;
IdReset=(Button)findViewById(R.id.IdReset);
bluetoothIn = new Handler() {
public void handleMessage(android.os.Message msg) {
if (msg.what == handlerState) {
String readMessage = (String) msg.obj;
DataStringIN.append(readMessage);
int endOfLineIndex = DataStringIN.indexOf("#");
if (endOfLineIndex > 0) {
String dataInPrint = DataStringIN.substring(0, endOfLineIndex);
String newline = "\r\n";
DataStringIN.delete(0, DataStringIN.length());
//--List adapter--//
addArray.add(dataInPrint);
ArrayAdapter<String> adapter =new ArrayAdapter<String>(device.this, android.R.layout.simple_list_item_1, addArray);
show.setAdapter(adapter);
}
}
};
btAdapter = BluetoothAdapter.getDefaultAdapter(); // get Bluetooth adapter
VerificarEstadoBT();
IdEncender.setOnClickListener(new View.OnClickListener() {
public void onClick(View v)
{
MyConexionBT.write("1");
}
});
IdApagar.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
MyConexionBT.write("0");
}
});
IdDesconectar.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if (btSocket!=null)
{
try {btSocket.close();}
catch (IOException e)
{ Toast.makeText(getBaseContext(), "Error", Toast.LENGTH_SHORT).show();;}
}
finish();
}
});
configurebutton();
}
private void configurebutton() {
Button startbutton = (Button)findViewById(R.id.Start);
startbutton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startActivity(new Intent(device.this,chart.class));
}
});
}
private BluetoothSocket createBluetoothSocket(BluetoothDevice device) throws IOException
{
return device.createRfcommSocketToServiceRecord(BTMODULEUUID);
}
#Override
public void onResume()
{
super.onResume();
Intent intent = getIntent();
address = intent.getStringExtra(BTConnect.EXTRA_DEVICE_ADDRESS);
BluetoothDevice device = btAdapter.getRemoteDevice(address);
try
{
btSocket = createBluetoothSocket(device);
} catch (IOException e) {
Toast.makeText(getBaseContext(), "fail", Toast.LENGTH_LONG).show();
}
try
{
btSocket.connect();
} catch (IOException e) {
try {
btSocket.close();
} catch (IOException e2) {}
}
MyConexionBT = new ConnectedThread(btSocket);
MyConexionBT.start();
}
#Override
public void onPause()
{
super.onPause();
try
{
btSocket.close();
} catch (IOException e2) {}
}
private void VerificarEstadoBT() {
if(btAdapter==null) {
Toast.makeText(getBaseContext(), "error in bluetooth connection", Toast.LENGTH_LONG).show();
} else {
if (btAdapter.isEnabled()) {
} else {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, 1);
}
}
}
public void savefile(String file, String text){
try {
FileOutputStream fos = openFileOutput(file, Context.MODE_APPEND);
fos.write(text.getBytes());
fos.close();
Toast.makeText(device.this, "saved!", Toast.LENGTH_LONG).show();
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(device.this,"error",Toast.LENGTH_LONG).show();
}
}
//Crea la clase que permite crear el evento de conexion
private class ConnectedThread extends Thread
{
private final InputStream mmInStream;
private final OutputStream mmOutStream;
public ConnectedThread(BluetoothSocket socket)
{
InputStream tmpIn = null;
OutputStream tmpOut = null;
try
{
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) { }
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run()
{
byte[] buffer = new byte[256];
int bytes;
while (true) {
try {
bytes = mmInStream.read(buffer);
String readMessage = new String(buffer, 0, bytes);
bluetoothIn.obtainMessage(handlerState, bytes, -1, readMessage).sendToTarget();
} catch (IOException e) {
break;
}
}
}
public void write(String input)
{
try {
mmOutStream.write(input.getBytes());
}
catch (IOException e)
{
Toast.makeText(getBaseContext(), "fail to connect", Toast.LENGTH_LONG).show();
finish();
}
}
}
}
If shortly move your connection/message_exchange logic to Thread/Runnable and start it from Service. You can exchange data between Service and Activity/Activities with BroadcastReceivers or Messenger. I also recommend you to use Bluetooth lib:
implementation 'me.aflak.libraries:bluetooth:1.3.4' this one already have inside thread so it is become easy to embed in your service.
Example code of service which use this lib and Messenger:
private ArrayList<Messenger> mClients = new ArrayList<>();
final private Messenger inComingMessenger = new Messenger(mIncomingHandler);
#SuppressLint("HandlerLeak")
final Handler mIncomingHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case Constants.MSG_REGISTER_CLIENT:
mClients.add(msg.replyTo);
Log.d(TAG, "handleMessage: new client connected. Total: " + mClients.size());
break;
case Constants.MSG_UNREGISTER_CLIENT:
mClients.remove(msg.replyTo);
Log.d(TAG, "handleMessage: client disconnected. Total: " + mClients.size());
break;
case Constants.MSG_YOUR_MESSAGE_TYPE:
String val = (String) msg.obj;
// stuff to do
break;
}
}
};
/**
* Send message to connected activities
*/
public void sendMessageToClients(int msgSignal, Object obj) {
if (mClients.size() == 0)
return;
sendMessage(mClients.get(0), Message.obtain(null, msgSignal, obj));
for (int i = 1; i < mClients.size(); i++) {
if (mClients.get(i) == null)
continue;
sendMessage(mClients.get(i), Message.obtain(null, msgSignal, obj));
}
}
/**
* Send message to binded activity
*/
private void sendMessage(Messenger msgr, Message msg) {
try {
msgr.send((msg));
} catch (RemoteException e) {
Log.e(TAG, "can't send message", e);
e.printStackTrace();
}
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
Log.d(TAG, "onStartCommand");
return START_STICKY;
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
Log.d(TAG, "onBind");
return inComingMessenger.getBinder();
}
#Override
public void onCreate() {
super.onCreate();
bleDevices = new ArrayList<>();
if(bluetooth == null) {
bluetooth = new Bluetooth(this);
bluetooth.setBluetoothCallback(new BluetoothCallback() {
#Override
public void onBluetoothTurningOn() {}
#Override
public void onBluetoothOn() {}
#Override
public void onBluetoothTurningOff() {
bluetooth = null;
}
#Override
public void onBluetoothOff() { }
#Override
public void onUserDeniedActivation() {
// when using bluetooth.showEnableDialog()
// you will also have to call bluetooth.onActivityResult()
}
});
bluetooth.setDiscoveryCallback(new DiscoveryCallback() {
#Override public void onDiscoveryStarted() {
}
#Override public void onDiscoveryFinished() {
bleDevices.clear();
}
#Override public void onDeviceFound(BluetoothDevice device) {
if(bleDevices.indexOf(device)<0) {
bleDevices.add(device);
Log.d(TAG, "Found new device while scanning: "+device.getAddress());
sendMessageToClients(Constants.MSG_BLE_DEVICE_FOUND, device);
}
}
#Override public void onDevicePaired(BluetoothDevice device) {}
#Override public void onDeviceUnpaired(BluetoothDevice device) {}
#Override public void onError(String message) {
Log.e(TAG, "DiscoveryCallback onError "+message);
}
});
bluetooth.setDeviceCallback(new DeviceCallback() {
#Override public void onDeviceConnected(BluetoothDevice device) { }
#Override public void onDeviceDisconnected(BluetoothDevice device, String message) { }
#Override public void onMessage(String message) {
// Handle your message
yourHandleFunction(message.replaceAll(" ",""));
Log.d(TAG, message);
}
#Override public void onError(String message) {
Log.e(TAG, "DeviceCallback onError "+message);
}
#Override public void onConnectError(BluetoothDevice device, String message) { }
});
bluetooth.onStart();
}
connectToSavedDevice();
}
}
private void connectToSavedDevice() {
Log.d(TAG, "connectToSavedDevice state="+getState());
if(getState() != STATE_DISCONNECTED) return;
SharedPreferences pref = getSharedPreferences(App.TAG, 0);
String address = pref.getString(Constants.PREF_AUTO_CONNECT_TO_ADDRESS, null);
if(address == null) {
Log.d(TAG, "saved address==null start scan for devices");
scanDevices();
return;
}
BluetoothDevice device = bluetoothAdapter.getRemoteDevice(address);
if(device!=null) {
Log.d(TAG, "device found try to connect/bound, connect to Arduino");
bluetooth.connectToAddress(address,false);
}
}
In activity implement ServiceConnection interface:
protected synchronized void unbindService() {
if (!isBound()) {
return;
}
// lock object (prevents access to service while disconnecting)
synchronized (outComingMessenger) {
sendMessageToService(Message.obtain(null, Constants.MSG_UNREGISTER_CLIENT));
unbindService(this);
outComingMessenger = null;
}
}
protected void bindService() {
bindService(mServiceIntent, this, BIND_AUTO_CREATE);
}
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
outComingMessenger = new Messenger(service);
final Message msg = Message.obtain(null, Constants.MSG_REGISTER_CLIENT);
msg.replyTo = inComingMessenger;
msg.obj = getClass().getSimpleName();
sendMessageToService(msg);
sendMessageToService(Constants.MSG_CHECK_IS_CONNECTION_READY);
}
#Override
public void onServiceDisconnected(ComponentName name) {
outComingMessenger = null;
bindService();
}
/**
* Send message to service
*/
protected void sendMessageToService(Message msg) {
if (!isBound()) {
return;
}
try {
msg.replyTo = inComingMessenger;
outComingMessenger.send(msg);
} catch (RemoteException e) {
}
}
/**
* Send simple message to connected service
* #param messageId
*/
protected void sendMessageToService(int messageId) {
sendMessageToService(Message.obtain(null, messageId));
}
/**
* Send simple message to connected service
* #param messageId
*/
protected void sendMessageToService(int messageId, Object obj) {
sendMessageToService(Message.obtain(null, messageId, obj));
}
/**
* Service is connected?
*/
protected final boolean isBound() {
return outComingMessenger != null;
}
#SuppressLint("HandlerLeak")
private final Handler mIncomingHandler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case Constants.MSG_YOUR_MESSAGE:
int res = (int) msg.obj;
break;
case Constants.MSG_CONNECTION_READY:
isReady = (boolean) msg.obj;
if(isReady) {
// show toast or what you want to do with the UI
} else {
// do something else
}
break;
case Constants.MSG_BLE_DEVICE_FOUND:
BluetoothDevice device = (BluetoothDevice)msg.obj;
SharedPreferences pref = getSharedPreferences(App.TAG, 0);
String deviceAddress = pref.getString(Constants.PREF_AUTO_CONNECT_TO_ADDRESS, null);
break;
}
}
};
final private Messenger inComingMessenger = new Messenger(mIncomingHandler);
I'm new in android develop and I'm developing an app that transmit/receive data to a BLE module via Uart service.
With smartphone android 5.x.x the app works fine, it connects with the hardware and receive/transmit data.
With smartphone android 7.x.x the app doesn't connects.
Below you can see a snippet of MainActivity.java:
private final BroadcastReceiver UARTStatusChangeReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
final Intent mIntent = intent;
//*********************//
if (action.equals(UartService.ACTION_GATT_CONNECTED)) {
runOnUiThread(new Runnable() {
public void run() {
Log.d(TAG, "HW_CONNECT_MSG");
DisconnectButton.setEnabled(true);
DeviceInfo.setText("Device Information:");
DeviceName.setText(mDevice.getName() + " - Connected");
mState = UART_PROFILE_CONNECTED;
isConnected = true;
if(isConnected) {
//Serial protocol to send command on MCU
Connectcmd[0] = (byte) STX;
Connectcmd[1] = (byte) 0x02;
Connectcmd[2] = (byte) 0x43; // 'C';
Connectcmd[3] = (byte) 0x54; // 'T'
Connectcmd[4] = (byte) ETX;
try {
//send data to UART service
SendData(Connectcmd);
sleep(500); // wait 500ms to send data
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
new Handler().postDelayed(mUpdateTimeTask, 2000);
}
else
{
isConnected = false;
}
}
});
}
It's seem that when SendData, the GATT operation is not yet finished. Smartphone show the message "Device doesn't support UART over BLE. Disconnecting..." due to action.equals(UartService.DEVICE_DOES_NOT_SUPPORT_BLE_UART).
If I delete the if(isConnected)...else... statement also smartphone with android 7.x.x will connects.
My question is what's happen and how can I resolve this issue?
My goal is to send a command to hardware via BLE so when the mcu is connected, a buzzer make a sound.
Thanks for help….
EDIT
Below you can find the whole MainActivity:
public class MainActivity extends Activity implements RadioGroup.OnCheckedChangeListener {
public static final String TAG = "DEBUG ";
public static final String DEV_NAME_FILTER = "";
private static final int REQUEST_SELECT_DEVICE = 1;
private static final int REQUEST_ENABLE_BT = 2;
private static final int UART_PROFILE_READY = 10;
private static final int UART_PROFILE_CONNECTED = 20;
public static final int UART_PROFILE_DISCONNECTED = 21;
private static final int STATE_OFF = 10;
private static final int PERMISSION_REQUEST_COARSE_LOCATION = 1;
TextView mRemoteRssiVal;
RadioGroup mRg;
private int mState = UART_PROFILE_DISCONNECTED;
private static UartService mService = null;
private static BluetoothDevice mDevice = null;
private BluetoothAdapter mBtAdapter = null;
private ListView messageListView;
private ArrayAdapter<String> listAdapter;
private Button SelectButton, DisconnectButton;
private EditText edtMessage;
private static Context context;
/**
* ATTENTION: This was auto-generated to implement the App Indexing API.
* See https://g.co/AppIndexing/AndroidStudio for more information.
*/
private GoogleApiClient client;
private static TextView DeviceInfo;
private static TextView DeviceName;
private static TextView Manufacturer;
public static boolean isConnected;
public static boolean isSetting;
public static boolean isReading;
public static boolean isManual;
public static boolean isFunctional;
public static boolean isBootloader;
public static byte[] SettingValues;
public static byte[] ReadingValues;
public static byte[] ManualValues;
public static byte[] FunctionalValues;
private static byte[] Connectcmd = new byte[5];
public static int STX = 0x3E; // '>'
public static int ETX = 0x23; // '#'
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DeviceInfo = (TextView) findViewById(R.id.deviceInfo);
DeviceName = (TextView) findViewById(R.id.deviceName);
Manufacturer= (TextView) findViewById(R.id.manufacturer);
isConnected = false;
isSetting = false;
isReading = false;
isManual = false;
isFunctional = false;
isBootloader = false;
context = this;
//Enable location
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// Android M Permission check
if (this.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("This app needs location access");
builder.setMessage("Please grant location access so this app can detect beacons.");
builder.setPositiveButton(android.R.string.ok, null);
builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
#Override
#TargetApi(Build.VERSION_CODES.M)
public void onDismiss(DialogInterface dialog) {
requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, PERMISSION_REQUEST_COARSE_LOCATION);
}
});
builder.show();
}
}
mBtAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBtAdapter == null) {
Toast.makeText(this, "Bluetooth is not available", Toast.LENGTH_LONG).show();
finish();
return;
}
SelectButton = (Button) findViewById(R.id.button);
DisconnectButton = (Button) findViewById(R.id.disconnect);
DisconnectButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Serial protocol to send command on MCU
Connectcmd[0] = (byte) STX;
Connectcmd[1] = (byte) 0x02;
Connectcmd[2] = (byte) 0x44; // 'D';
Connectcmd[3] = (byte) 0x43; // 'C'
Connectcmd[4] = (byte) ETX;
try {
//send data to Banner service
SendData(Connectcmd);
sleep(500); // Wait 500ms to send data
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
MainActivity.disconnected();
setContentView(R.layout.activity_main);
finish();
} catch (Exception e) {
Log.e(TAG, "Disconnect error");
}
}
});
// Handle Select device button
SelectButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!mBtAdapter.isEnabled()) {
Log.i(TAG, "onClick - BT not enabled yet");
Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
} else {
if (SelectButton.getText().equals("SELECT CELU")) {
//Connect button pressed, open DeviceListActivity class, with popup windows that scan for devices
Log.i(TAG, "Push button CONNECT");
Intent newIntent = new Intent(context, DeviceListActivity.class);
((Activity) context).startActivityForResult(newIntent, MainActivity.REQUEST_SELECT_DEVICE);
} else {
//Disconnect button pressed
disconnected();
}
}
}
});
// Set initial UI state
// ATTENTION: This was auto-generated to implement the App Indexing API.
// See https://g.co/AppIndexing/AndroidStudio for more information.
client = new GoogleApiClient.Builder(this).addApi(AppIndex.API).build();
}
//UART service connected/disconnected
private ServiceConnection mServiceConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder rawBinder) {
mService = ((UartService.LocalBinder) rawBinder).getService();
Log.d(TAG, "onServiceConnected mService= " + mService);
if (!mService.initialize()) {
Log.e(TAG, "Unable to initialize Bluetooth");
finish();
}
}
public void onServiceDisconnected(ComponentName classname) {
//// mService.disconnect(mDevice);
mService = null;
}
};
private Handler mHandler = new Handler() {
#Override
//Handler events that received from UART service
public void handleMessage(Message msg) {
}
};
private final BroadcastReceiver UARTStatusChangeReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
final Intent mIntent = intent;
//*********************//
if (action.equals(UartService.ACTION_GATT_CONNECTED)) {
runOnUiThread(new Runnable() {
public void run() {
String currentDateTimeString = DateFormat.getTimeInstance().format(new Date());
Log.d(TAG, "CELU_CONNECT_MSG");
//btnConnectDisconnect.setText("Disconnect");
//edtMessage.setEnabled(true);
DisconnectButton.setEnabled(true);
DeviceInfo.setText("Device Information:");
DeviceName.setText(mDevice.getName() + " - Connected");
mState = UART_PROFILE_CONNECTED;
isConnected = true;
//IF COMMENTED THE APP CONNECTS!!!!!!!!!!!!!!!!!!
//ELSE IF NOT COMMENTED THE APP NEVER CONNECTS
/*if(isConnected) {
//Serial protocol to send command on MCU
Connectcmd[0] = (byte) STX;
Connectcmd[1] = (byte) 0x02;
Connectcmd[2] = (byte) 0x43; // 'C';
Connectcmd[3] = (byte) 0x54; // 'T'
Connectcmd[4] = (byte) ETX;
try {
//send data to UART service
SendData(Connectcmd);
sleep(500); // Wait 500ms to send data
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
new Handler().postDelayed(mUpdateTimeTask, 2000);
}
else
{
isConnected = false;
}*/
new Handler().postDelayed(mUpdateTimeTask, 2000);
}
});
}
//*********************//
if (action.equals(UartService.ACTION_GATT_DISCONNECTED)) {
runOnUiThread(new Runnable() {
public void run() {
Log.d(TAG, "HW_DISCONNECT_MSG");
DisconnectButton.setEnabled(false);
DeviceName.setText("Not Connected");
mState = UART_PROFILE_DISCONNECTED;
mService.close();
//setUiState();
}
});
}
//Enable notifivcation on UART service//
if (action.equals(UartService.ACTION_GATT_SERVICES_DISCOVERED)) {
mService.enableTXNotification();
}
//*********************//
if (action.equals(UartService.ACTION_DATA_AVAILABLE)) {
final byte[] txValue = intent.getByteArrayExtra(UartService.EXTRA_DATA);
try {
ParsingPacket(txValue);
} catch (Exception e) {
Log.e(TAG, e.toString());
}
}
//*********************//
if (action.equals(UartService.DEVICE_DOES_NOT_SUPPORT_BLE_UART)) {
showMessage("Device doesn't support UART over BLE Celu . Disconnecting");
mService.disconnect();
}
}
};
private static void ParsingPacket(byte[] packet) throws Exception {
if (packet.length == 0) {
// received empty packet
isConnected = false;
isSetting = false;
isReading = false;
isManual = false;
isFunctional = false;
isBootloader = false;
}
if(isSetting){
isSetting = false;
SettingValues = packet.clone();
String text = new String(SettingValues, "UTF-8");
Log.d(TAG, text);
}
if(isReading){
ReadingValues= packet;
ReadActivity.updateMeasure(ReadingValues);
//ReadActivity.addData(packet);
//String text = new String(ReadingValues, "UTF-8");
Log.d("Length ", String.format("%02d", (int) ReadingValues.length));
for(int i=0; i<ReadingValues.length; i++) {
String text = String.format("%02x", (int) ReadingValues[i]);
Log.d(TAG, text);
}
}
if(isManual){
isManual = false;
ManualValues = packet.clone();
String text = new String(ManualValues, "UTF-8");
Log.d(TAG, text);
}
if(isFunctional){
isFunctional = false;
FunctionalValues = packet.clone();
String text = new String(FunctionalValues, "UTF-8");
Log.d(TAG, text);
}
if(isBootloader){
isBootloader = false;
// do samething
}
}
private Runnable mUpdateTimeTask = new Runnable() {
public void run() {
if(DeviceName.getText()!="Not Connected") {
Intent connectedIntent = new Intent(getApplicationContext(), MenuActivity.class); //new Intent("com.antertech.mybleapplication.MenuActivity");
startActivity(connectedIntent);
}
}
};
private void service_init() {
Intent bindIntent = new Intent(this, UartService.class);
bindService(bindIntent, mServiceConnection, Context.BIND_AUTO_CREATE);
LocalBroadcastManager.getInstance(this).registerReceiver(UARTStatusChangeReceiver, makeGattUpdateIntentFilter());
}
private static IntentFilter makeGattUpdateIntentFilter() {
final IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(UartService.ACTION_GATT_CONNECTED);
intentFilter.addAction(UartService.ACTION_GATT_DISCONNECTED);
intentFilter.addAction(UartService.ACTION_GATT_SERVICES_DISCOVERED);
intentFilter.addAction(UartService.ACTION_DATA_AVAILABLE);
intentFilter.addAction(UartService.DEVICE_DOES_NOT_SUPPORT_BLE_UART);
return intentFilter;
}
#Override
public void onStart() {
super.onStart();// ATTENTION: This was auto-generated to implement the App Indexing API.
// See https://g.co/AppIndexing/AndroidStudio for more information.
client.connect();
// ATTENTION: This was auto-generated to implement the App Indexing API.
// See https://g.co/AppIndexing/AndroidStudio for more information.
AppIndex.AppIndexApi.start(client, getIndexApiAction());
}
#Override
public void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy()");
try {
LocalBroadcastManager.getInstance(this).unregisterReceiver(UARTStatusChangeReceiver);
} catch (Exception ignore) {
Log.e(TAG, ignore.toString());
}
unbindService(mServiceConnection);
mService.stopSelf();
mService = null;
}
#Override
protected void onStop() {
Log.d(TAG, "onStop");
super.onStop();// ATTENTION: This was auto-generated to implement the App Indexing API.
// See https://g.co/AppIndexing/AndroidStudio for more information.
AppIndex.AppIndexApi.end(client, getIndexApiAction());
// ATTENTION: This was auto-generated to implement the App Indexing API.
// See https://g.co/AppIndexing/AndroidStudio for more information.
client.disconnect();
}
#Override
protected void onPause() {
Log.d(TAG, "onPause");
super.onPause();
}
#Override
protected void onRestart() {
super.onRestart();
Log.d(TAG, "onRestart");
}
#Override
public void onResume() {
super.onResume();
Log.d(TAG, "onResume");
if (!mBtAdapter.isEnabled()) {
Log.i(TAG, "onResume - BT not enabled yet");
Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
}
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case REQUEST_SELECT_DEVICE:
//When the DeviceListActivity return, with the selected device address
if (resultCode == Activity.RESULT_OK && data != null) {
String deviceAddress = data.getStringExtra(BluetoothDevice.EXTRA_DEVICE);
mDevice = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(deviceAddress);
Log.d(TAG, "... onActivityResultdevice.address==" + mDevice + " mserviceValue " + mService);
mService.connect(deviceAddress);
//setContentView(R.layout.activity_setting);
((TextView) findViewById(R.id.deviceName)).setText(mDevice.getName() + " - Connecting...");
}
break;
case REQUEST_ENABLE_BT:
// When the request to enable Bluetooth returns
if (resultCode == Activity.RESULT_OK) {
Toast.makeText(this, "Bluetooth has turned on ", Toast.LENGTH_SHORT).show();
} else {
// User did not enable Bluetooth or an error occurred
Log.d(TAG, "BT not enabled");
Toast.makeText(this, "Problem in BT Turning ON ", Toast.LENGTH_SHORT).show();
finish();
}
break;
default:
Log.e(TAG, "wrong request code");
break;
}
}
#Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
}
public static void SendData(byte[] text) {
mService.writeRXCharacteristic(text);
Log.i(TAG, "Message send to Target");
}
public static void disconnected() {
if (mDevice != null) {
mService.disconnect();
Log.i(TAG, "Push Button DISCONNECT");
}
}
private void showMessage(String msg) {
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
}
#Override
public void onBackPressed() {
if (mState == UART_PROFILE_CONNECTED) {
Intent startMain = new Intent(Intent.ACTION_MAIN);
startMain.addCategory(Intent.CATEGORY_HOME);
startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(startMain);
showMessage("CELU TPE running in background.\n Disconnect to exit");
} else {
new AlertDialog.Builder(this)
.setIcon(android.R.drawable.ic_dialog_alert)
.setTitle(R.string.popup_title)
.setMessage(R.string.popup_message)
.setPositiveButton(R.string.popup_yes, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
})
.setNegativeButton(R.string.popup_no, null)
.show();
}
}
#Override
public void onRequestPermissionsResult(int requestCode,
String permissions[],
int[] grantResults) {
switch (requestCode) {
case PERMISSION_REQUEST_COARSE_LOCATION: {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Log.d(TAG, "coarse location permission granted");
} else {
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Functionality limited");
builder.setMessage("Since location access has not been granted, this app will not be able to discover beacons when in the background.");
builder.setPositiveButton(android.R.string.ok, null);
builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
#Override
public void onDismiss(DialogInterface dialog) {
}
});
builder.show();
}
return;
}
}
}
/**
* ATTENTION: This was auto-generated to implement the App Indexing API.
* See https://g.co/AppIndexing/AndroidStudio for more information.
*/
public Action getIndexApiAction() {
Thing object = new Thing.Builder()
.setName("Main Page") // TODO: Define a title for the content shown.
// TODO: Make sure this auto-generated URL is correct.
.setUrl(Uri.parse("http://[ENTER-YOUR-URL-HERE]"))
.build();
return new Action.Builder(Action.TYPE_VIEW)
.setObject(object)
.setActionStatus(Action.STATUS_TYPE_COMPLETED)
.build();
}
}
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 5 years ago.
Error I'm getting null point exception in Bluetooth when I'm starting a service.
LiveFragment.class
public class LiveFragment extends Fragment {
// Intent request codes
private static final int REQUEST_CONNECT_DEVICE_SECURE = 1;
private static final int REQUEST_CONNECT_DEVICE_INSECURE = 2;
private static final int REQUEST_ENABLE_BT = 3;
private BluetoothAdapter mBluetoothAdapter =null;
public BluetoothChatService mChatService = null;
private PowerManager.WakeLock wakeLock = null;
private PowerManager powerManager = null;
private String mConnectedDeviceName = null;
private boolean isServiceBound;
private boolean preRequisites = true;
private SharedPreferences prefs;
private BroadcastReceiver broadcastReceiver;
private Context c;
private AbstractGatewayService ab;
protected ImageView blue_onoffBut, gps_Button, obd_inidca, ss_button, bluetooth_indicator, gps_indicator,obd_connectButt;
protected TextView ss_Status,btStatusTextView,obdStatusTextView,gpsStatusTextView;
private LinearLayout vv;
protected BluetoothSocket sock = null;
public LiveFragment() {
// Required empty public constructor
}
private final Runnable mQueueCommands = new Runnable() {
public void run() {
Log.d(TAG, "Runnable mQueueCommands ()");
if (ab != null && ab.isRunning() && ab.queueEmpty()) {
queueCommands();
}
// run again in period defined in preferences
new Handler().postDelayed(mQueueCommands, 4000);
}
};
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
final View view = inflater.inflate(R.layout.fragment_live, container, false);
blue_onoffBut = (ImageView) view.findViewById(R.id.blutooth_butoon);
gps_Button = (ImageView) view.findViewById(R.id.gps_button);
obd_inidca = (ImageView) view.findViewById(R.id.obd_Indicator);
ss_button = (ImageView) view.findViewById(ssButton);
gps_indicator = (ImageView) view.findViewById(R.id.gps_indicator);
bluetooth_indicator = (ImageView) view.findViewById(R.id.bluetooth_indicator);
obd_connectButt = (ImageView) view.findViewById(R.id.Obd_Connect_Button);
ss_Status = (TextView) view.findViewById(R.id.statusTx);
btStatusTextView = (TextView) view.findViewById(R.id.blue);
obdStatusTextView = (TextView) view.findViewById(R.id.obd);
gpsStatusTextView = (TextView) view.findViewById(R.id.gps);
vv = (LinearLayout) view.findViewById(R.id.fragment_live_layout);
ss_Status.setTextColor(getResources().getColor(R.color.colorGreen));
if (mBluetoothAdapter.isEnabled()) {
bluetooth_indicator.setImageResource(R.drawable.green_circle);
} else {
bluetooth_indicator.setImageResource(R.drawable.red_circle);
}
gps_Button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final LocationManager manager = (LocationManager) getActivity().getSystemService( Context.LOCATION_SERVICE );
if ( !manager.isProviderEnabled( LocationManager.GPS_PROVIDER ) ) {
buildAlertMessageNoGps();
}
else {
showToast("Already GPS is ON");
}
}
});
blue_onoffBut.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!mBluetoothAdapter.isEnabled()) {
mBluetoothAdapter.enable();
showToast("Bluetooth Turned ON"+"\n"+"Connect Your OBD now");
bluetooth_indicator.setImageResource(R.drawable.green_circle);
mChatService = new BluetoothChatService(getActivity(), mHandler);
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();
}
}
} else if (mBluetoothAdapter.isEnabled()) {
mBluetoothAdapter.disable();
mBluetoothAdapter.cancelDiscovery();
obd_inidca.setImageResource(R.drawable.red_circle);
showToast("Bluetooth Turned OFF");
bluetooth_indicator.setImageResource(R.drawable.red_circle);
}
}
});
ss_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mBluetoothAdapter.isEnabled() && mChatService.getState() == BluetoothChatService.STATE_CONNECTED) {
startLiveData();
} else if (!mBluetoothAdapter.isEnabled()) {
showToast("Turn ON Bluetooth to Continue");
}
else if (!(mChatService.getState() == BluetoothChatService.STATE_CONNECTED)){
showToast("Select your OBD to Start ");
}
}
});
obd_connectButt.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(mBluetoothAdapter.isEnabled()) {
Intent serverIntent = new Intent(getActivity(), DeviceListActivity.class);
startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE_SECURE);
}
else if (!mBluetoothAdapter.isEnabled()){
showToast("Turn ON Bluetooth to Connect OBD");
}
}
});
return view;
}
private ServiceConnection serviceConn = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName className, IBinder binder) {
Log.d(TAG, className.toString() + " service is bound");
isServiceBound = true;
ab = ((AbstractGatewayService.AbstractGatewayServiceBinder) binder).getService();
ab.setContext(getActivity());
Log.d(TAG, "Starting live data");
try {
ab.startService();
if (preRequisites)
btStatusTextView.setText("Connected");
} catch (IOException ioe) {
Log.e(TAG, "Failure Starting live data");
btStatusTextView.setText("Connection failed");
doUnbindService();
}
}
#Override
protected Object clone() throws CloneNotSupportedException {
Log.d(TAG, "CloneNotSupportedException ");
return super.clone();
}
#Override
public void onServiceDisconnected(ComponentName className) {
Log.d(TAG, className.toString() + " service is unbound");
isServiceBound = false;
}
};
public static String LookUpCommand(String txt) {
Log.d(TAG, "LookUpCommand() ");
for (AvailableCommandNames item : AvailableCommandNames.values()) {
if (item.getValue().equals(txt)) return item.name();
}
return txt;
}
public void updateTextView(final TextView view, final String txt) {
Log.d(TAG, "updateTextView() ");
new Handler().post(new Runnable() {
public void run() {
view.setText(txt);
}
});
}
#Subscribe(threadMode = ThreadMode.MAIN)
public void stateUpdate(ObdCommandJob job) {
final String cmdName = job.getCommand().getName();
String cmdResult = "";
final String cmdID = LookUpCommand(cmdName);
Log.d(TAG, "stateUpdate() ");
if (job.getState().equals(ObdCommandJob.ObdCommandJobState.EXECUTION_ERROR)) {
cmdResult = job.getCommand().getResult();
if (cmdResult != null && isServiceBound) {
obdStatusTextView.setText(cmdResult.toLowerCase());
}
} else if (job.getState().equals(ObdCommandJob.ObdCommandJobState.BROKEN_PIPE)) {
if (isServiceBound)
stopLiveData();
} else if (job.getState().equals(ObdCommandJob.ObdCommandJobState.NOT_SUPPORTED)) {
cmdResult = "NA";
} else {
cmdResult = job.getCommand().getFormattedResult();
if (isServiceBound)
obdStatusTextView.setText("Receiving data...");
}
cmdResult.replace("NODATA", "0");
if (vv.findViewWithTag(cmdID) != null) {
TextView existingTV = (TextView) vv.findViewWithTag(cmdID);
existingTV.setText(cmdResult);
}
}
#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
if (mBluetoothAdapter == null) {
FragmentActivity activity = getActivity();
Toast.makeText(activity, "No Bluetooth Feature in Device", Toast.LENGTH_LONG).show();
activity.finish();
}
}
#Override
public void onStart() {
super.onStart();
final LocationManager manager = (LocationManager) getActivity().getSystemService( Context.LOCATION_SERVICE );
if ( !manager.isProviderEnabled( LocationManager.GPS_PROVIDER ) ) {
gps_indicator.setImageResource(R.drawable.red_circle);
}
if(mBluetoothAdapter.isEnabled()){
mBluetoothAdapter.disable();
bluetooth_indicator.setImageResource(R.drawable.red_circle);
}
}
#Override
public void onResume() {
super.onResume();
powerManager = (PowerManager) getActivity().getSystemService(Context.POWER_SERVICE);
wakeLock = powerManager.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "ObdReader");
final LocationManager manager = (LocationManager) getActivity().getSystemService( Context.LOCATION_SERVICE );
if ( manager.isProviderEnabled( LocationManager.GPS_PROVIDER ) ) {
gps_indicator.setImageResource(R.drawable.green_circle);
} else {
gps_indicator.setImageResource(R.drawable.red_circle);
}
EventBus.getDefault().register(this);
if(mBluetoothAdapter.isEnabled()) {
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 void onPause() {
super.onPause();
Log.d(TAG, "Pausing..");
releaseWakeLockIfHeld();
EventBus.getDefault().unregister(this);
}
private void showToast(String message) {
final Toast toast = Toast.makeText(getContext(), message, Toast.LENGTH_SHORT);
toast.show();
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
toast.cancel();
}
}, 500);
}
#Override
public void onDestroy() {
/* unregisterReceiver(mReceiver);*/
super.onDestroy();
releaseWakeLockIfHeld();
if (mChatService != null) {
mChatService.stop();
}
if (isServiceBound) {
doUnbindService();
}
if (mBluetoothAdapter.isEnabled()) {
mBluetoothAdapter.disable();
}
showToast("Take Care!");
}
private void startLiveData() {
if (mChatService.getState() == BluetoothChatService.STATE_CONNECTED) {
Log.d(TAG, "Starting live data..");
ss_Status.setText("Stop");
ss_Status.setTextColor(getResources().getColor(R.color.colorRed));
wakeLock.acquire();
ss_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ss_Status.setText("Go Live");
ss_Status.setTextColor(getResources().getColor(R.color.colorGreen));
stopLiveData();
}
});
doBindService();
LocalBroadcastManager.getInstance(getActivity()).registerReceiver((broadcastReceiver), new IntentFilter(OBD_GATEWAY_SERVICE));
new Handler().post(mQueueCommands);
}
}
private void stopLiveData() {
Log.d(TAG, "Stopping live data..");
releaseWakeLockIfHeld();
new Handler().removeCallbacks(mQueueCommands);
ss_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ss_Status.setText("Go Live");
ss_Status.setTextColor(getResources().getColor(R.color.colorGreen));
startLiveData();
}
});
doUnbindService();
LocalBroadcastManager.getInstance(getActivity()).unregisterReceiver(broadcastReceiver);
}
private void queueCommands() {
Log.d(TAG, "LiveFragment queueCommands() ");
if (isServiceBound) {
for (ObdCommand Command : ObdConfig.getCommands()) {
if (prefs.getBoolean(Command.getName(), true))
ab.queueJob(new ObdCommandJob(Command));
}
}
}
private void doBindService() {
if (!isServiceBound) {
Log.d(TAG, "Binding OBD service..");
if (preRequisites) {
btStatusTextView.setText("Connecting.....");
Intent serviceIntent = new Intent(getActivity(),ObdGatewayService.class);
getActivity().bindService(serviceIntent, serviceConn, Context.BIND_AUTO_CREATE);
}
}
}
private void doUnbindService() {
if (isServiceBound) {
if (ab.isRunning()) {
ab.stopService();
if (preRequisites)
btStatusTextView.setText("Ready...");
}
Log.d(TAG, "Unbinding OBD service..");
getActivity().unbindService(serviceConn);
isServiceBound = false;
obdStatusTextView.setText("Disconnected");
}
}
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:
obd_inidca.setImageResource(R.drawable.green_circle);
break;
case BluetoothChatService.STATE_CONNECTING:
obd_inidca.setImageResource(R.drawable.orange_circle);
break;
case BluetoothChatService.STATE_LISTEN:
case BluetoothChatService.STATE_NONE:
obd_inidca.setImageResource(R.drawable.red_circle);
break;
}
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();
obd_inidca.setImageResource(R.drawable.green_circle);
}
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) {
try {
connectDevice(data, true);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
private void connectDevice(Intent data, boolean secure) throws IOException {
// Get the device MAC address
String address = data.getExtras()
.getString(DeviceListActivity.EXTRA_DEVICE_ADDRESS);
// Get the BluetoothDevice object
BluetoothDevice dev = mBluetoothAdapter.getRemoteDevice(address);
// Attempt to connect to the device
mChatService.connect(dev, secure);
}.
This is ObdGateway service class:
public class ObdGatewayService extends AbstractGatewayService {
private static final String TAG = ObdGatewayService.class.getName();
#Inject
SharedPreferences prefs;
private BluetoothDevice dev = null;
private BluetoothSocket sock = null;
private BluetoothChatService mChatservice = null;
private BluetoothAdapter bluetoothAdapter =null;
public final static String JOB_NAME_STAMP = "Name";
public final static String JOB_STATE_STAMP = "State";
public final static String JOB_RESULT_STAMP = "Result";
public final static String JOB_FORMATED_RESULT_STAMP = "Formated REsult";
public final static String OBD_GATEWAY_SERVICE = "com.samplersoft.saz.Obd.ObdGatewayService";
public void startService() throws IOException {
Log.d(TAG, "Starting service..");
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
// get the remote Bluetooth device
if(mChatservice.getState() != BluetoothChatService.STATE_CONNECTED){
Toast.makeText(ctx, "No Bluetooth device selected", Toast.LENGTH_LONG).show();
// log error
Log.e(TAG, "No Bluetooth device has been selected.");
stopService();
throw new IOException();
}
else
{
Log.d(TAG, "Stopping Bluetooth discovery.");
bluetoothAdapter.cancelDiscovery();
try {
startObdConnection();
} catch (Exception e) {
Log.e(
TAG,
"There was an error while establishing connection. -> "
+ e.getMessage()
);
// in case of failure, stop this service.
stopService();
throw new IOException();
}
}
}
private void startObdConnection() throws IOException {
Log.d(TAG, "Starting OBD connection..");
isRunning = true;
if(mChatservice.getState() == BluetoothChatService.STATE_CONNECTED){
// Let's configure the connection.
Log.d(TAG, "Queueing jobs for connection configuration..");
queueJob(new ObdCommandJob(new ObdResetCommand()));
try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); }
queueJob(new ObdCommandJob(new EchoOffCommand()));
queueJob(new ObdCommandJob(new EchoOffCommand()));
queueJob(new ObdCommandJob(new LineFeedOffCommand()));
queueJob(new ObdCommandJob(new TimeoutCommand(62)));
// Get protocol from preferences
queueJob(new ObdCommandJob(new SelectProtocolCommand(ObdProtocols.valueOf("AUTO"))));
// Job for returning dummy data
queueJob(new ObdCommandJob(new AmbientAirTemperatureCommand()));
queueCounter = 0L;
Log.d(TAG, "Initialization jobs queued.");
}
else {
stopService();
throw new IOException();
}
}
#Override
public void queueJob(ObdCommandJob job) {
// This is a good place to enforce the imperial units option
//job.getCommand().useImperialUnits(prefs.getBoolean(ConfigActivity.IMPERIAL_UNITS_KEY, false));
// Now we can pass it along
super.queueJob(job);
}
protected void executeQueue() throws InterruptedException {
Log.d(TAG, "Executing queue..");
while (!Thread.currentThread().isInterrupted()) {
ObdCommandJob job = null;
try {
job = jobsQueue.take();
// log job
Log.d(TAG, "Taking job[" + job.getId() + "] from queue..");
if (job.getState().equals(ObdCommandJob.ObdCommandJobState.NEW)) {
Log.d(TAG, "Job state is NEW. Run it..");
job.setState(ObdCommandJob.ObdCommandJobState.RUNNING);
if (sock.isConnected()) {
job.getCommand().run(sock.getInputStream(), sock.getOutputStream());
} else {
job.setState(ObdCommandJob.ObdCommandJobState.EXECUTION_ERROR);
Log.e(TAG, "Can't run command on a closed socket.");
}
} else
// log not new job
Log.e(TAG,
"Job state was not new, so it shouldn't be in queue. BUG ALERT!");
} catch (InterruptedException i) {
Thread.currentThread().interrupt();
} catch (UnsupportedCommandException u) {
if (job != null) {
job.setState(ObdCommandJob.ObdCommandJobState.NOT_SUPPORTED);
}
Log.d(TAG, "Command not supported. -> " + u.getMessage());
} catch (IOException io) {
if (job != null) {
if(io.getMessage().contains("Broken pipe"))
job.setState(ObdCommandJob.ObdCommandJobState.BROKEN_PIPE);
else
job.setState(ObdCommandJob.ObdCommandJobState.EXECUTION_ERROR);
}
Log.e(TAG, "IO error. -> " + io.getMessage());
} catch (Exception e) {
if (job != null) {
job.setState(ObdCommandJob.ObdCommandJobState.EXECUTION_ERROR);
}
Log.e(TAG, "Failed to run command. -> " + e.getMessage());
}
ObdCommandJob job2 = job;
if(job2 !=null)
EventBus.getDefault().post(job2);
}
}
public void stopService() {
Log.d(TAG, "Stopping service..");
jobsQueue.clear();
isRunning = false;
if (sock != null)
// close socket
try {
sock.close();
} catch (IOException e) {
Log.e(TAG, e.getMessage());
}
// kill service
stopSelf();
}
public boolean isRunning() {
return isRunning;
}
}.
This is Abstract Class where service method gets called from from Livefragment Class from serivceConnection().
public abstract class AbstractGatewayService extends RoboService {
private static final String TAG = AbstractGatewayService.class.getName();
private final IBinder binder = new AbstractGatewayServiceBinder();
protected Context ctx;
protected boolean isRunning = false;
protected Long queueCounter = 0L;
protected BlockingQueue<ObdCommandJob> jobsQueue = new LinkedBlockingQueue<>();
Thread t = new Thread(new Runnable() {
#Override
public void run() {
try {
executeQueue();
} catch (InterruptedException e) {
t.interrupt();
}
}
});
protected LocalBroadcastManager broadcastManager;
#Override
public IBinder onBind(Intent intent) {
return binder;
}
#Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "Creating service..");
final BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
t.start();
Log.d(TAG, "Service created.");
}
#Override
public void onDestroy() {
super.onDestroy();
Log.d(TAG, "Destroying service...");
t.interrupt();
broadcastManager = LocalBroadcastManager.getInstance(this);
Log.d(TAG, "Service destroyed.");
}
public boolean isRunning() {
return isRunning;
}
public boolean queueEmpty() {
return jobsQueue.isEmpty();
}
public void queueJob(ObdCommandJob job) {
queueCounter++;
Log.d(TAG, "Adding job[" + queueCounter + "] to queue..");
job.setId(queueCounter);
try {
jobsQueue.put(job);
Log.d(TAG, "Job queued successfully.");
} catch (InterruptedException e) {
job.setState(ObdCommandJob.ObdCommandJobState.QUEUE_ERROR);
Log.e(TAG, "Failed to queue job.");
}
}
public void setContext(Context c) {
ctx = c;
}
abstract protected void executeQueue() throws InterruptedException;
abstract public void startService() throws IOException;
abstract public void stopService();
public class AbstractGatewayServiceBinder extends Binder {
public AbstractGatewayService getService() {
return AbstractGatewayService.this;
}
}
}.
You are getting the exception because in class ObdGatewayService your class member mChatservice is not the same as mChatservice in class LiveFragment
They are just different member variables
mChatservice gets assigned like this in your Fragment
mChatService = new BluetoothChatService(getActivity(), mHandler);
You need to pass this reference to ObdGatewayService 's startService() like this where ever you are instantiating/invoking it:-
ObdGatewayService ogs;
....
ogs.startservice(mChatservice); // This is fragment's member reference
And in ObdGatewayService you have to assign it accordingly:-
public void startService(BluetoothChatService _mChatservice) throws IOException {
Log.d(TAG, "Starting service..");
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
mChatservice = _mChatservice //Assignment YOU ARE MISSING THIS
.......
.......
}
i am using this code for printing:
public class BPrinterActivity extends Activity implements Runnable {
protected static final String TAG = "TAG";
private static final int REQUEST_CONNECT_DEVICE = 1;
private static final int REQUEST_ENABLE_BT = 2;
private Button mScan, mPrint, mDisc;
private UUID applicationUUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
private ProgressDialog mBluetoothConnectProgressDialog;
private BluetoothSocket mBluetoothSocket;
private BluetoothDevice mBluetoothDevice;
private BluetoothAdapter mBluetoothAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_bprinter);
mScan = (Button) findViewById(R.id.Scan);
mScan.setOnClickListener(new View.OnClickListener() {
public void onClick(View mView) {
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter == null) {
Toast.makeText(BPrinterActivity.this, "Message1", 2000).show();
} else {
if (!mBluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent,REQUEST_ENABLE_BT);
} else {
ListPairedDevices();
Intent connectIntent = new Intent(BPrinterActivity.this,DeviceListActivity.class);
startActivityForResult(connectIntent,REQUEST_CONNECT_DEVICE);
}
}
}
});
mPrint = (Button) findViewById(R.id.mPrint);
mPrint.setOnClickListener(new View.OnClickListener() {
public void onClick(View mView) {
Thread t = new Thread() {
public void run() {
try {
String BILL = "";
BILL = "1234567812345678ABCDEFGH";
BILL="الرئيسية";
BILL = "ABCDEFGH";
OutputStream os = mBluetoothSocket.getOutputStream();
os.write(BILL.getBytes());
} catch (Exception e) {
Log.e("Main", "Exe ", e);
}
}
};
t.start();
}
});
mDisc = (Button) findViewById(R.id.dis);
mDisc.setOnClickListener(new View.OnClickListener() {
public void onClick(View mView) {
if (mBluetoothAdapter != null)
mBluetoothAdapter.disable();
}
});
}// onCreate
#Override
protected void onDestroy() {
super.onDestroy();
try {
if (mBluetoothSocket != null)
mBluetoothSocket.close();
} catch (Exception e) {
Log.e("Tag", "Exe ", e);
}
}
#Override
public void onBackPressed() {
try {
if (mBluetoothSocket != null)
mBluetoothSocket.close();
} catch (Exception e) {
Log.e("Tag", "Exe ", e);
}
setResult(RESULT_CANCELED);
finish();
}
public void onActivityResult(int mRequestCode, int mResultCode,Intent mDataIntent) {
super.onActivityResult(mRequestCode, mResultCode, mDataIntent);
switch (mRequestCode) {
case REQUEST_CONNECT_DEVICE:
if (mResultCode == Activity.RESULT_OK) {
Bundle mExtra = mDataIntent.getExtras();
String mDeviceAddress = mExtra.getString("DeviceAddress");
Log.v(TAG, "Coming incoming address " + mDeviceAddress);
mBluetoothDevice = mBluetoothAdapter.getRemoteDevice(mDeviceAddress);
mBluetoothConnectProgressDialog = ProgressDialog.show(this,"Connecting...", mBluetoothDevice.getName() + " : "+ mBluetoothDevice.getAddress(), true, false);
Thread mBlutoothConnectThread = new Thread(this);
mBlutoothConnectThread.start();
// pairToDevice(mBluetoothDevice); This method is replaced by
// progress dialog with thread
}
break;
case REQUEST_ENABLE_BT:
if (mResultCode == Activity.RESULT_OK) {
ListPairedDevices();
Intent connectIntent = new Intent(BPrinterActivity.this,DeviceListActivity.class);
startActivityForResult(connectIntent, REQUEST_CONNECT_DEVICE);
} else {
Toast.makeText(BPrinterActivity.this, "Message", 2000).show();
}
break;
}
}
private void ListPairedDevices() {
Set<BluetoothDevice> mPairedDevices = mBluetoothAdapter.getBondedDevices();
if (mPairedDevices.size() > 0) {
for (BluetoothDevice mDevice : mPairedDevices) {
Log.v(TAG, "PairedDevices: " + mDevice.getName() + " "+ mDevice.getAddress());
}
}
}
public void run() {
try {
mBluetoothSocket = mBluetoothDevice.createRfcommSocketToServiceRecord(applicationUUID);
mBluetoothAdapter.cancelDiscovery();
mBluetoothSocket.connect();
mHandler.sendEmptyMessage(0);
} catch (IOException eConnectException) {
Log.d(TAG, "CouldNotConnectToSocket", eConnectException);
closeSocket(mBluetoothSocket);
return;
}
}
private void closeSocket(BluetoothSocket nOpenSocket) {
try {
nOpenSocket.close();
Log.d(TAG, "SocketClosed");
} catch (IOException ex) {
Log.d(TAG, "CouldNotCloseSocket");
}
}
private Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
mBluetoothConnectProgressDialog.dismiss();
Toast.makeText(BPrinterActivity.this, "DeviceConnected", 5000).show();
}
};
public static byte intToByteArray(int value) {
byte[] b = ByteBuffer.allocate(4).putInt(value).array();
for (int k = 0; k < b.length; k++) {
System.out.println("Selva [" + k + "] = " + "0x"+ UnicodeFormatter.byteToHex(b[k]));
}
return b[3];
}
public byte[] sel(int val) {
ByteBuffer buffer = ByteBuffer.allocate(2);
buffer.putInt(val);
buffer.flip();
return buffer.array();
}
}
this code work very well but before printing this will going to scan device pairing it and then print now i have printer device address now i directly want to print without scan or paring