I am using android:configChanges="orientation|keyboardHidden" in menifest. But still its refresh my activity. Here is my activity tag in menifest.
<activity
android:name="com.paksoft.people.MiActivity"
android:label="#string/app_name"
android:configChanges="orientation|keyboardHidden"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustPan" >
</activity>
It's possible that launching of ACTION_IMAGE_CAPTURE intent will push your activity out of memory. See for example: Android startCamera gives me null Intent and ... does it destroy my global variable?
In this situation, onCreate() of your activity is called before onActivityResult(). You should prepare your activity to reinitialize itself, probably using onSaveInstanceState(Bundle).
Note that the decision whether to shut down the activity, or keep it in background, depends on the overall system state that is beyond your control.
PS: android:configChanges attribute is irrelevant because the activity is destroyed not as response of the system to orientation switch (and this cannot happen with android:screenOrientation="portrait"), but because the system resources are drained by launching the Camera app to fullfill the ACTION_IMAGE_CAPTURE intent.
Related
When I pressing "home" button, app calling - (void)applicationWillResignActive:(UIApplication *)application, ok its good, but when I wait for a some time (10-15 mins), app starting from first loading screen, why? I have added:
[UIApplication sharedApplication].idleTimerDisabled = YES;
But not success. I think it goes to suspended mode, how do I prevent this? Thanks.
It means that your app has been killed by the system.
You can't prevent it completely, the system kills background apps when it needs more memory, but you can do something like this:
free as memory as you can when the app goes in background: doing this, when the system needs memory, your app won't be one of the first to be killed because its footprint is low.
Since you can't be sure that your app won't be killed, use state preservation / restoration: Link
EDIT:
since your app needs to reproduce audio in the background (as written in the comments) I give you some extra advices.
remember to register your app background mode (from this link: Multitasking guide) --> "by including the UIBackgroundModes key (with the value audio) in its Info.plist file"
the app continues to work in the background since it's playing audio, but when the audio is suspended the app is suspended too (it means that it can be killed). So, you must use state preservation to restore it when the user comes back.
Another extract:
"When the UIBackgroundModes key contains the audio value, the system’s media frameworks automatically prevent the corresponding app from being suspended when it moves to the background. As long as it is playing audio or video content, the app continues to run in the background. However, if the app stops playing the audio or video, the system suspends it."
You app has exited. If you want it to come back to where you left off you'll have to preserve the state somehow, check on launch, and then restore the state.
I'm building an app that is location-aware and triggers text to speech whenever the user gets near a certain point. I have singleton classes GPSManager (for getting location updates) and RouteDetails (for defining the points that should trigger the text-to-speech). I also have a view controller that shows a map updating the user's location from GPSManager and showing a route from RouteDetails.
What I want to do is keep the functionality of the view controller running when the app is suspended, i.e. be notified when the location is updated, compare it to the locations in RouteDetails, and then play the text-to-speech. However I can't seem to find a good example of this being done - how do I made sure RouteDetails and GPSManager stay in memory? And where should I put the text-to-speech module where it can access the details in RouteDetails and also be in memory so that it can play when the app is suspended and the phone is locked? I'm assuming the view controller can't receive notifications when the app is suspended.
Also, I've added the location and audio options to the UIBackgroundModes key in the Info.plist file. And I don't need the app to bring itself back into the foreground when it gets a location update/plays a sound, it just needs to play a sound and update a variable in RouteDetails.
I'm working on a radio alarm clock, and i have some issues.
I am using local notifications for the alarms, so it has a gentle fallback if the app is not running.
I am well aware of the limitations of the device, and i know what i can and cannot do when the device has gone into background.
But my question is this:
I have seen other apps starting an audio streamer when i've locked the device. How is this possible? May this be inside an execution-timeframe?
How is the best way to implement this? Is it any way i can activate a streaming session when the device is locked?
Edit
To clarify: I know how i make audio play in the background. But the issue is triggering the audio-playback when an local notification or some other event fires.
One app that seems to do this, is Radio Alarm Clock. I haven't tried it for long period of times yet. But it seems to do this. A video demo of the app: http://www.youtube.com/watch?v=KJQiFOcdBWk
Have you already declared your background task?
Support for some types of background execution must be declared in advance by the app that uses them. An app declares support for a service using its Info.plist file. Add the UIBackgroundModes key to your Info.plist file and set its value to an array containing one or more of the following strings:
audio — The app plays audible content to the user while in the background. (This content includes streaming audio or video content using AirPlay.)
iOS App Programming Guide - Implementing Long Running Background Tasks
You can add this by clicking on your main project icon, then under the Info tab you can add "Required Background Modes" to the "Custom iOS Target Properties" section. "App Plays Audio" will be one of the three default values.
Big Edit With New Answer:
If everything else is already in order, you can keep your app running in the background using the UIApplication method
- (UIBackgroundTaskIdentifier)beginBackgroundTaskWithExpirationHandler:(void (^)(void))handler
detailed here: UIApplication Class Reference
with an example here: Hour 21: Building Background-Aware Applications
This allows you to run an instance of NSTimer which triggers your music player. The difference between this approach and UILocalNotifications is that this method never lets the app fully enter the background mode, the music player exists the entire time which subverts the need to create it from the background, which looks to be impossible.
There may be limitations to how long of a timer you can set, I haven't tested this past 14 minutes out.
I have an app, that will keep track of everything the user do in the iPod app. To do this, I added few observers to NSNotificationCenter, like MPMusicPlayerControllerNowPlayingItemDidChangeNotification. But my problem is, I only get those notifications when my app is in the foreground, if its in the background, the system add the notification to a queue, and then the next time my app becomes active it delivers it to me. I have no interest in this queue, since I want to receive real-time notifications.
Is there any way for me to get those notifications even if my app is in suspended state? I want to run just 3 lines of code everytime I get this NowPlayingItemDidChange notifications for example.
Here is where I add the observer.
MPMusicPlayerController *iPodMediaPlayer = [MPMusicPlayerController iPodMusicPlayer];
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
[notificationCenter addObserver: self selector: #selector(handle_NowPlayingItemChanged:) name:MPMusicPlayerControllerNowPlayingItemDidChangeNotification
object:iPodMediaPlayer];
[iPodMediaPlayer beginGeneratingPlaybackNotifications];
Also, if I add another kind of object to the observer instead of iPodMediaPlayer, the observer won't call the method.
Thanks a lot,
Abras
iOS applications are suspended when they are not in the foreground. There are three exceptions to this rule. You can have code execute in the background if your application is
a) Playing audio. This means the application itself is actually generating audio. My understanding is that the MPMediaPlayerController iPodMusicPlayer object only controls the playback of the external iPod process, rather than playing audio from the app itself. Perhaps you could have some success if you called applicationMusicPlayer instead of iPodMusicPlayer and set the appropriate background flags in your applications Info.plist. This seems like the most legitimate way to get your application to work, but you wouldn't be able to control iPod playback from the iPod app, only your app and the system audio controls.
b) Get your app to monitor the location. If the app is using the GPS it can continue to execute in the background. Downside to this is that the GPS will drain battery, and users might be creeped out that you're requesting their location.
c) Ask UIApplication for extra time. If you use UIApplication's beginBackgroundTask method, your application will continue to run for a finite amount of time in the background. If your users are going to come into your application once every ten minutes or so, this could work as well.
Hope that helps.
Multitasking in iOS is currently a very restricted one. You may start a background task using beginBackgroundTaskWithExpirationHandler: method (of an UIApplication object), but it is intended to finish a finite-length task before going suspended. All background tasks may expire (and get terminated) before it finishes its job. You can check how much longer your application can run by checking backgroundTimeRemaining property of the application object.
As I explained here iOS receive Media Player Notifications when app is in background, there seems no way to get notifications from iPodMusicPlayer.
About Omar Raul Qazi answer:
a) i tried and I had no success. The music kept going down when pressing home button. I think this background flag only works for normal AudioSessions and not for MPMusicPlayer...
b) I am not sure this would work and I don't think Apple would like it when looking for approval
c) You can run in background only synchronous task. You cannot wait there for a notification. Am I wrong?
I want a functionality in which i want to detect if my device is being shaked.The problem is i can detect the shake with didAccelerate method of UIAcceleratorDelegate , but i dont know how to detect if the device is still shaking. I want to play an audio file when the user shakes the device for first time,i have to check if the user is still shaking the device while playing the 1st audio file,if it is still being shaked, then i have to play another file.
See the sample project GLPaint from Apple which was found by visiting http://developer.apple.com/iphone and entering "shake" in the search box. Developer account not required.
You might consider writing a Method that runs in a separate thread that polls wether your device is being shaken every now and then and fire events that you handle somewhere else in your code (or instead of that, handle whatever you want to handle within the threads context itself, even tough i would not recommend doing that).
You just have to make sure, that your "shake-detektor"-thread exits at some point in time, you probably want to do that when the second audio file stopped playing. So your loop could test on that condition.
Hope I could help a bit.