jsundin
jsundin

Reputation: 226

Android launches system settings instead of my app

For some reason whenever I (try to) start my app the phone decides to launch system settings instead of my "main activity". And yes, I am referring to the "Android system settings", and not something from my app.

This only happens on my phone, and I suppose it probably could be related to the fact that my app had just opened system settings when I decided to re-launch with a new version from Eclipse.

It is possible to start the app from within Eclipse, but when I navigate back from the app it returns to the system settings rather than the home screen, as if the settings activity was started first and then my activity. If I then start the app from the phone all I get is system settings yet again.

The app is listening to the VIEW-action for a specific URL substring, and when I start the app using a matching URL I get the same result as when I start it from Eclipse, app starts, but when I return I return to settings.

I have tried googling for this problem, and all I could find was something about Android saving state when an app gets killed, but without any information on how to reset this state. I have tried uninstalling the app, killing system settings, rebooting the phone, reinstalling, clearing application data.. no luck..

For what it's worth, here's the definition of my main activity from the manifest,

<activity android:name=".HomeActivity" android:label="@string/app_name" android:screenOrientation="portrait" android:clearTaskOnLaunch="true" android:launchMode="singleTop">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
    <intent-filter>
        <action android:name="android.intent.action.VIEW"></action>
        <category android:name="android.intent.category.DEFAULT"></category>
        <category android:name="android.intent.category.BROWSABLE"></category>
        <data android:pathPrefix="/isak-web-mobile/smart/" android:scheme="http" android:host="*"></data>
    </intent-filter>
 </activity>

And here is the logcat-line from when I try to start my app, nothing about any settings anywhere.

I/ActivityManager( 1301): Starting activity: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=se.opencare.isak/.HomeActivity }

When I launch from Eclipse I also get this line (as one would expect),

I/ActivityManager( 1301): Start proc se.opencare.isak for activity se.opencare.isak/.HomeActivity: pid=23068 uid=10163 gids={3003, 1007, 1015}

If it matters the phone is a HTC Desire Z running 2.2.1.

Currently, this is my HomeActivity,

public class HomeActivity extends Activity {
    public static final String TAG = "HomeActivity";

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        Log.d(TAG, "onActivityResult(" + requestCode + ", " + resultCode + ", " + data + ")");
        super.onActivityResult(requestCode, resultCode, data);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        Log.d(TAG, "onCreate(" + savedInstanceState + ")");
        super.onCreate(savedInstanceState);
    }

    @Override
    protected void onDestroy() {
        Log.d(TAG, "onDestroy()");
        super.onDestroy();
    }

    @Override
    protected void onPause() {
        Log.d(TAG, "onPause()");
        super.onPause();
    }

    @Override
    protected void onPostCreate(Bundle savedInstanceState) {
        Log.d(TAG, "onPostCreate(" + savedInstanceState + ")");
        super.onPostCreate(savedInstanceState);
    }

    @Override
    protected void onPostResume() {
        Log.d(TAG, "onPostResume()");
        super.onPostResume();
    }

    @Override
    protected void onRestart() {
        Log.d(TAG, "onRestart()");
        super.onRestart();
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        Log.d(TAG, "onRestoreInstanceState(" + savedInstanceState + ")");
        super.onRestoreInstanceState(savedInstanceState);
    }

    @Override
    protected void onResume() {
        Log.d(TAG, "onResume()");
        super.onResume();
    }

    @Override
    protected void onStart() {
        Log.d(TAG, "onStart()");
        super.onStart();
    }

    @Override
    protected void onStop() {
        Log.d(TAG, "onStop()");
        super.onStop();
    }

    @Override
    protected void onUserLeaveHint() {
        Log.d(TAG, "onUserLeaveHint()");
        super.onUserLeaveHint();
    }
}

Nothing (of the above) is written to the log.

After reading Blundell's response I have tried changing the launchMode/clearTaskOnLaunch settings, with the following results,

Upvotes: 17

Views: 3036

Answers (4)

Karan
Karan

Reputation: 12782

You are not calling setContentView() from the HomeActivity (as per the code added by you). And when it is not present, different device behave differently, like on emulator you will see "Application not installed on your phone". Try setting content view.

Upvotes: 3

Tino
Tino

Reputation: 10489

Please note that I am not an Android developer, but I own an Android phone and think this issue is quite interesting.

To sum it up what I have read about this issue so far here it looks for me that following may be the root cause of this issue:

  • You use clearTaskOnLaunch, which wipes out all intents/activities/tasks/whatever_buzzword_is_used_for_this when your application starts.
  • Android then seems to remember permanently the last state of the application in some (what I now will call) global internal state database (GISD for brevity) which cannot be wiped that easily (at least not with uninstalling the application, rebooting, clearing intents, etc.).
  • Android tries to reopen the application with it's last state. If there is no current activity then this info is taken from the GISD, hence in your case it is "system settings".
  • There is no way (or it is unknown how) to wipe the state held in the GISD. (Your question is how to do that.)

If this is true this is clearly a phone issue, a major bug in Android, as you then can probably brick applications! All you must do is following:

  • Somehow provoke a similar thing like clearTaskOnLaunch - which should be possible - for the application you want to brick.
  • Trick the application to launch to some other application like "System settings" - many applications do this to enable WiFi or similar, but I think some clever people (read: not me) will find a way to do this for virtually any application
  • Now kill the application in this state.

Android will remember that state then in the GISD and if you try to launch the application from Home screen this will fail in future. Nice.

However even in the absence of a fix hopefully it is possible to bring back the application the same way:

  • Start your application with an Activity such that it launches. As you write, this works for you.
  • Apply what clearTaskOnLaunch does. (I really have no idea how, but you as Android developer probably know.)
  • Let your application launch a third application such that this third application becomes the global state.
  • Kill your application.

Perhaps timing and sequence is important, so perhaps you have to leave the third application after your application is killed, perhaps you have to pull the battery of your phone at the right time, perhaps you must use some weird ADB stuff to prevent your phone to do the right thing, perhaps you need another sequence of actions or somethign still is missing, whatever, even finding out how to provoke your type of error can be difficult - but thanks to your finding we know there is such a thing.

If you can make Android launch the third application from Home screen instead of your app this would confirm, that you indeed can fix that issue. If this does not work, so it is impossible to prevent Android to invoke system settings instead of your app, then Android certainly has a big problem, as it is likely someone finds a way to permanently brick apps in all those precious phones out there (ab)using that bug.

If the previous step works, however, the last step now is to let this third application launch back into the main screen of your application:

  • Start your application.
  • This will launch the third application.
  • Apply what clearTaskOnLaunch does.
  • Let the third application launch your application's main screen (or whatever you want)
  • Kill the third application (and perhaps your application).

Now the global activity state shall be set back to your application again - if everything goes well third application should not be harmed either.

Note that I am not sure this really can be done, as I am not able to test it myself. And having said that all, I agree that we certainly need be a better way to repair this issue!

But interesting would be to see what happens, if your app has the state of the third app and the third app has the state of your app. Does this lead to an endless loop?

Interesting too is, what happens if you deinstall the third app. Does this clean the automatic launch into that application or does it leave you helpless?

As an Android Phone onwer (only), I must say, that's quite a nice mess you have found. And that's why I am highly interested if there is a fix, as doing a factory reset cannot be considered a solution. Read: This is not only a developer problem, it affects Android users as well.

PS: Please forgive me my bad English, the length of this post, not using the right Buzzwords and posting on an issue which I am not an expert of so that my answer is a little bit OT. However I do this with HTH.

Upvotes: 0

Blundell
Blundell

Reputation: 76544

My 2Cents

You could look into the launch activity of the Application.

Basically what I think might be happening is, your app is being launched in the same 'Stack' as the settings was, therefore the OS will push the settings to the screen and then load your activity on top of that stack.

You could try adding:

android:launchMode="singleInstance"

into your <activity /> tag of your manifest file. This will start a new stack for your application and only your application

This may fix the issue but there may be another cause and this may cause adverse effects depending on how your app works. Have a look at the documentation for further info:Android:LaunchMode

EDIT

Reading your manifest, why not just remove android:launchMode="singleTop" and let it launch with the default?

Also you are pairing this with:android:clearTaskOnLaunch , because the OS has the settings activity and your activity as the same task it may be clearing it down to the 'root' activity which is the settings and not your app. Is there a reason you have this, remove it and try again?

Upvotes: 0

ThaMe90
ThaMe90

Reputation: 4296

I've tested this on my phone, but this seems to work correctly here... What if you try to create a new project, and then just copy the code into it? It worked for me, maybe it will work for you to...

I suspect it has something to do with your change of version of Eclipse, which might use some different setting from the version you used before, therefore rendering your initial set-up as useless...

Upvotes: 1

Related Questions