Hello I'm creating tracking app and I want to quickly get the location. But this app should be friendly for people. It should works like that:
I turn on GPS and i want to get location by it
If it takes more that 5 seconds I try get location by network provider
If it takes more that 5 seconds i try to get location by wifi
if it takes more I do something else.
I already have this functions! How to do that they work one after another (If one wokrs more than 5 sec we move to another one).
So I'm thinking that I must use some kind of timer, but here I got a problem if I put code like this
Timer timer2 = new Timer();
TimerTask testing = new TimerTask() {
public void run() {
handler.post(new Runnable() {
public void run() {
Toast.makeText(MainActivity.this, "test", Toast.LENGTH_SHORT).show();
}
});
}
}; timer2.schedule(testing, 1000); ***
*** here syntax errors
not inside onCreate I have syntax errors (and I want to do that after pushing the button). However how should looks this timer for 3 methods following next by next ?
depending on the OS that you are devlopping for, I would recommend you to make use of the OS specific methods available for retrieving location.
In case of Android for example there is a service available that makes is quite easy for you to retrieve the location in an user friendly manner:
Please check this: https://developer.android.com/training/location/index.html
This allows you to create location requests, depending on your situation you can define the request with a certain priority. For example: in case city precision is enough in your situation, you can define it and the framework might decide to only use the currently available WIFI to get the location (and not startup the GPS).
Related
I have this scenario, where data from my sensor is sent to my server every 5 minutes. The server stores received data in the database. Now when a server receives the data, I want to start 6 minutes timer for this specific sensor. If I receive data earlier than those 6 minutes, this timer must be canceled and started again. If the timer happens to finish, onFinish() must be called, which then I will send a notification to the user about a possible connection issue with the sensor. I have this list of sensors and a method that gets called when the server receives data:
// list to save sensors and their timers
private val sensors: MutableMap<Long, CountDownTimer> = HashMap()
// this method gets called after server receives data from the sensor
// must keep in mind that CountDownTimer is undefined
fun initiateTimer(sensorId: Long) {
sensors[sensorId] = object : CountDownTimer(360000, 1000) {
fun onTick(duration: Long) {
// Blank
}
fun onFinish() {
// Send notification to user about possible connection issue
}
}.start()
}
I've been looking into scheduleWithFixedDelay, but this requires ExecutorService with specific threads count. Now what if I have thousands of sensors and I need those thousand timers running at once?
Now in Android, I can simply use CountDownTimer, but since it's not Android, I am seeking advice for the best possible approach to solve this problem using Kotlin in Spring Boot environment (or in simple terms, not in Android environment). Thank you.
ScheduledExecutorService that you found is a standard way of scheduling tasks in the future. You can schedule thousands of timers and execute them all using a single thread - no problem with that.
Alternatively, if you use coroutines, you can use utils like delay() or withTimeout().
Also, if you really plan to have a big number of such timers, then it could be easier to implement and maintain alternative solution where we only have a single "ticking" thread/coroutine that checks all sensors once per e.g. 10 seconds. It iterates over all sensors and checks when the data was received the last time. When new data arrives, we only update the time, but we don't need to cancel and restart any timers.
I've been working on developing an application that interacts with BLE devices. Everything works great, I can scan, connect, and consume services.
I've been reading through all the docs and I do not see anything that gives the developer the option of listening for BLE devices. Basically I would like to trigger a broadcast receiver when the devices enters the range of a BLE device.
I know I could continually scan for this, but battery use is way too high and I would like this to be invoked even when my application is not being used.
Is this feature not supported or am I missing a section of the docs that discuss this?
I have done a project recently, and from what I read in your question it has some similarity to what I did.
I know I could continually scan for this but battery use is way too high and I would like this to be invoked even when my application is not being used.
Regarding battery problem, having Bluetooth on all the time is power consuming, but at the same time you can not detect BLE with out having Bluetooth on.
What I did is two experiments and both are useful but are different and I can not say which one is best, but you need to test it so it fits your requirement.
Having Thread running that turns Bluetooth on and listen to iBeacon and off (with sleeping time) for while programmatically. It can be done many ways.
Using a package called Altbeacon, has a lot of useful features, one of those features is Auto Battery Saving with example code:
public class MyApplication extends Application implements BootstrapNotifier {
private BackgroundPowerSaver backgroundPowerSaver;
public void onCreate() {
super.onCreate();
// Simply constructing this class and holding a reference to it
// in your custom Application class
// enables auto battery saving of about 60%
backgroundPowerSaver = new BackgroundPowerSaver(this);
}
}
We need a broadcast event, that wakes up our app once a BLE-device with a certain Service-UUID is in reach. Maybe now there is a better BLE API available than 2 years ago. The most energy saving and most precise method gets rewarded.
Your other part, it is called triggering actions at a specific distance.
I still use the Altbeacon to check beacon range and triggering action. A sample code is something like
#Override
public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {
for (Beacon beacon : beacons) {
if (beacon.getDistance() < 5.0) {
Log.d(TAG, "I see a beacon that is less than 5 meters away.");
// Perform distance-specific action here
}
}
}
So when that said, you can also get distance of specific UUID I build a method based on Altbeacon, looks like this (Look inside the for loop and if statement):
private void startRangeNotifier() {
Log.i(TAG, "Starting range notifier...");
beaconManager.setRangeNotifier(new BeaconRangeListener() {
#Override
public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {
if (beacons.size() > 0) {
for (Beacon beacon : beacons) {
Log.d(TAG, "uuid's: " + beacon);
Log.d(TAG, "uuid id1: " + beacon.getId1());
if (beacon.getId1().toString()
.equals("b9407f30-f5f8-466e-aff9-25556b57fe6d")) {
Log.d(TAG, "uuid id1 distance: " + beacon.getDistance());
}
}
}
}
});
try {
beaconManager.startRangingBeaconsInRegion(
new Region(BEACON_MONITORING_ID, null, null, null));
} catch (RemoteException e) {
e.printStackTrace();
}
}
My log output:
D/Main activity:: uuid's: id1: b9407f30-f5f8-466e-aff9-25556b57fe6d id2: 31807 id3: 59251
D/Main activity:: uuid id1: b9407f30-f5f8-466e-aff9-25556b57fe6d
D/Main activity:: uuid id1 distance: 0.2108658568686884
In my answer I wanted to present the concept I used, Beacons project need patience in general. As the other answer mentioned it is also possible to combine the solution here with Geofences and ActivityRecognition.
Note: Since the nature of bluetooth beacon, the distance is proximity and not absolute, and some time even the bluetooth beacon is 1 meter a way it might show 2 meter or 0.5 meter, so have that in mind
Link reference:
https://altbeacon.github.io/android-beacon-library/distance-triggering.html
https://altbeacon.github.io/android-beacon-library/samples.html
https://altbeacon.github.io/android-beacon-library/eddystone-how-to.html
https://github.com/AltBeacon/android-beacon-library-reference
BLE scanning on Android is pretty battery intensive, and it's definitely not something you want to do in the background all the time. If you are working on a background application with stationary bluetooth devices (à la ibeacons) that you know the location of, you can use Geofences to turn scanning on and off when you think you are in the approximate proximity of a device. If you are not careful geofencing can also drain battery.
If you don't know the location of your bluetooth devices I guess you can also play tricks with ActivityRecognition, i.e only scan periodically when the user is walking and stopping it if the user is stationary/running/biking/in vehicle. Again, the activity recognition stuff also takes battery so you are going to have to be judicious.
We need a broadcast event, that wakes up our app once a BLE-device with a certain Service-UUID is in reach.
You probably know how to filter scan results by Service UUID so I won't go into that. About the waking up: if your app is scanning, it is awake by definition. It may or may not be on the foreground, but it is awake.
Maybe now there is a better BLE API available than 2 years ago.
Since SDK version 21, there is a new API that you can use for BLE scanning. To my knowledge, the only difference is the way you access the API and the underlying functionality (regarding power consumption etc.) has not changed.
About the scanning:
It's true that scanning is battery-intensive. Even the docs say so.
The intensity is relative though. It is intensive compared to not scanning at all, but it is not intensive enough that it will hopelessly drain your battery. It's called low energy after all.
An other answer suggest monitoring Geofences and only scan when you know you are in range of BLE devices. While this will lower the battery consumption of the ble scan, it will need that battery power for the GPS, otherwise it can't monitor the Geofences (well, it can, with cellular/wifi data, but then it won't be nearly as accurate).
Depending on how time critical your scanning is (e.g. if there is a device nearby, must you know it right away? or is it okay if it's delayed a couple seconds?) you can implement a pause inbetween scans.
Say you scan for 5 seconds, pause for 5 seconds, scan for 5 seconds again. That way you will be scanning almost all the time, yet only consume roughly half of the battery power. These intervals can be tweaked to match your situation. Maybe you're okay with scanning 3 seconds and pausing for 10. (note that the maximum time between a device's broadcasts is 10.24 seconds).
I have an app with about 50 users that scans with pauses like this (scan for 3 seconds, pause for 3, repeat) 24/7 in the background, and have not received any complaints about excessive battery usage.
If you have a specific BLE peripheral you want to detect, then figure out its advertisement period. If you have different devices, find the longest advertisement period. Scan longer than the advertisement period of the device, so you get at least one advertisement message. Repeat this scanning periodically with the frequency that is suitable for your use case. E.g. Your peripheral is advertising every second once. You would like to detect the device in 5s when it comes to proximity. Then Scan for 1s (or a bit more). Switch off scanning for 4s. This way you can save battery.
I am making an android app. There is an activity in the app, which when triggered, makes a sparsearray and fills it with data. Now this process takes upto 1 minute on the emulator, which is very long. So I want to make that sparsearray once, right when the app is launched, and save the sparsearray in RAM for the lifetime of the app. And whenever the activity is triggered it should access the sparsearray in RAM instead of making a new one, thus saving time and processing power. Can this be done, if so how? Sorry if this question is dumb, I am new to android. Thanks!
*Edit: This is what the sparsearray making function looks like:
//function which accesses sparsearray making function
public String[] process(){
InputStream is = context.getAssets().open("feedtitlesandaddresses.txt");
InputStreamReader iz=new InputStreamReader(is);
BufferedReader br = new BufferedReader(iz);
String line = null;
while((line=br.readLine())!=null) {
readLine(line);
}}
//sparsearray making function
private void readLine(String line) {
//some string processing(omitted here)
int num1 = Integer.parseInt(firstNumber);
//int num2 = Integer.parseInt(secondNumber);
if(sparseArray.get(num1) == null) {
sparseArray.put(num1, new SparseArray<String>());
}
temporarySparseArray = sparseArray.get(num1);
for(int w=0;w<size;w++){
temporarySparseArray.put(w, array1[w]);
}
sparseArray.put(num1, temporarySparseArray);
temporarySparseArray = null;
}
You can write you object in the android internal or external file system, and you can read the object when you want to use it.
I feel this question deserves an answer, and I was sure someone would come up with one, but, hmm, not really so far; and if I were Tom Wong, it would currently look to me as if StackOverflow was a place where wannabe experts start fighting over questions rather than answering them. ;) So here we go.
Do something at startup, the result of which lasts as long as your App is in memory: The right place to do this is Application.onCreate(), for which you need to subclass Application. It is okay to store the result in the Application object as well in this case, where you can access it from any Activity by getting the Application context.
Do something that will take some time: In general, it's a good idea to use AsyncTask on Android, but it is specialized for doing things which relate to the User Interface but must not block it. Also, without some explicit tuning, its behaviour will vary amongst different Android versions. Currently, without further measures, if you did your computation via AsyncTask, other AsyncTasks would have to wait first. Also, what you want to do is not a classic task for using an AsyncTask, so use a one-time Thread which simply stores its result finally in a volatile reference.
The following code snippet should give you the idea.
final class MyApplication extends Application {
public volatile String[] expensiveToCompute;
#Override
public void onCreate() {
expensiveToCreate = null;
(new Thread() {
#Override
public void run() {
String[] result = computeMyData();
// it is important to assign the locally created data at once here
expensiveToCompute = result;
}
}).start();
}
}
In this way, expensiveToCompute will be null until the asynchronous computation has finished.
It is important to understand that this Thread will run until it has finished, and that it holds a reference to your MyApplication object. This means that even if the user leaves your app, your Thread will still continue if it has not finished until then.
This is in fact nice, because either Android decides to leave your Application object alive just because it can, in which case the user experience improves. Or Android kills the whole process with the Application object, your Thread and any held data, in which case it will start from scratch next time.
One more thing about, umm, suggestions to move expensive computations into AsyncTask etc: Android assigns a default background priority to such threads, and all background threads will (currently) have to live with 10% CPU time altogether no matter whether the Android system is idle otherwise. So many people who move intensive computations to background tasks notice that it will take ten times longer. Hence, you may want to read my suggestions regarding how to handle this here and/or here.
I just started using Wicket (and really am not too familiar with a lot of web development) and have a question with regards to a download link. I have a web app that simply allows users to upload particular files, processes some of the information in the files, and offers downloads of different formats of the processed information. However this is really supposed to be a lite version of some software I am working on, so I really don't want to do much processing. I am wondering if there is a way to set something like a timeout for the download link, so that if the user clicks on the link and the processing takes longer than 20 seconds or so, it will simply quit the processing and send them an error instead. Thanks!
I agree with Xavi that the processing (and possible termination of the processing) should be done with a thread.
However, especially if it takes more than just a few seconds, it is much better to not just wait with the open connection, but rather to check at regular intervals to see whether the thread is done.
I'd do something like this:
Start the thread doing the actual work
Show a Panel that says "Processing your download" or something like that.
Attach an AbstractAjaxTimerBehavior to the panel with a timer duration of, say, 10 seconds or so.
In the timer behavior's onTimer method, check the state of the processing:
If it's still working, do nothing.
If it's canceled because it took too long, show a message like "Canceled" to the user, e.g. by replacing the panel or setting a warning label to visible.
If it's done, show a message like "Your download is starting" and start the download. See this document for how to do an AJAX response and at the same time initiate a download
To be able to cancel processing if it takes more than a given amount of time, it would be appropriate to perform it in a separate thread. This matter is addressed in the following question: How to timeout a thread.
Now for the Wicket part of it: If I understood what you're trying to achieve, you could for instance roll your own Link that would perform the processing, and respond with the results in case it doesn't timeout. In case the processing takes too much time, you can simply throw an error (remember to have a FeedbackPanel so that it can be shown).
The processing, or generation of the file to download, could be implemented in a LoadableDetachableModel for efficiency. See this question for more details: How to use Wicket's DownloadLink with a file generated on the fly?
For instance:
IModel<File> processedFileModel = new LoadableDetachableModel<File>(){
protected File load(){
// Implement processing in a separate thread.
// If it times out it could return null, for instance
}
}
Link<File> downloadLink = new Link<File>("yourID", processedFileModel) {
#Override
public void onClick() {
File processedFile = getModelObject();
if (file != null) {
IResourceStream rs = new FileResourceStream(file);
getRequestCycle().setRequestTarget(new ResourceStreamRequestTarget(rs));
} else {
error("Processing took too long");
}
}
};
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Android:how does application Protector app works?
How can i be notified when new app begin launching? clearly to say, i click on app icon , and app begin launching, i want to set my service to observer of that event (if there is any). Is there any event or some way to know that before app launched ?
If I were you, I would get the ActivityManager with a call to
getSystemService(Context.ACTIVITY_SERVICE)
and then setup my program with the following code:
private final static Handler updateHandler = new Handler();
private static long WAKEUP_INTERVAL = 10000; // 10secs?
private Runnable periodicUpdate = new Runnable() {
#Override
public void run() {
checkRunningProcesses();
updateHandler.postDelayed(this, WAKEUP_INTERVAL);
}
};
to do periodical checks of the following two things:
check getRecentTasks() to find out what user has launched recently (requres GET_TASKS permission)
get from getRunningAppProcesses() and keep somewhere list of running processes just in case periodical check interval has been chosen too long and some processes were added/removed but did not show in getRecentTasks()
This way I could not get an instant notification about program launch, but could find about that soon enough (seconds later, maybe) to do something about it.
One more thing, it might be a wise idea to stop checks when screen goes dark, to save the battery.
android listen for app launch
You can't really do this with intents or anything like that. Check out this guy's brute hack. Not a great solution but the closest you'll get.