I'm looking into making an app that prevents the default action on volume up / down key presses, and would like to get some input to see if I'd be wasting my time trying.
Here's the setup:
I have a Samsung Galaxy S3. I like to listen to music. Often i unintentionally change the volume of whats playing when the phone is locked and in my pocket.
At first i thought it would be simple; having tested a simple override of the onKeyDown() method for retrieving the integer values for the volume keys. Quickly i came to the realization that this would only work if i were to not lock my phone and keep ONLY that app open.
Next i found a few articles on Services, however i believe this also falls short for my needs as it's not a subset of Activity and so doesn't implement onKeyDown(); and unless I'm mistaken, a wake lock actually wakes and/or unlocks the phone?
Should I give up now, or is this actually achievable?
(actually it must be possible as the whole point of this is that i don't have to pay £3 for an app for this one feature. lol)
Note: Running 4.2.1
New to Android, but not to Java.
Steve.
Edit: Just a thought, but if i extended Activity to my own class (and override onKeyDown), and instantiated it in a Service as a static instance, would that custom activity persist while the phone is locked?
Edit2: I found this SO post which suggests using FLAG_SHOW_WHEN_LOCKED. I'll start looking at this when I get home, but I'm still open to suggestions and advice :D
Edit 3:
OK so tell me if i start losing the plot here...
Using a broadcast receiver i will listen for the ACTION_SCREEN_OFF flag. If that gets called, create my custom Activity (with the onKeyDown() Override) and set it to FLAG_SHOW_WHEN_LOCKED to take over my lock screen (i don't care because the screen is off). The receiver then listens for the ACTION_SCREEN_OFF, if called it will then destroy the Activity before showing the screen (or after, I'm not bothered if it flickers).
(possibly even just pause it, and only kill it if it detects an unlock).
Also a big thanks to #StoneBird for getting me this far, sometimes it helps to just hash it out with someone who knows what there talking about (hopefully ^_-).
Try this?
Settings.System
You can start a service and set system volume like every 1 ms to keep it at a steady level. No key checking should be needed since the value is overwritten every 1 ms.
Also, there are free volume keepers on the market so you don't have to pay for that.
Related
For some strange reason, which I'm not entirely sure why, I'm getting not only an ANR for my application, but also of the entire systemui. It's so bad that I HAVE to reboot, and after rebooting it has to "Optimize" all of my apps like it corrupted something (anyone have an explanation as to why this happens?).
I'm assuming that parts of my code are so bad that they're causing this, but should even malicious code be able to overload the systemui? Anyway...
What I am doing is that I'm attempting to launch a service to handle screen recording. The activity (from a fragment) asks for permission (which is obtained, and I see the Screencast icon in the top right corner of the screen), then it binds a service which handles any state changes. What I mean by state changes is this...
States:
Dead - Means it needs to be initialized and prepared
Alive - Means it needs to be start and is fully initialized/prepared
Started - Means it is currently recording.
Paused - Means it will start a new video after starting again, which it will combine all temporary videos into one (haven't worked out that details yet).
Stopped - Means combine any and all files into one, then send the URI through an intent in a broadcast (haven't gotten this far yet).
It goes from Dead -> Alive -> Started <-> Paused -> Stopped -> Dead. At least that's the overall plan. I plan on having a floating button that acts as remote for controlling the service, and hence broadcasting on a receiver (local) to my fragment which is waiting for it to be finished.
Now, enough of what I intend to have, lets get into what I have right now. It's kind of a mess, I've never done this stuff before, hence why I'm asking on here. Trust me when I say that I have tried a lot of stuff, and the unfortunate bit is, the only way to test out a new solution is to reboot and wait 15 minutes while Android optimizes everything again. Now I understand it's a "Long" code-segment, but I'll say that one place it crashes is stopRecording(), at line 216.
Code here.
Let me know if I should make any changes.
Lastly: Should any of this be run on another thread? Could that be the issue? Why doesn't the app crash only instead of systemui?
I am currently working on an audio player that is supposed to pause/stop when losing audio focus, for example when a call comes in.
While I got this working fine by using an OnAudioFocusChangeListener I want to enhance this function to behave differently under different circumstances.
As the application implements a timeout function in case the user has fallen asleep while listening I only want to resume playback when I can be positive that the user is still awake.
I figured I could pretty much ignore notification sounds like those of an incoming email, as these usually are only short clips and my audio continuing to play will not be a nuisance to the user, as it would be during a phone call.
Thus I want to limit pausing/stopping to situation where either a phone call comes in or the user makes a call.
I have seen that AudioManager has some convenient states to signal this, but upon calling AudioManager.getMode() in my OnAudioFocusChangeListener I do not get consistent output.
Sometimes an incoming call does generate MODE_RINGTONE, but often enough to render the function unreliable I get MODE_NORMAL.
I could actually live with not knowing the mode when losing focus as long as I get the correct mode when re-gaining focus, but also this doesn't seem to work reliably.
The only actual device I could test this behavior on is the Galaxy S2, running Android 2.3.6 (the application is API level 10 due to me using MediaMetadataRetriever, thus requires at least 2.3.3).
I have tested the loss and re-gaining of audio focus in various emulated systems, and overall it seems to be working better there, but I also don't really get the same results each time.
Maybe the problem is that I misunderstand what AudioManager.getMode() should return, maybe somebody could clarify this for me:
phone rings -> AudioManager.getMode() should return MODE_RINGTONE on focus loss
user makes or picks up a call -> AudioManager.getMode() should return MODE_IN_CALL on focus loss
doesn't pick up the call -> AudioManager.getMode() should return MODE_RINGTONE on focus gain
user hangs up -> AudioManager.getMode() should return MODE_IN_CALL on focus gain
Is that the way it is supposed to work? At least my tests suggest that this is the way it is supposed to be, but for some reason isn't all the time.
Another way I am trying to solve this problem is by using a PhoneStateListener, but the problem I have with this is that this requires my application to request the permission to read the phone state. As I am sharing my application, currently through SourceForge, later possibly through the Android Market, I would like to avoid using this kind of permissions.
So, coming to an end I would like to ask if the way I understand AudioManager.getMode() is correct and if there is any information on its reliability, as for me the results I get from it are kinda useless.
I am trying to figure out how to turn off the screen from within a service. I have already read this but I am failing to realize how to do this from within a service. I don't really want to deal with wake locks because as soon as the screen goes off, I don't really care about turning it back via java code. I just need a one time method for turning the screen off and I have searched forever on this.
I see two options:
(1) Create a dummy Activity and use it to get a Window object through the getWindow(); method. Then you would use an Intent to call the screen off from your Service.
(2) Use IHardwareService.Stub. Not part of the SDK, but there's a workaround in this blog post: http://www.tutorialforandroid.com/2009/01/changing-screen-brightness.html
BTW: I would strongly recommend the first option. You never know when a class that is not part of the SDK might change.
I am developing an android app which makes no reference to the sensor aspect of the phone. At a certain pint the program sends an sms and then sleeps for five minutes. If I move the phone during this sleep period a dialog box displayed earlier reappears. I realise this is rather vague without code at this stage but to start with is this something to be expected. I am wondering if one of the broadcast listeners is being triggered by the movement but even if this is so I cant make the connection with the dialog box. Any pointers will be much appreciated.
Fist off, I would take care of the orientation change possibility by forcing the app into an orientation by using the option in the manifest file.
Second, I would look at what other apps are on the device that might have an affect on this functionality. Assuming by your question, your app uses BroadcastReceivers. If this is the case, provided your business logic permits, use explicit intents ( new Intent(this, )) in place of implicit intents and receivers. If this is not possible because of business logic, then perhaps using permissions to protect against accidental implicit intent receive triggers. Ref: http://developer.android.com/guide/topics/manifest/permission-element.html (its a good starting place anyways).
Without more info on your specific business logic or source code I can't go much deeper into the problem, but my first suggestion would probably give the simplest result. Just remember to set this attribute for each activity that this problem affects.
Steve.
I am now programming a program that collects sensor data, e.g. acclerometer values for a whole day.
Current I just use an Activity and run the activity for a whole day (I turn off screen auto-black), and don't make any shortmessages or phone calls during the day.
I've heard I can make this kind of long running data collector in background using Service. But after I've checked the pedometer at http://code.google.com/p/pedometer/. I found that, when the screen blacks out, the pedometer does not work. (But An application like predometer should work in any case as long as the power is on.)
Although I don't care about the power problem of always sensing acclerometers, I do want to black out the screen to save the power in screen to record more acclerometer data points.
I am thinking about two ways:
1.Using an Service, however, as the pedometer application showed. When the screen blacks out, the service seems stoped working too! Maybe the code has bugs.
2.My application is still an Activity. But I change the scrren light into 0 or totally black to save power.
My question is that: for 1) does a Service have the abality to be always running even when the screen blacks out for a long time; For 2, how to change the screen light?
Thanks!
concerning 1 - what you need is a remote service. this is a service nearly similar to a 'local' service (that is used in the pedometer example) but can run even if no activity is bound to it, in the background. you can turn off the screen and even the activity can crash (in a bad case ;) ) but the service keeps running if you started it with startService(...) instead of bindService(...).
try getting through this and see if that helps.
concerning 2 - you should really use (1) ;)
You do not need a remote service - this can be done with a local Service.
Use the command pattern instead of the binding pattern for the service i.e. use startService() / stopService() rather than bind() / unbind().
In your service onStartCommand() method, return Service.START_REDELIVER_INTENT or something similar, so that the service lives longer than the Activity.
Now the trick: to keep the service processing properly when the phone goes to sleep, you need to work with a PowerManager.WakeLock. These are quite difficult to get right, and I don't think a full explanation is needed in this answer.
Here is some more info:
How to get an Android WakeLock to work?
Also try Lars Vogel's blog: Using Android Wakelock – Staying up all night long
Apologies for the summary answer, but your question is quite broad in terms that it touches on some advanced topics.
Background service can be implemented with IntentService for the most of the scenarios.
Make sure that the background service works in latest and earlier Android version like 2.3 or 2.2.
Designing background operations is different starting from Android 4.0.
Best Practices for Background Jobs
Performing Network Operations