Android BLE Scan in Background Service -


i'm trying make android app scan bluetooth device background service. once phone within range of bluetooth device, measured reading rssi, background service start activity displayed user. if phone moved out of range of bluetooth device, (after rssi value beyond threshold,) activity should killed.

here code background service:

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";      //desired device find     private static final string targetmac = "e1:be:a8:1a:8b:a0";      //class handle saving rssi values , detecting bluetooth proximity     private proxdetector proxy;      //boolean determine if phone in bt range     static boolean inprox = false;      private bluetoothadapter mbluetoothadapter;      @override     public ibinder onbind(intent intent) {         // todo auto-generated method stub         return null;     }      @override     public void oncreate() {         super.oncreate();          //proximity detector         proxy = new proxdetector();          final bluetoothmanager bluetoothmanager =                 (bluetoothmanager) getsystemservice(context.bluetooth_service);         mbluetoothadapter = bluetoothmanager.getadapter();     }      @override     public int onstartcommand(intent intent, int flags, int startid){         /*          * need enforce bluetooth first enabled, , take          * user settings enable if have not done so.          */          if (mbluetoothadapter == null || !mbluetoothadapter.isenabled()) {             //bluetooth disabled             intent enablebtintent = new intent(bluetoothadapter.action_request_enable);             enablebtintent.addflags(intent.flag_activity_new_task);             startactivity(enablebtintent);         }          /*          * check bluetooth le support.  in production, our manifest entry keep          * installing on these devices, allow test devices or other          * sideloads report whether or not feature exists.          */         if (!getpackagemanager().hassystemfeature(packagemanager.feature_bluetooth_le)) {             toast.maketext(this, "no le support.", toast.length_short).show();             return start_sticky;         }          //begin scanning le devices         startscan();          return start_sticky;     }      @override     public void ondestroy() {         super.ondestroy();          //cancel scans in progress         mhandler.removecallbacks(mstoprunnable);         mhandler.removecallbacks(mstartrunnable);         mbluetoothadapter.stoplescan(this);     }      private runnable mstoprunnable = new runnable() {         @override         public void run() {             stopscan();         }     };     private runnable mstartrunnable = new runnable() {         @override         public void run() {             startscan();         }     };      private void startscan() {         toast.maketext(this, "scanning", toast.length_short).show();         //scan bluetooth device specified mac         mbluetoothadapter.startlescan(this);         mhandler.postdelayed(mstoprunnable, 5000);     }      private void stopscan() {         toast.maketext(this, "not scanning", toast.length_short).show();         mbluetoothadapter.stoplescan(this);         mhandler.postdelayed(mstartrunnable, 2500);     }      /* bluetoothadapter.lescancallback */      @override     public void onlescan(bluetoothdevice device, int rssi, byte[] scanrecord) {         /*         * create new beacon , pass main thread         */         toast.maketext(self, "onlescan", toast.length_short).show();         bt_beacon beacon = new bt_beacon(device.getaddress(), rssi);         mhandler.sendmessage(message.obtain(null, 0, beacon));     }      /*      * have handler process scan results on main thread      */     private handler mhandler = new handler() {          @override         public void handlemessage(message msg) {             toast.maketext(self, "handlering", toast.length_short).show();             bt_beacon beacon = (bt_beacon) msg.obj;             if(beacon.getaddress().equals(targetmac)){//only target device                 toast.maketext(self, string.format("%ddbm", beacon.getsignal()), toast.length_short).show();                 //handle proximity detection                 intent i1 = new intent(unlock);                 proxy.processprox(beacon.getsignal());                 intent i2 = new intent(signal);                 i2.putextra(get_signal, proxy.prox);                 sendbroadcast(i2);                 if(proxy.crossedline()){                     i1.putextra(status, 1);                     sendbroadcast(i1);                     inprox = true;                     intent = new intent(self,myactivity.class);                     i.addflags(intent.flag_activity_new_task);                     startactivity(i);                 }else{                     i1.putextra(status, 0);                     sendbroadcast(i1);                     inprox = false;                 }             }         }     }; } 

ultimately want background service started on boot, testing purposes, able create or destroy service activity should display 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 = new intent(this,beaconscanservice.class);                 startservice(i);                 break;              case r.id.btnunscan:                 intent = 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 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 activity started , ended beaconscanservice, broadcastreceiver registered this:

@override protected void onresume() {     super.onresume();     registerreceiver(beaconscanreceiver, new intentfilter(beaconscanservice.unlock)); } 

and broadcastreceiver looks 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 run code, can start , stop beaconscanservice fine, , know service scanning bluetooth device due debug toasts being displayed. far can tell, code breaks down somewhere in handler of service. no rssi value displayed in textview, , myactivity not started when phone brought close enough bluetooth device.

i'm not familiar interprocess communication aspects of android programming, i'm doing wrong there. thoughts?


Comments

Popular posts from this blog

javascript - RequestAnimationFrame not working when exiting fullscreen switching space on Safari -

Python ctypes access violation with const pointer arguments -