I am trying to make an android app that scans a specific bluetooth device as a background service. After the phone is in a certain range of the Bluetooth device, measured by reading RSSI, the background service will start the action displayed to the user. If the phone is moved outside the range of the Bluetooth device (after the RSSI value exceeds a certain threshold), activity should be killed.
Here is the code for the help desk:
public class BeaconScanService extends Service implements BluetoothAdapter.LeScanCallback { private Service self = this; public static final String UNLOCK = "unlock"; public static final String STATUS = "status"; public static final String SIGNAL = "signal"; public static final String GET_SIGNAL = "get_signal";
Ultimately, I want this background service to start at boot, but for testing purposes, I can create or destroy this service from Activity, which should also display an RSSI value:
public class MainActivity extends Activity implements OnClickListener { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button btnScan = (Button) findViewById(R.id.btnScan); Button btnUnscan = (Button) findViewById(R.id.btnUnscan); btnScan.setOnClickListener(this); btnUnscan.setOnClickListener(this); } @Override protected void onResume() { super.onResume(); registerReceiver(mReceiver, new IntentFilter(BeaconScanService.SIGNAL)); } @Override protected void onPause() { super.onPause(); unregisterReceiver(mReceiver); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.btnScan: Intent i = new Intent(this,BeaconScanService.class); startService(i); break; case R.id.btnUnscan: Intent i = new Intent(this,BeaconScanService.class); stopService(i); break; } } private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Bundle bundle = intent.getExtras(); if(bundle != null) { int sig = bundle.getInt(BeaconScanService.GET_SIGNAL); TextView rssiView = (TextView) findViewById(R.id.text_rssi); rssiView.setText(String.format("%ddBm", sig)); } } }; }
This is the layout for MainActivity:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity"> <Button android:id="@+id/btnScan" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Scan"/> <Button android:id="@+id/btnUnscan" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Stop Scan" android:layout_below="@+id/btnScan"/> <TextView android:id="@+id/text_rssi" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:textAppearance="?android:attr/textAppearanceListItem" android:text="dBm" android:layout_below="@+id/btnUnscan"/> </RelativeLayout>
In an activity that starts and ends with BeaconScanService, the BroadcastReceiver is logged as follows:
@Override protected void onResume() { super.onResume(); registerReceiver(beaconScanReceiver, new IntentFilter(BeaconScanService.UNLOCK)); }
and BroadcastReceiver looks like this:
private final BroadcastReceiver beaconScanReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Bundle bundle = intent.getExtras(); if(bundle != null) { int status = bundle.getInt(BeaconScanService.STATUS); if(status == 0) { finish(); } } } };
When I run this code, I can start and stop the BeaconScanService, and I know that the service scans the Bluetooth device due to debugging toasts. As far as I can tell, the code breaks somewhere in the service handler. RSSI is not displayed in the TextView, and MyActivity does not start when the phone approaches the Bluetooth device.
I'm not too good at aspects of the interaction between processes in Android programming, so I'm probably doing something wrong. Any thoughts?