Start Acitivity in background on Android 4.4 KitKat

For some reason, Android 4.4 KitKat has changed the implementation while starting activity.

In Android 4.3, Activity started from inactive Activity is also inactive.
But in Android 4.4, Activity started form inactive Activity will be brought to front.
Here, Inactive Activity means the activity paused by user pressing Home button or switch to another app.

This change won’t be felt in most sceanrios. But for activities that started from AsyncTask, it does have some significant impact on user experience.

I’m working on a app, that shows a Splash Screen when user logged in. And the Splash screen is implemented with activity.

It takes some time for app to communicate with backend server during the loggin in, and user might press “Home” button to temporarily leave the app during the time.

I don’t want the my splash screen to interrupt the user if the user returned to the home screen. So I wish to start the splash screen activity in the background if current acitivity has been brought to background.

It isn’t an issue on Android 4.3, but on Android 4.4 KitKat, it causes problem.
I googled this issue and tried the FLAG_ACTIVITY_MULTIPLE_TASK, and comfirmed that it is not helping to this issue.

So I have to come up some kind of “hacking” solution as described below:

I add a isPaused property to BaseAcitity, which is the base class of all activities in my app.

Add isPaused to BaseActivity
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class BaseActivity extends FragmentActivity {
public static final String START_FROM_PAUSED_ACTIVITY_FLAG = "START_FROM_PAUSED_ACTIVITY_FLAG";
protected boolean paused = false;
@Override
protected void onPause() {
super.onPause();
paused = true;
}
@Override
protected void onResume() {
super.onResume();
paused = false;
}
public boolean isPaused() {
return paused;
}
}

Then when I start the start the SplashActivity, I’ll put the isPaused value into the intent.

Add flag when start activity
1
2
3
4
5
6
7
8
Intent intent = new Intent(activity, SplashActivity.class);
boolean isStartingFromBackgroundActivity = activity.isPaused();
intent.putExtra(BaseActivity.START_FROM_PAUSED_ACTIVITY_FLAG, isStartingFromBackgroundActivity);
startActivity(intent);

And check isPaused value in onCreate callback in SplashAcitivity, and push the SplashAcitivty to background if the value is true.

Check flag when activity is created
1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (isStartedFromBackgroundActivity())
moveTaskToBack(true);
}
private boolean isStartedFromBackgroundActivity() {
return getIntent().getBooleanExtra(START_FROM_PAUSED_ACTIVITY_FLAG, false);
}

Reuse Android built-in Bluetooth Device Picker

Most Android devices support Bluetooth, and most Android ROMs has built-in bluetooth device picker, which is available to other system apps to select a bluetooth device. Theoretically the Bluetooth Device Picker could be reuse in any apps. But for some reasons, the API is not documented, and not published to everyone.

But it is possible to reuse such resources, so I wrote the following code. But due to the using of undocumented API, so it is not garenteed to work on all android devices.

Code is available as Gist

In the code I uses the Android Annotations, but it should be easy to remove the dependency on Android Annotations by adding a constructor to BluetoothDeviceManager that accepts Context.