How to launch a background activity from a widget? - android

I have an android widget which has a very simple function. The widget simply launches an activity when pressed, runs through the activity, pops a toast, and closes the activity.
The annoying thing is that when the widget is pressed on the home screen, the screen flickers as it opens and closes the activity. Is there any way to launch the activity from the background, to avoid this flicker? I'm kind of looking to do something similar to the ATK widget, which simply pops up a toast after closing all the background processes.
If it's possible to just run a single function in place of a PendingIntent, that would definitely work as well. Thanks!

I eventually did this by implementing a service instead of an activity. The service runs in the background and then stops itself once it has finished. The PendingIntent simply launches the service, using the getService() method of PendingIntent.

I know I'm very late, but I was having a similar problem and I didn't want to use a service.
If your activity is very quick, it is enough to modify your manifest and insert this into the activity your widget will be launching,
android:theme="#android:style/Theme.Translucent.NoTitleBar"
This way your activity will be transparent thus no flickering will be seen and, being it very quick it won't get in the way.
Please note that this may only be used if your activity is fast, otherwise it will result in a frozen effect.

I'm doing this kind of thing using Application class. You need to declare your own - e.g. MyApplication class (need to be declared in Android manifest) and during creation MyApplication just launch separate Thread:
public class MyApplication()
{
// only lazy initializations here!
public MyApplication()
{
super();
}
#Override
public void onCreate()
{
super.onCreate();
Log.d(TAG, "Starting MyApplication"+this.toString());
Thread myThread=new MyThread();
myThread.start();
}
}
So in the end you will have "background" application which doesn't contain any activities. Application will be alive while your thread is alive. From those thread you can start whatever you want - for instance popup window, toast or any activity - depending on what you want.

Related

How can AlarmBroadcastReceiver check if there is no Activity from specified package running

Currently, I have a stock market app. When the stock market app "quit", it will start AlarmBroadcastReceiver, to monitor the stock market in background.
This code would looks like this.
// Code from main activity.
#Override
public void onPause() {
super.onPause();
ConnectivityChangeBroadcastReceiver.startAlarmBroadcastReceiver(this);
However, there's a tricky part here. It is extremely difficult to tell, when an app is "quit".
From end user perspective, "quit" really mean, when there is no Activity screen from the app package visible on screen.
onPause will be triggered in the following situations
Back button pressed. - Should start AlarmBroadcastReceiver
Home button pressed. - Should start AlarmBroadcastReceiver
Launch another Activity (Like settings preference activity) from main Activity. - I wish not. But it will start AlarmBroadcastReceiver with current code
It is difficult to differentiate Back button pressed / Home button pressed with Launch another Activity from main Activity.
Using isFinishing wouldn't work for my case, as it only return true during Back button pressed, not Home button pressed
Hence, I decide to install the following logic, at the early of AlarmBroadcastReceiver's onReceive
public class AlarmBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// If the current on screen activity, is *SAME* application package
// as AlarmBroadcastReceiver. This mean our app is not "quit" yet.
// We should return early without performing anything else.
However, I realize this is not an easy thing to do, as I can see from
How to get current foreground activity context in android?
ActivityManager's getRunningTasks is depreciated in Android 5.
Or, according to answer of gezdy, you need to have "hacky" code to update a global static variable, in every Activities in your app.
The suggested solution doesn't really look much elegant, and maintainable to me.
I was wondering, is there any better workaround, for my case? So that I can prevent AlarmBroadcastReceiver from running its logic code, when other Activity within same package is still visible on screen.
Hope this help to some extent. This is what I found while googling around.
You can register Activity Life Cycle with registerActivityLifecycleCallbacks(Application.ActivityLifecycleCallbacks callback)
, but introduced in API Level 14.
A blog written by Steve Liles - Is my Android app currently foreground or background using ActivityLifecycleCallbacks

Which is better to use : A service or a translucent activity in Android?

I'm using a transparent activity as the MAIN,to test a certain variable, and depending on its value, the transparent Activity will intent a certain Activity.
Since the transparent activity will be paused after it's executed, i'm wondering if it's better to use a Service instead of the transparent Activity.
services are used for long runnig task to do in background like playing mp3 files. you can use
activity . there is no problem in that . it will hardly take to move to next activity .
you can also use a application class.This class will always be executed once before staring the launcher activity. example
create a class
public class MyApplication extends Application
{
#Override
public void onCreate()
{
super.onCreate();
// here check for your variable
//start your intent activity frokm here.
}
in menifeast give name of your class.
<application android:name="com.myname.MyApplication"
android:icon="#drawable/icon"
android:label="#string/app_name"></application>
what you can do is create a launcher activity....in its onCreate method check your variables and start the intent and finish this activity in oncreate itself. this way it is correct.
You could subclass your own MyApplication class from android Application class. In MyApplication.onCreate you can then check the variable and launch the corresponding activity,
Service is used for doing a background operation so that even if your activity loses focus the code runs without any problem. So it all depends on you, if your user close your activity while it is executing your code then go ahead and use it.

Android: How to backup a database when the application gets closed?

I am needing help to determine the right approach. I want to make a backup of an internal database to a location in the external storage every time the whole application gets interrupted or terminated/destroyed. I want to call this method from a central class called Main which extends Application. The reason for that is, that I need to use several activites and I want to call the backup Method only when needed (like described when the whole application gets destroyed or interrupted by another application). I try to avoid calling this backup method in every activity in their onPause() methods.
I thought about starting a service in the onCreate() method of the application, and starting the backup method when the service gets destroyed. But this won't help in the case of an interrupt, as far as I understood the logic behind services. And also the service doesn't seem to start. startService(new Intent(getApplicationContext(), BackupService.class)); Furthermore I don't think it is a good approach to just use the onDestroy() method of a service, this is not what the service class is made for in my opinion.
So summarizing my Question, do you know a better way then using a service, or if not do you know how I should use the service to be able to call a backup only at the point when the whole app (and not only an activity) is interrupted or destroyed.
First of all, if your service "doesn't seem to start", you are probably doing something wrong.
To accomplish your goal make a backup of an internal database to a location in the external storage every time the whole application gets interrupted or terminated/destroyed:
There are three cases in general here.
If you want to do it in the activity layer:
To know when your application is crashed, you need to implement a custom handler to catch the uncaught exceptions.
To know when your activity is "interrupted", the only way is do it in onPause.
To know when your activity is "terminated", the only way is to do it in onDestroy.
This will require you to have a clear navigation and only do it in your "main activity", and all the other activity starts and comes back to it OR use a flag to indicate if the pause was caused by going to another activity.
If you want to do it in the service layer: (Your way of doing it onDestroy won't allow you to detect interrupted case since you will have to start service sticky to keep it running)
You will have to set up a flag on each activity onBind (you will have to bind it and unbind it) to know if it is a crash/interrupt/termination, which will complicate other part of your code.
To avoid running repetitive code, you will have to create a generic base class and extend your other activities from it.
I use this approach to play background music in one of my games, but I guess it works in this scenario as well.
Use a boolean flag to indicate whether or not your app is launching another part of your app.
boolean movingInApp = false;
....
movingInApp = true;
Intent intent...
.....
public void onPause() {
if(!movingInApp) {
//start service
}
}
public void onResume() {
movingInApp = false;
//Stop service
}
By setting the value of movingInApp to true before launching any intent etc, you can prevent your app from starting the service. Remember to set it to false again later in your onResume() method. If the system makes your app go to the background, this will be false, and your service will be started.
Why dont u have all of your activities extend a base activity which in turn extend the android activity class
I the base activity have backupDB method in the onPause
Therefore u dont have to put it in every activity pause method

Launch service from app start, not activity

I want to launch a Service when the app is launched instead of an Activity; and then said Service will launch an Activity. I need to do this because my app needs to be running ALWAYS, and when I say ALWAYS I mean ALWAYS. And the only way I've managed to avoid the OS killing my app is by starting a service as Sticky and should Android kill either my Activity or my Service I'll restart them right away.
I found this question but the top answer seems rather clumsy, any one has a better idea?
PS: I know this doesn't look like a very friendly app but this is a very specific research scenario and it's not intended for regular users, i.e. the phone is solely used for this purpose; but even if memory is dedicated to my app Android keeps killing it every now and then... Any doubts I might have had about Android's purported strict memory management scheme are now gone.
In general Activity does NOT have to show any UI - it usually does but it is NOT mandatory. So you can simply set app's starting point to your "invisible" activity. And invisible means either themed as
android:theme="#android:style/Theme.NoDisplay"
or simply your code will not do any setContentView() and once it's job is done in your onCreate(), you start another activity and terminate this one with finish() - and no UI would pop up from that activity - that way you can easily benefit from doing your job in activity subclass (which may be simpler for some tasks) and still do not need any UI:
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
// [... do your job here...]
// we're done, so let's jump to another acitivity
// this can be skipped if you do not want to jump anywhere
Intenet intent = new Intent(....)
...
try {
startActivity( intent );
// finish him
finish();
} catch ( Exception e ) {
e.printStackTrace();
}
}

Android OnApplicationPause/OnApplicationResume

Is there any way to handle when my android application goes into background and back?
I want to use notification service for a on-line game - I use a service, which shows an alert when something happens in the game. I want alerts to show only if my application is active (on the foreground), so I need to start my service when application goes foreground and stop it when application goes background.
Note that I cannot use Activity.OnPause/OnResume methods. I have many activities in my application, and if I'll handle OnPause/OnResume, it is possible in a moment, when a user swtches one activity to another, application will look like background, thorough it will be foreground actually
Note that I cannot use Activity.OnPause/OnResume methods. I have many
activities in my application, and if I'll handle OnPause/OnResume, it
is possible in a moment, when a user swtches one activity to another,
application will look like background, thorough it will be foreground
actually
Why don't you write a base class that extends Activity and enables or disables the service in these methods? After that extend all your activities from this base activity.
All you have to do is call the superclass method if you override these methods in your activties, e.g. by calling super.onResume() inside onResume(), to make sure these get still called. If you don't override them, everything works directly.
Not a clean way of doing this that I know of but,
You could perhaps send an Intent to your Service onCreate() and onPause() with a unique identifier.
You Service can then start a timer (with a delay which will be longer than the difference between onPause and onCreate being called in each activity) which, if not notified of an onCreate() within this time will set the Activity as "Paused".
If you add this functionality in a parent class which extends Activity you can then pull this same functionality into every class by extending that it rather than Activity (with the contract that you must call super.onCreate() and super.onPause() in each respective method).
Problem solved in a following way (C# code, mono for android)
class MyService : Service{
OnSomethingHappened(){
ActivityManager am = (ActivityManager) GetSystemService(ActivityService);
if(am.RunningAppProcesses.Any((arg) =>
arg.ProcessName == "myprocessname" &&
arg.Importance == ActivityManager.RunningAppProcessInfo.ImportanceForeground
)){
Trace("FOREGROUND!!!!");
}else{
Trace("BACKGROUND!!!!");
}
}
}

Categories

Resources