How altbeacon is keeping a background service alive? - android-service

I am running into a issue that is the opposite problem of this thread:
AltBeacon not detect beacon when app is closed
I have an app that uses altbeacon (http://altbeacon.org/)
The app initializes the alt-beacon implementing the interfaces at the application level as below (details omitted)
public class MyApp extends Application implements
BootstrapNotifier,
BeaconConsumer {
//some code
#Override
public void onCreate() {
super.onCreate();
initBeacons();
}
public void initBeacons() {
mBackgroundPowerSaver = new BackgroundPowerSaver(this);
org.altbeacon.beacon.BeaconManager altBeaconManager = org.altbeacon.beacon.BeaconManager.getInstanceForApplication(this);
altBeaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24"));
// estimote
altBeaconManager.setBackgroundScanPeriod(5000);
altBeaconManager.setBackgroundBetweenScanPeriod(25000);
mBeaconManager = MyBeaconManager.getInstance(this, altBeaconManager);
mRegionBootstrap = new RegionBootstrap(this, MyBeaconManager.getRegions());
altBeaconManager.bind(this);
}
#Override
public void onBeaconServiceConnect() {
Thread thread = new Thread() {
public void run() {
// Try range the beacons
rangeMyBeacons();
}
};
thread.start();
}
#Override
public void didEnterRegion(Region region) {
// Some code
}
#Override
public void didExitRegion(Region region) {
// Some code
}
#Override
public void didDetermineStateForRegion(int i, Region region) {
// Some code
}
public class MyBeaconManager implements
RangeNotifier {
// some code
However, If I kill the app or restart the phone, without any special broadcasts or app permissions the alt-beacon service comes back alive. Alt-beacon re-starts itself all the time, in other words. Notice that I don't have any foreground services running. Here' is a screenshot of the app after several hours (and I rebooted the phone), with all apps closed. You can see the alt-beacon is alive and scanning the beacons.
yet when I look at alt-beacon code, it is not a foreground service
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
LogManager.i(TAG,
intent == null ?
"starting with null intent"
:
"starting with intent " + intent.toString()
);
return super.onStartCommand(intent, flags, startId);
}
I did search inside the library and I see not hits to START_REDELIVER_INTENT or START_STICKY.
My question is how does alt-beacon keep the service alive when the app is killed?
The reason I want to understand this feature is that I am writing a similar service but I can only get it do work as alt-beacon if I wrap it into a foreground service. Everything else I tried, the service gets killed as soon as the app closes.
thank you.

The Android Beacon Library uses an AlarmManager to keep the scanning service running in the background. It periodically sets an alarm for 5 minutes in the future, which causes the operating system to deliver it a BroadcastIntent which will start the scanning service if stopped. When running, the library continually reschedules this alarm.
You can see the code that does that here:
https://github.com/AltBeacon/android-beacon-library/blob/master/src/main/java/org/altbeacon/beacon/service/scanner/CycledLeScanner.java#L339
// In case we go into deep sleep, we will set up a wakeup alarm when in the background to kickoff
// off the scan cycle again
protected void setWakeUpAlarm() {
// wake up time will be the maximum of 5 minutes, the scan period, the between scan period
long milliseconds = 1000l * 60 * 5; /* five minutes */
if (milliseconds < mBetweenScanPeriod) {
milliseconds = mBetweenScanPeriod;
}
if (milliseconds < mScanPeriod) {
milliseconds = mScanPeriod;
}
AlarmManager alarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + milliseconds, getWakeUpOperation());
LogManager.d(TAG, "Set a wakeup alarm to go off in %s ms: %s", milliseconds, getWakeUpOperation());
}
This design ensures that if the app needs to be terminated due to low memory, scanning will be restarted five minutes in the future. This allows the phone time to complete the memory intensive operation, while still allowing beacon detections in a reasonable time frame.

Related

Handling a received not covered in become

I am using Akka.NET to develop a logistics simulation.
Having tried various patterns, it seems to me that FSM-type behaviour using become will substantially simplify development.
The system has a repeating clock tick message that all relevant actors receive in order to simulate accelerated passage of time for the entire simulation system. This clock tick message should be handled by all actors that are subscribed to it regardless of which message loop is currently active for any specific actor.
Am I correct in thinking that the only way to handle the clock message in all message loops is by explicitly checking for it in all message loops, or is there a way of defining messages that are handled regardless of which message loop is active?
If the former is the case my idea is to check for a clock tick message in a ReceiveAny, which all the message loops need to have anyway, and to then pass it on to an appropriate handler.
You could use Stashing to Stash the messages while Simulating. I came up with the following code sample to better explain how that works:
// See https://aka.ms/new-console-template for more information
using Akka.Actor;
using Akka.NET_StackOverflow_Questions_tryout.Questions;
var actorSystem = ActorSystem.Create("stackOverFlow");
var sim = actorSystem.ActorOf(Props.Create(()=> new StackOverflow71079733()));
sim.Tell(5000L);
sim.Tell("string");
sim.Tell(1000L);
sim.Tell("strin2");
sim.Tell("strin3");
Console.ReadLine();
public class StackOverflow71079733 : ReceiveActor, IWithUnboundedStash
{
public IStash Stash { get ; set ; }
private readonly IActorRef _simActor;
public StackOverflow71079733()
{
_simActor = Context.ActorOf<SimulationActor>();
ClockTickMessage();
}
private void Simulate(long ticks)
{
Console.WriteLine($"Ticks: {ticks}");
Receive<Done>(d =>
{
Console.WriteLine("Simulation done");
Become(ClockTickMessage);
Stash?.Unstash();
});
// you can add additional messages that may to be handled while the simulation is happening
// e.g:
Receive<string>(s => Console.WriteLine($"received in '{s}' in simulation"));
//While the simulation is on-going, add the incoming message into a queue/stash it
// so that it is not lost and can be picked and handled after stimulation is done
ReceiveAny(any =>
{
Stash.Stash();
Console.WriteLine($"Stashed Ticks: {any}");
});
_simActor.Tell(ticks);
}
private void ClockTickMessage()
{
// you can create an object to represent the ClockTickMessage
Receive<long>(ticks =>
{
Become(() => Simulate(ticks));
});
}
}
/// <summary>
/// We need to run simulation in a another actor so that the parent actor can keep receiving ClockTicksMessages
/// In case the sim takes a long time to become
/// </summary>
public sealed class SimulationActor : ReceiveActor
{
private IActorRef _sender;
public SimulationActor()
{
Receive<long>(l =>
{
_sender = Sender;
Thread.Sleep(TimeSpan.FromMilliseconds(l));
_sender.Tell(Done.Instance);
});
}
}
public sealed class Done
{
public static Done Instance = new Done();
}

.netcore webapi debugging pause

I have a web api project which is a console application and the main looks like
public static void Main(string[] args)
{
// Get the current settings.
ThreadPool.GetMinThreads(out var minWorker, out var minIOC);
// Change the minimum number of worker threads to four, but
// keep the old setting for minimum asynchronous I/O
// completion threads.
if (ThreadPool.SetMinThreads(250, minIOC))
{
Logger.Info("The minimum number of threads was set successfully");
}
else
{
Logger.Error("The minimum number of threads was not changed");
// The minimum number of threads was not changed.
}
BuildWebHost(args).Run();
}
public static IWebHost BuildWebHost(string[] args)
{
return WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>().Build();
}
When the debugger runs and paused it's always this line that is hit:
BuildWebHost(args).Run();
How do I make it pausing at the actual code being executed?
Edit
I'm pressing pause while some request is being executed and expect to see, for example, a call to the database when paused
While debugging open threads window (Debug->Windows->Threads). Once paused one of those threads will be the right worker with required call stack.

Issue with syncing data between watch and phone

I have developed an Android App which runs on both a smartphone and a smartwatch in parallel. On both devices, (let's say) it reads certain sensor data, processes that data (calculate its mean), and then store that results. The watch sends this result to the phone so all storing takes place on the phone. I used buffer writer to write a number into a text file every 5 seconds.
Now after every 320 data items exchanges from watch to the phone, my app on the phone gets killed and I get "the name of the app" is unfortunately stopped as a message. I can't figure it what why they stop exactly after this time? The app running on the watch continues to work fine. However, I cannot store its data because it cannot communicate to the phone version so I get this message "the app is unfortunately stopped as a message" every time the watch sends a number to phone for storing. The app has one activity which has a service (foreground).
Could it be that there is a limit on the amount of data being shared?
The code on watch:
// Create a data map and put data in it
private void increaseCounter() {
PutDataMapRequest putDataMapReq = PutDataMapRequest.create("/count");
putDataMapReq.getDataMap().putInt(COUNT_KEY, count++); // I add current time here as well
PutDataRequest putDataReq = putDataMapReq.asPutDataRequest();
PendingResult<DataApi.DataItemResult> pendingResult =
Wearable.DataApi.putDataItem(mGoogleApiClient, putDataReq);
}
Code on phone (possible problematic area):
#Override
public void onDataChanged(DataEventBuffer dataEvents) {
for (DataEvent event : dataEvents) {
if (event.getType() == DataEvent.TYPE_CHANGED) {
// DataItem changed
DataItem item = event.getDataItem();
if (item.getUri().getPath().compareTo("/count") == 0) {
DataMap dataMap = DataMapItem.fromDataItem(item).getDataMap();
updateCount(dataMap.getInt(COUNT_KEY));
}
} else if (event.getType() == DataEvent.TYPE_DELETED) {
// DataItem deleted
}
}
}
You have to use Service with StartForeground notification to be sure app is always working.
and try to use START_STICKY flag while staring.
UPDATE
You have to dealloc memory of dataevent:
#Override
public void onDataChanged(DataEventBuffer dataEvents) {
try{
for(DataEvent dataEvent: dataEvents){
if(dataEvent.getType() != DataEvent.TYPE_CHANGED){
continue;
}
////... code
dataEvents.release();
}catch (Exception e){
Log.v("SunshineWatchFace",e.getMessage());
}
}

Titanium module - life cycle events not called

I am building a Titanium module for the Android platform and I want to use the life cycle events of the module (i.e. onDestroy, onPause, etc). I tried to use them by overriding these life cycle events in the module class like this:
#Kroll.module(name="custom", id="vub.ac.be.custom")
public class CustomModule extends KrollModule {
private static final String TAG = "customModule";
#Kroll.onAppCreate
public static void onAppCreate(TiApplication app) {
}
private void destroyServices(){
//...
}
#Override
public void onStop(Activity activity) {
Log.d(TAG, "STOPPING");
destroyServices();
super.onStop(activity);
}
#Override
public void onPause(Activity activity) {
Log.d(TAG, "[MODULE LIFECYCLE EVENT] pause");
super.onPause(activity);
}
#Override
public void onResume(Activity activity) {
Log.d(TAG, "[MODULE LIFECYCLE EVENT] resume");
super.onResume(activity);
}
#Override
public void onDestroy(Activity activity) {
Log.d(TAG, "[MODULE LIFECYCLE EVENT] destroy");
destroyService();
super.onDestroy(activity);
}
}
but when I opening and closing the application, these life cycle events are never called. Does anybody know how to use them, because only if I can use them I will be able to build the module I want. Thanks
Could this be the origin of my problems: inline link moddevguide
https://github.com/appcelerator/titanium_modules/blob/master/moddevguide/mobile/android/src/ti/moddevguide/ModdevguideModule.java
on line 72 they describe the following:
// Lifecycle
// NOTES:
//
// 1. Modules are created in the root context
// 2. Using navBarHidden (or fullscreen or modal) causes the window, when opened, to run in a new Android Activity.
// 3. The root context/activity will be stopped when a new activity is launched
// 4. Lifecycle notifications will NOT be received while the root activity is stopped.
I run the module in an application that uses navBarHidden, so as described a new android activity wil be started and the root activity is stopped. Whenever the root activity is stopped, the lifecycle notifications are received. Can anyone confirm this and does anybody know how to solve this? thanks
What version of SDK are you using? On 3.3.0 lifecycle callbacks is calling regardless to navigation bar hidden.

usbManager openDevice call fails after several hundred successful attempts

I'm using usbmanager class to manage USB host on my android 4.1.1 machine.
all seems to work quite well for a few hundreds of transactions until (after ~ 900 transactions) opening the device fails, returning null without exception.
Using a profiler it doesn't seem to be a matter of memory leakage.
this is how I initialize the communication from my main activity (doing this once):
public class MainTestActivity extends Activity {
private BroadcastReceiver m_UsbReceiver = null;
private PendingIntent mPermissionIntent = null;
UsbManager m_manager=null;
DeviceFactory m_factory = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
m_UsbReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {
UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if (device != null) {
// call your method that cleans up and closes communication with the device
Log.v("BroadcastReceiver", "Device Detached");
}
}
}
};
registerReceiver(m_UsbReceiver, filter);
m_manager = (UsbManager) getSystemService(Context.USB_SERVICE);
m_factory = new DeviceFactory(this,mPermissionIntent);
}
and this is the code of my test:
ArrayList<DeviceInterface> devList = m_factory.getDevicesList();
if ( devList.size() > 0){
DeviceInterface devIf = devList.get(0);
UsbDeviceConnection connection;
try
{
connection = m_manager.openDevice(m_device);
}
catch (Exception e)
{
return null;
}
The test will work OK for 900 to 1000 calls and after this the following call will return null (without exception):
UsbDeviceConnection connection;
try
{
connection = m_manager.openDevice(m_device);
}
You might just run out of file handles, a typical limit would be 1024 open files per process.
Try calling close() on the UsbDeviceConnection, see doc.
The UsbDeviceConnection object has allocated system ressources - e.g. a file descriptor - which will be released only on garbage collection in your code. But in this case you run out of ressources before you run out of memory - which means the garbage collector is not invoked yet.
I had opendevice fail on repeated runs on android 4.0 even though I open only once in my code. I had some exit paths that did not close the resources and I had assumed the OS would free it on process termination.
However there seems to be some issue with release of resources on process termination -I used to have issues even when I terminated and launched a fresh process.
I finally ensured release of resources on exit and made the problem go away.