How to keep using onSensorChanged() when phone asleep? - java

I'm creating an application that needs to detect the biggest acceleration that the phone detects. Currently it works, but it does not continue the task when the screen turns off. To achieve what I have now, I wrote in onCreate:
mSensorManager = getSystemService(SENSOR_SERVICE) as SensorManager
mAccelerometer = mSensorManager!!.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION)
I have initialized these variables globally in the class. I then have implemented onSensorChanged(), onResume(), onPause() and left onAccuracyChanged empty.
From what I have understood implementing functions like this is different than more simply creating an asynchronous task. How would I go about changing this so to make it work in the background as well? Thank you!

You won't be able to use the Sensors API when the app went to the background even with WakeLock - the official documentation is clear about that.
You can easily proceed with using Sensors API even with the phone screen disabled inside a foreground service, though. In order to do that use this documentation as a start - Foreground Service. This doesn't guarantee the eternal live of the Service but it will most definitely live longer than an ordinary Service as well as you will have the access to the Sensors API. I am not sure about WakeLock in this case - you will have to try(but I think you won't need it).
Here is a span of answers. Some of them contain sample code and even links to sample projects
Here and here there are neet examples in form of medium articles.

Related

How to continuously check for field/document change in Firestore - Android

I am trying to listen to my document using the Snapshot Listener method in Android.
I have a document called 'Mobile' and a field called 'UUID'. In 'UUID', I keep all the UUID's of the phones the person has logged into.
The problem with this code is that I am not able to get listeners continuously with this code. Can we use Android Services or something to continuously check for changes in the document or a field in the document.
I need to create a code which will be continuously checking the UUID field for any changes and the code should create a Toast accordingly.
I am also worried that this will kind of increase the number of read/writes for our database.
Can someone please help me? Thanks in Advance
The problem with this code is that I am not able to get listeners continuously with this code.
Why would you say that? This is what it does, it gets the data in real-time.
Can we use Android Services or something to continuously check for changes in the document or a field in the document.
If you want to get updates even if the user closes the app, indeed you need a service. For more info, please check my answer from the following post:
How to create firebase background service in Android?
I am also worried that this will kind of increase the number of reads/writes for our database.
Yes, it will increase for sure the number of reads/writes if you continue to keep the listener active. So for not paying extra reads/writes, you should remove the listener according to the life-cycle of your activity as explained in my answer from the following post:
How to set addSnapshotListener and remove in populateViewHolder in RecyclerView Item?

Starting an activity before phonecall is placed

I'm making an app where a BroadcastReceiver intercepts an outgoing call and starts an activity with an AlertDialog right before the phonecall is actually placed. I've tested on several phones with different results. On two of the phones I've tested everything works great, the activity is started before the call is placed and therefore "interupts" the phonecall. After the activity is shut down, the phonecall resumes as normal.
On the third phone, an HTC, this doesn't work. The phonecall is placed before the activity starts. How can I prevent this? Are there any priorities I should be looking for?
Welcome to the wide world of HTC headaches when it comes to android development, specifically regarding broadcast receivers. Sense always seems to handle things differently, or in some special way. Though this isn't really the best answer, it is too long for a comment. After looking around a bit, this is a known issue with HTC. A quick fix seemed to have been found at Problem with interecepting outgoing calls on HTC Desire, though somewhat outdated.
They state that you can try
As it seems the HTC Desire (2.2) responds to setResultData(null)
which will stop the out dial. Then you can place a new intent
(Action.CALL) to call the new number. Not so nice workaround, but as
a user you hardly notice it.
Again I am not even sure if this works, or is the answer you are looking for, but it was too much for a comment :P

Since when is the phone charging/discharging

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.

Collating/Managing data to populate "live activity feeds" in web app

I have something of an abstract question regarding managing live feeds/polling on web sites.
I am creating a web app (built on Java/Spring/Hibernate) and on the user's home page I want a live feed of the latest activity from all the members of there team, and I am trying to work out the best way to handle this query on the server side.
The brute force way would be to load the current users list of team mates, and then iterate through each of his team mates, loading their latest conversations/file uploads/etc, and then merging all this activity in to a single list sorted by timestamp and returning that (lets say for sake of example that we just return the top 10 latest activity for the feed).
However, that seems very un-performant, especially as this operation would need to be done regularly (depending on the polling interval).
I have also considered making all the potential activities (conversations/status updates/uploads) as extending an Activity class and then just having a direct SQL/JPQL query in a DAO that selects all the latest activity from a set of users to be returned, but concerned that might bypass the caching and continued access to the DB would also reduce performance.
Has anyone handled this type of problem before? any one know what a good approach is?
Thanks!
This is an old one now, but here is what i did for this:
All tasks that should appear on a live wall extend Activity (this was already the case)
Created a new Notification object, the Notification had a link to the underlying Activity and a link to a user (who was being notified).
Created a pre-persist hook for Activity that created a Notification object for the Activity being persisted - it did this for every user that was interested (all users following the user that was persisting the Activity)
For the moment, Notifications are persisted/retrieved to the DB - possibly not scalable to very high volumes, but the approach I think supports moving to a Queue based system (such as LinkedIn's Kafka queue library which is designed exactly for this purpose). As it is per-user, it also provides the option to have a read/unread notification flag for significant notifications.

How can I change the behavior of Android's airplane mode so that it will not turn off the cellular radio?

I have been trying to create a simple application that will let the user customize the behavior of airplane mode in Android. The motivation for this is from a relative who has a Samsung Fascinate, and during calls he will accidentally turn on airplane mode. This happens when he holds the phone, accidentally holds down the side power/lock button, which opens a dialog with a menu for “Silent Mode”, “Airplane Mode”, and “Power Off”. He accidentally triggers airplane mode by a touch of the phone to his cheek. This drops the call and is an annoyance to him.
Ultimately, I would like to create an app that prevents the cellular radio from being turned off while the user is in the middle of a call. But, for a first iteration I thought it made sense to let the user manually choose which radios would not get turned off by airplane mode.
I am not looking to modify the Android source code or do something that would require rooting. I am looking for a solution within the standard framework
My first attempt to solve this was to create an application that would modify System.AIRPLANE_MODE_RADIOS like so:
System.putString(getApplication().getContentResolver(), System.AIRPLANE_MODE_RADIOS, "");
According to the API docs, this constant is "A comma separated list of radios that need to be disabled when airplane mode is on". It seems that airplane mode does not actually use this constant, and it continues to work as normal after the change is made.
My next attempt was to create a BroadCastReceiver, receive the AIRPLANE_MODE action, and send out an Intent to reverse it:
Intent am = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
intent.putExtra("state", 0);
context.sendBroadcast(am);
This does turn off airplane mode after it has been activated. However, if the user was in the middle of a call, it will still be dropped (which makes sense). So, this is not quite the solution to my problem.
Does anyone know how to prevent airplane mode from disabling the cellular radio?
As far as i know you wont be able to do this since the option itself(airplane mode) would be of no use if 3rd party applications are able to access towers with airplane mode enabled on the device.
The source of PhoneApp.java
https://android.googlesource.com/platform/packages/apps/Phone/+/gingerbread-release/src/com/android/phone/PhoneApp.java
Makes it clear why this will not work.
In contrast to the wifi and bluetooth implementations which register a receiver for Intent.ACTION_AIRPLANE_MODE_CHANGED only when on the list of airplane mode radios, PhoneApp does it all the time:
IntentFilter intentFilter =
new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED);
And then unconditionally acts on it:
if (action.equals(Intent.ACTION_AIRPLANE_MODE_CHANGED)) {
boolean enabled = System.getInt(getContentResolver(),
System.AIRPLANE_MODE_ON, 0) == 0;
phone.setRadioPower(enabled);
}
Given the purpose of airplane mode, I'm sure this is an intentional feature and not a bug.
If the airplane mode is triggered by a physical button it is possible to override the button press action. Although to achieve this I believe it requires root access to the system.
But to trigger airplane mode from a physical button is a weird idea. IF the button is in the software and while in the call, perhaps you can create a phone application that doesn't have an airplane mode button inside the call screen.
Some applications modify the actual call-in-progress screen, and I know the CityID thing that came pre-installed on my Fascinate (Tells me the city associated with the area code of the number being dialed or incoming) was able to interrupt a call right before it dialed the number to tell me to register the software. If you can make your own (full-screen) call-in-progress view then it sounds like you have a solution. Perhaps not the most elegant, but it solves the problem.
I know this is possible to do because Opera-mini can go "full screen" and you can't drag down the task menu from the top; it is not visible to the user while in "full screen" mode.
I have an app in the market called "Airplane Mode Wi-fi Tool",
it allows the user to do this using the following method:
Settings.System.putString(getContentResolver(),
Settings.System.AIRPLANE_MODE_RADIOS, "cell,bluetooth");
Default RADIOS are "cell,bluetooth,wifi" (these are the radios that turn off when enabling airplane mode.
I don't think you will be able to do this as it would make airplane mode redundant. One would think that it would be possible to disallow airplane mode from starting somehow. I think the solution you are looking for is a bad idea as it modifies an application to make it useless while still allowing it to run. The problem is a design issue that should be solved by the phone creator. I have no real experience with android (yet) but I would imagine that the kind of functionality you are looking for in the standard framework wont be there.
I'm sure there is a reasonable way around this problem but its unlikely to be in the direction you are going.

Categories

Resources