I have to make an android application with the purpose of a user check-in on a bus. The app have to research the beacons from a bus and at the same time has to send a beacon. How can I check that the received beacon is a beacon that last 2 minutes, in order to understand that the user is actually on the bus and he's not passing by?
As a starting point, I'm using https://github.com/Jaosrikate/iBeacon-Android and I'm trying to make some changes.
Do you have any suggestions on how to do this?
Beacon ranging involves a callback from the API that gives you a beacon identifier. The time of the callback is the time the beacon was detected.
The basic algorithm is simple:
Create a HashMap<String,Date> to store the timestamp of the first time a beacon was detected. Use a string representation of the beacon identifier as the key.
Whenever a beacon is detected, check to see if it’s identifier is already in the map.
If the identifier is not in the map, store it along with the current Date()
If the identifier is in the map, check to see if the current time - the stored time in the map > 2 minutes. If so, you have a match
In-app messages work well in test mode, but seem to be very unreliable in production. I made campaigns with "Modals" as the message layout. The simplest possible messages, without any pictures. If I set countries as the targets, no messages seem to be shown in the target countries.
I have 2 campaigns without any country targets and those messages get shown, but still just sometimes. The first of these campaigns informs the user they have an opportunity to reach Level 1.
The message get shown about 50% of the times it should be shown (once per device). Sometimes the message get shown so quickly that it just flashes by, so it is impossible to read the text. It closes before the user closes it. The second of these campaigns inform the user when they have reached Level 1. It is the same result as described above here.
My calls to logEvent are from methods, which are directly called from the onresume method in the Main activity of the app. They are called according to certain conditions, not every time onresume is called. My calls look for instance like this:
FirebaseAnalytics.getInstance(this).logEvent("gyro_access", Bundle.EMPTY);
What can be done to make the In-app messages work in a reliable way in production?
I got this to work now. I used this method instead to trigger the messages:
FirebaseInAppMessaging.getInstance().triggerEvent()
I also updated Gradle, so the latest version of com.google.firebase:firebase-inappmessaging-display was used.
So the solution to my problem was either using the triggerEvent-method or updating Gradle.
I'm using Google Maps on my app so I'd like to know a different way to do my goal. My goal is every time user joins a street it should call an api saying hey I'm in, so my question is, what's better use geofencing with this or shall I create a service that makes a call every 5 seconds to the server sending the current position?
It depends on how optimised app you want.
You can call geofencing every few secs, you can also make call to server to send current position.
You can also configure GPS to call only when user moved some distance, then for example check using geofencing if street was changed or send it to server. Some tweaks and testing will be required, to limit the calls to server and limit the battery drain
I'm developing an android application and hit the problem with determining system first boot up time. I mean i need to measure how much time already passed from device first boot up.
I know about solution with listening for ACTION_BOOT_COMPLETED and save anything in SharedPreferences, but i need another solution, because this one does not work for some cases. Maybe there is any system property?
Use case (excerpt from discussion)
The filename of each file I receive from server includes a timestamp
taken from System.currentMillis()
I compare those timestamps in order to determine, which file the most current one is.
Now, the user changes system time a few months ahead.
I am still able to determine the most current file downloaded after user changed system time.
Now, the user changes time back to original setting.
The file downloaded on step 4 always wins when comparing timestamps.
The silver bullet to solve this problem would be a timestamp that counts seconds since first boot (after factory reset). Just like SystemClock.elapsedRealtime() but without reset after each boot. Unfortunately, the answers so far tell us, that this silver bullet doesn't exist.
However, many answers show a great variety of options how to tackle that problem. OneWorld123 commented each answer, how that suited his needs.
Maybe there is any system property?
Not sure about system property, but there is SystemClock class which provides API's to get system uptime:
SystemClock.uptimeMillis() which
Returns milliseconds since boot, not counting time spent in deep sleep.
You may also use SystemClock.elapsedRealtime() which
Returns milliseconds since boot, including time spent in sleep.
Hope this helps.
In case one needs to know when was the first time an Android device was booted,
The easiest method would be to have an application
that is installed in the factory image
that is configured to run during boot
that logs the current date & time into a sharedPreference on its first run
Subsequently any other apps that need to determine the first boot time of the Android device can lookup the appropriate sharedPreference during the lifetime of the device. (or until the device is factory-reset; at which point the pre-installed app would write the new date&time into the shared preference after a reboot.)
However if it is not possible to an pre-install an application on the Android device, then a couple of potential workarounds would be:
1. As a root/superuser
one would lookup the time-stamp of a directory/file that is known to get created on the Android device during first-boot.
2. As a regular app,
a simple workaround method using standard Android APIs would be to check for the installation-time of an appropriate system package that is known to get installed during first-boot.
/* This returns the last time a package was installed */
PackageManager pm = context.getPackageManager();
PackageInfo pInfo = pm.getPackageInfo(<app-package-name>, 0);
return pInfo.firstInstallTime;
3. Alternately as a regular app,
if we can rely on a specific package being updated one-time during first-boot (and never again) we can check its update-time as follows:
/* This returns the last time a package was updated */
PackageManager pm = context.getPackageManager();
ApplicationInfo appInfo = pm.getApplicationInfo(<app-package-name>, 0);
String appFile = appInfo.sourceDir;
long installed = new File(appFile).lastModified();
If we stick to the SDK, I don't know of a method providing this information directly; but there might be a way to derive this information from other resources. Again, if we stick to SDK, one "rather reliable" option is to use application usage statistics which Android OS saves during device lifetime. That is - the timestamp for a first "usage stats" ever saved.
This, though, clearly does not provide an exact "first boot time" timestamp, so it depends on whether some approximation is OK in your case. Generally, the problem with usage statistics is that Andriod aggregates it for periods distant in time - so, the older device is - the less accurate the date is. For example, for my current phone, first booted on Dec. 3 2014, aggregated usage statistics is first recorded on Dec. 21 2014 currently (for the record - it is Feb. 2016 by the time of this writing). (I have to admit though that I don't know how Android OS schedules the aggregation, and if it is just scheduled on Dec. 21 every year, or if it is indeed somewhat close to the first device usage - I guess it is easy to check with any other device.)
Following is some sample code showing UsageStatsManager usage, but it certainly would need more adjustments in order to address the fact of having more precision for more recent periods:
UsageStatsManager usageStatsManager = (UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE);
Calendar year2013 = Calendar.getInstance(); year2013.set(2013, 0, 1);
List<UsageStats> stats = usageStatsManager.queryUsageStats(
UsageStatsManager.INTERVAL_YEARLY, // or adjust for "younger" devices to get more precision - so, you'll probably need several queries
year2013.getTimeMillis(),
Calendar.getInstance().getTimeInMillis());
// now, first element in stats (if it is present at all) will point to the "earliest" statistics saved *for this interval* (yearly in this case)
// use UsageStats.getFirstTimeStamp() to get first known/saved usage
Note also that, as documented in the SDK, UsageStatsManager requires PACKAGE_USAGE_STATS system-level permission, so you'll need to make user accept it in Settings first:
Intent settingsIntent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS);
startActivity(settingsIntent);
Hope it helps!
According to your discussion on: https://chat.stackoverflow.com/rooms/102325/discussion-between-ankitagrawal-and-oneworld , you need a monotonic counter to uniquely identify a dataset.
For that you can easily set a SharedPreference and increment this value every time you need a new identifier. When you require to know which is the newest file, just compare the identifiers. If it is an issue that this counter gets reset once the app is uninstalled, please refer to: In android is there any way to preserve SharedPreferences after an uninstall
A different approach that could be used, is to request a timestamp from an outside server.
Hope it helps ;-)
There are 3 methods in ANDROID SDK for these:-
public static long elapsedRealtime ()
Added in API level 1
Returns milliseconds since boot, including time spent in sleep.
Returns
elapsed milliseconds since boot.
public static long elapsedRealtimeNanos ()
Added in API level 17
Returns nanoseconds since boot, including time spent in sleep. Returns
elapsed nanoseconds since boot.
For #oneWorld Case:
You can use 2 approach:-
1) While writing check if some data has date above the current date then change the date of previous data to something less than current data and time,
so it will return correct latest data.
2) You can store the time on server and retrieve time from there and set it.
I wanted to learn more about the Android Services / Broadcasts, so I started a simple project, to create a battery monitoring app. It turned out pretty good, I'm using it for a few days now, but I want to add a new function: to show since when is the phone charging/discharging.
First I thought that I would create two static fields in my BoradcastReciever extension class, where I get and publish the data about the battery, one for the actual state (charging/discharging), and one for the time, when the change in state happened. This way, I could just subtract from the current time the last change, and know exactly since when is the phone charging/discharging.
But there is a problem with this solution: It won't show the correct data at first, when a user starts the app. I wouldn't make a big deal of it, but I saw that Android tracks this data somewhere, because inside my phone settings I found this information, so why take the hard way.
So my question is: is there an easy way to get from the Android system the date/time (no matter what format) of the last charging state change?
I looked at the BatteryManager reference but there are no constants named after what I seek, and which I could use, to get the information from the Intent of my receiver.
The Android OS tracks the connect/disconnect of a power source, but does not make this data accessible to apps. You have to record this all yourself, using intent filters.
The two intent filters to use are android.intent.action.ACTION_POWER_CONNECTED and android.intent.action.ACTION_POWER_DISCONNECTED; with these, you can monitor when the power source is connected and disconnected.
You can find information about this process explained incredibly clearly here. Another blog describing the process can be found here.