i've been able create app (thanks davidgyoung!) monitors beacons in background , subsequently opens app in background.
now app first prompt notification in status bar saying "i've detected beacon! open out app?". user click on notification open app or dismiss , ignore notification.
i've searched on stack overflow haven't had success in finding relevant beacons. did find page talks adding statusbar
notifications i'm not having success.
particularly in beaconreferenceapplication.java
, monitoringactivity.java
file. think put code in correct place (after didenterregion
) have unresolved classes areas notificationbutton
, setlatesteventinfo
, etc. can help? in advance!
beaconreferenceapplication.java:
import android.app.application; import android.app.notification; import android.app.notificationmanager; import android.app.pendingintent; import android.app.taskstackbuilder; import android.content.context; import android.content.intent; import android.support.v4.app.notificationcompat; import android.util.log; import org.altbeacon.beacon.beaconmanager; import org.altbeacon.beacon.beaconparser; import org.altbeacon.beacon.identifier; import org.altbeacon.beacon.region; import org.altbeacon.beacon.powersave.backgroundpowersaver; import org.altbeacon.beacon.startup.regionbootstrap; import org.altbeacon.beacon.startup.bootstrapnotifier; public class beaconreferenceapplication extends application implements bootstrapnotifier { private static final string tag = "beaconreferenceapp"; private regionbootstrap regionbootstrap; private backgroundpowersaver backgroundpowersaver; private boolean havedetectedbeaconssinceboot = false; private monitoringactivity monitoringactivity = null; public void oncreate() { super.oncreate(); beaconmanager beaconmanager = org.altbeacon.beacon.beaconmanager.getinstanceforapplication(this); // default androidbeaconlibrary find altbeacons. if wish make // find different type of beacon, must specify byte layout beacon's // advertisement line below. example shows how find beacon // same byte layout altbeacon beacontypecode of 0xaabb. find proper // layout expression other beacon types, web search "setbeaconlayout" // including quotes. // beaconmanager.getbeaconparsers().clear(); beaconmanager.getbeaconparsers().add(new beaconparser(). setbeaconlayout("s:0-1=feaa,m:2-2=00,p:3-3:-41,i:4-13,i:14-19")); log.d(tag, "setting background monitoring beacons , power saving"); // wake app when beacon seen region region = new region("backgroundregion", identifier.parse("2f234454f4911ba9ffa6"), null, null); regionbootstrap = new regionbootstrap(this, region); // constructing class , holding reference in custom application // class automatically cause beaconlibrary save battery whenever application // not visible. reduces bluetooth power usage 60% backgroundpowersaver = new backgroundpowersaver(this); // if wish test beacon detection in android emulator, can use code this: // beaconmanager.setbeaconsimulator(new timedbeaconsimulator() ); // ((timedbeaconsimulator) beaconmanager.getbeaconsimulator()).createtimedsimulatedbeacons(); } @override public void didenterregion(region arg0) { // in example, class sends notification user whenever beacon // matching region (defined above) first seen. log.d(tag, "did enter region."); if (!havedetectedbeaconssinceboot) { log.d(tag, "sending notification statusbar"); @suppresswarnings("deprecation") private void notify(string notificationtitle, string notificationmessage) { notificationmanager notificationmanager = (notificationmanager) getsystemservice(notification_service); @suppresswarnings("deprecation") notification notification = new notification(r.mipmap.ic_launcher, "new message", system.currenttimemillis()); intent notificationintent = new intent(this, monitoringactivity.class); pendingintent pendingintent = pendingintent.getactivity(this, 0, notificationintent, 0); notification.setlatesteventinfo(monitoringactivity.this, notificationtitle, notificationmessage, pendingintent); notificationmanager.notify(9999, notification); } } } else { if (monitoringactivity != null) { log.d(tag, "auto launching mainactivity"); // first time since boot detect beacon, launch // mainactivity intent intent = new intent(this, monitoringactivity.class); intent.setflags(intent.flag_activity_new_task); // important: make sure add android:launchmode="singleinstance" in manifest // keep multiple copies of activity getting created if user has // manually launched app. this.startactivity(intent); havedetectedbeaconssinceboot = true; } } } @override public void didexitregion(region region) { if (monitoringactivity != null) { log.d(tag,"i no longer see beacon."); } } @override public void diddeterminestateforregion(int state, region region) { if (monitoringactivity != null) { log.d(tag,"i have switched seeing/not seeing beacons: " + state); } } private void sendnotification() { notificationcompat.builder builder = new notificationcompat.builder(this) .setcontenttitle("beacon reference application") .setcontenttext("an beacon nearby.") .setsmallicon(r.mipmap.ic_launcher); taskstackbuilder stackbuilder = taskstackbuilder.create(this); stackbuilder.addnextintent(new intent(this, monitoringactivity.class)); pendingintent resultpendingintent = stackbuilder.getpendingintent( 0, pendingintent.flag_update_current ); builder.setcontentintent(resultpendingintent); notificationmanager notificationmanager = (notificationmanager) this.getsystemservice(context.notification_service); notificationmanager.notify(1, builder.build()); } public void setmonitoringactivity(monitoringactivity activity) { this.monitoringactivity = activity; } }
monitoringactivity.java:
import android.manifest; import android.annotation.suppresslint; import android.annotation.targetapi; import android.content.pm.packagemanager; import android.graphics.bitmap; import android.os.build; import android.os.bundle; import android.app.activity; import android.app.alertdialog; import android.content.dialoginterface; import android.content.intent; import android.util.log; import android.view.view; import android.webkit.websettings; import android.webkit.webview; import android.webkit.webviewclient; import android.widget.button; import android.widget.edittext; import android.widget.progressbar; import org.altbeacon.beacon.beaconmanager; public class monitoringactivity extends activity { protected static final string tag = "monitoringactivity"; private static final int permission_request_coarse_location = 1; private webview mwebview; progressbar progressbar; @override protected void oncreate(bundle savedinstancestate) { log.d(tag, "oncreate"); super.oncreate(savedinstancestate); setcontentview(r.layout.activity_monitoring); // code button notification button notificationbutton = (button) findviewbyid(r.id.notificationbutton); notificationbutton.setonclicklistener(new view.onclicklistener() { @override public void onclick(view v) { notify("title: meeting business", "msg:pittsburg 10:00 est "); } }); // code button notification mwebview = (webview) findviewbyid(r.id.activity_main_webview); progressbar = (progressbar) findviewbyid(r.id.progressbar1); websettings websettings = mwebview.getsettings(); websettings.setjavascriptenabled(true); mwebview.loadurl("http://communionchapelefca.org/edy-home"); mwebview.setwebviewclient(new myappwebviewclient()); verifybluetooth(); log.d(tag, "application launched"); 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 app can detect beacons in background."); builder.setpositivebutton(android.r.string.ok, null); builder.setondismisslistener(new dialoginterface.ondismisslistener() { @targetapi(23) @override public void ondismiss(dialoginterface dialog) { requestpermissions(new string[]{manifest.permission.access_coarse_location}, permission_request_coarse_location); } }); builder.show(); } } } private class hellowebviewclient extends webviewclient{ @override public void onpagestarted(webview view, string url, bitmap favicon) { // todo auto-generated method stub super.onpagestarted(view, url, favicon); } @override public boolean shouldoverrideurlloading(webview webview, string url) { webview.loadurl(url); return true; } @override public void onpagefinished(webview view, string url) { // todo auto-generated method stub super.onpagefinished(view, url); progressbar.setvisibility(view.gone); } } @override public void onbackpressed() { if(mwebview.cangoback()) { mwebview.goback(); } else { super.onbackpressed(); } } @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, app not able discover beacons when in background."); builder.setpositivebutton(android.r.string.ok, null); builder.setondismisslistener(new dialoginterface.ondismisslistener() { @override public void ondismiss(dialoginterface dialog) { } }); builder.show(); } return; } } } public void onrangingclicked(view view) { intent myintent = new intent(this, rangingactivity.class); this.startactivity(myintent); } @override public void onresume() { super.onresume(); ((beaconreferenceapplication) this.getapplicationcontext()).setmonitoringactivity(this); } @override public void onpause() { super.onpause(); ((beaconreferenceapplication) this.getapplicationcontext()).setmonitoringactivity(null); } private void verifybluetooth() { try { if (!beaconmanager.getinstanceforapplication(this).checkavailability()) { final alertdialog.builder builder = new alertdialog.builder(this); builder.settitle("bluetooth not enabled"); builder.setmessage("please enable bluetooth in settings , restart application."); builder.setpositivebutton(android.r.string.ok, null); builder.setondismisslistener(new dialoginterface.ondismisslistener() { @override public void ondismiss(dialoginterface dialog) { finish(); system.exit(0); } }); builder.show(); } } catch (runtimeexception e) { final alertdialog.builder builder = new alertdialog.builder(this); builder.settitle("bluetooth le not available"); builder.setmessage("sorry, device not support bluetooth le."); builder.setpositivebutton(android.r.string.ok, null); builder.setondismisslistener(new dialoginterface.ondismisslistener() { @override public void ondismiss(dialoginterface dialog) { finish(); system.exit(0); } }); builder.show(); } } }
so able fix problem using example android developers website notifications. used sample code, adapted use, , further used .bigtext make notification great. credit goes them , daviggyoung getting app working. thanks!
i didnt need edit monitoringactivity.java posted earlier.
final beaconreferenceapplication.java:
import android.app.application; import android.app.notification; import android.app.notificationmanager; import android.app.pendingintent; import android.app.taskstackbuilder; import android.content.context; import android.content.intent; import android.support.v4.app.notificationcompat; import android.util.log; import android.widget.remoteviews; import org.altbeacon.beacon.beaconmanager; import org.altbeacon.beacon.beaconparser; import org.altbeacon.beacon.identifier; import org.altbeacon.beacon.region; import org.altbeacon.beacon.powersave.backgroundpowersaver; import org.altbeacon.beacon.startup.regionbootstrap; import org.altbeacon.beacon.startup.bootstrapnotifier; public class beaconreferenceapplication extends application implements bootstrapnotifier { private static final string tag = "beaconreferenceapp"; private regionbootstrap regionbootstrap; private backgroundpowersaver backgroundpowersaver; private boolean havedetectedbeaconssinceboot = false; private monitoringactivity monitoringactivity = null; public void oncreate() { super.oncreate(); beaconmanager beaconmanager = org.altbeacon.beacon.beaconmanager.getinstanceforapplication(this); // default androidbeaconlibrary find altbeacons. if wish make // find different type of beacon, must specify byte layout beacon's // advertisement line below. example shows how find beacon // same byte layout altbeacon beacontypecode of 0xaabb. find proper // layout expression other beacon types, web search "setbeaconlayout" // including quotes. // beaconmanager.getbeaconparsers().clear(); beaconmanager.getbeaconparsers().add(new beaconparser(). setbeaconlayout("s:0-1=feaa,m:2-2=00,p:3-3:-41,i:4-13,i:14-19")); log.d(tag, "setting background monitoring beacons , power saving"); // wake app when beacon seen region region = new region("backgroundregion", identifier.parse("2f234454f4911ba9ffa6"), null, null); regionbootstrap = new regionbootstrap(this, region); // constructing class , holding reference in custom application // class automatically cause beaconlibrary save battery whenever application // not visible. reduces bluetooth power usage 60% backgroundpowersaver = new backgroundpowersaver(this); // if wish test beacon detection in android emulator, can use code this: // beaconmanager.setbeaconsimulator(new timedbeaconsimulator() ); // ((timedbeaconsimulator) beaconmanager.getbeaconsimulator()).createtimedsimulatedbeacons(); } @override public void didenterregion(region arg0) { // in example, class sends notification user whenever beacon // matching region (defined above) first seen. log.d(tag, "did enter region."); if (!havedetectedbeaconssinceboot) { log.d(tag, "sending notification statusbar"); //begin code notification notificationcompat.builder mbuilder = new notificationcompat.builder(this) .setsmallicon(r.drawable.notification_icon) .setcontenttitle("message communion chapel") .setcontenttext("welcome! coming!") .setstyle(new notificationcompat.bigtextstyle() .bigtext("we noticed you're here today, click here open app , today's sermon notes , bulletin.")) .setautocancel(true); ; // creates explicit intent activity in app intent resultintent = new intent(this, monitoringactivity.class); // stack builder object contain artificial stack // started activity. // ensures navigating backward activity leads out of // application home screen. taskstackbuilder stackbuilder = taskstackbuilder.create(this); // adds stack intent (but not intent itself) stackbuilder.addparentstack(monitoringactivity.class); // adds intent starts activity top of stack stackbuilder.addnextintent(resultintent); pendingintent resultpendingintent = stackbuilder.getpendingintent( 0, pendingintent.flag_update_current ); mbuilder.setcontentintent(resultpendingintent); notificationmanager mnotificationmanager = (notificationmanager) getsystemservice(context.notification_service); // mid allows update notification later on. mnotificationmanager.notify(123, mbuilder.build()); } } @override public void didexitregion(region region) { if (monitoringactivity != null) { log.d(tag,"i no longer see beacon."); } } @override public void diddeterminestateforregion(int state, region region) { if (monitoringactivity != null) { log.d(tag,"i have switched seeing/not seeing beacons: " + state); } } private void sendnotification() { notificationcompat.builder builder = new notificationcompat.builder(this) .setcontenttitle("beacon reference application") .setcontenttext("a beacon nearby.") .setsmallicon(r.drawable.app_icon); taskstackbuilder stackbuilder = taskstackbuilder.create(this); stackbuilder.addnextintent(new intent(this, monitoringactivity.class)); pendingintent resultpendingintent = stackbuilder.getpendingintent( 0, pendingintent.flag_update_current ); builder.setcontentintent(resultpendingintent); notificationmanager notificationmanager = (notificationmanager) this.getsystemservice(context.notification_service); notificationmanager.notify(1, builder.build()); } public void setmonitoringactivity(monitoringactivity activity) { this.monitoringactivity = activity; } }
Comments
Post a Comment