Can't exit an Android application - android

When I exit my android application it resumes to the previous screen. How can I exit the Android application properly?
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// TODO Auto-generated method stub
switch(item.getItemId()) {
case EXIT:
try {
this.finish();
} catch(Exception e) {
}
break;
}
return false;
}

The answer is that you shouldn't exit your Android application.
Have a look at this excellent answer for more information.

this.finish();
will only finishes your current activity , that's the reason your resuming to previous screen.
In android you can't kill the application.
Still you want to kill your application , then kill your process ID.

//Put this in to exit an application. Not a window
System.Exit(0);

If I don't exit my Android app such as myTuner, the radio station keeps playing...stopping it from playing is kind of ridiculous when exiting to give back the phone its memory makes every bit more sense. Whoever thought of allowing Android apps to just accumulate un-exited and slow down your phone made a huge mistake in my opinion.
It's how people want to user their phone that matters more than how someone else thinks they have to use it. I prefer freedom of choice for something that makes more sense.
Make apps you can exit out of like other OSes allow for.

Related

Screen Pinning unreliable: sometimes asks for passcode on awakening, other times skips directly to pinned app

(this question was originally posted on the android enthusiasts stub in a slightly altered form)
I've been trying to lock an android tablet in kiosk mode for a survey app I'm making; for that I've made use of the Screen Pinning lollipop feature (with passcode enabled).
I used the following code
#Override
protected void onResume() {
super.onResume();
startLockTask();
}
For the most part, this worked "reliably",
- If the application is pinned and the user lets the device screen time out (or presses the power/lock button), the device will enter sleep and next time he tries to awaken the device (via the power/lock button) the pinned app will pop into view again (without the user having to enter the passcode that he obviously doesn't know).
- On the other hand if the user attempts to unpin it, he/she is presented with the lock screen and the passcode.
So far so good.
However some times (and this is puzzling me) when the user tries to awaken the device, instead of going directly to the pinned app, the device will display the lock screen and ask the user for the passcode!
I'm not sure why the inconsistency in behavior (ie on wake, it sometimes asks for passcode, while other times goes directly to the pinned app) and couldn't find any mention anywhere of such a behavior.
Any input will be greatly appreciated!
Thanks!
Apparently every time the device wakes up, the startLockTask() is being executed. In case it was already in pinned mode this would run again, and cause issues.
Eventually, I tested out my initial assumption and edited the onResume() function to perform a startLockTask() only if it is not pinned already.
This seems to have solved the problems (even though I don't understand why it this behavior). Would be glad if somebody could explain this.
I'm posting the answer here for anybody who bumps into this issue.
onResume()
#Override
protected void onResume() {
super.onResume();
if(Build.VERSION.SDK_INT >=Build.VERSION_CODES.LOLLIPOP) {
if (!isAppInLockTaskMode()) {
startLockTask();
}
}
}
isAppInLockTaskMode() was taken from enter link description here and solves the issue for different API versions.
public boolean isAppInLockTaskMode() {
ActivityManager activityManager=(ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
if(Build.VERSION.SDK_INT >=Build.VERSION_CODES.M) { // When SDK version is 23
int lockTaskMode=activityManager.getLockTaskModeState();
return lockTaskMode != ActivityManager.LOCK_TASK_MODE_NONE ? true : false;
}
else if(Build.VERSION.SDK_INT >=Build.VERSION_CODES.LOLLIPOP &&
Build.VERSION.SDK_INT< Build.VERSION_CODES.M) {
//When SDK version <=21 and <23. This API is deprecated in 23.
return activityManager.isInLockTaskMode();
}
else {
return false;
}
}

Android close an application

I've read there are a lot of ways to close an application, so I would like to know if this way is correct or there are defects
main_activity.java
public boolean onOptionsItemSelected(MenuItem item) {
.....
.....
else if (id == R.id.exit) {
onDestroy();
}
}
#Override
protected void onDestroy() {
System.exit(0);
super.onDestroy();
finish();
}
Is this conceptually correct?
To close your app, this pinch of code will help you do the job.
android.os.Process.killProcess(android.os.Process.myPid());
Android How to programmatically close an app..
But you may want to know that I have never seen this approach in use anywhere. Even apps from certified developers do not try to close and remove themselves from processes. What you can really do and preferred is finishing all the running activities and services and hence allow user to kill apps from recent apps himself (default behaviour of any app).
This functions closes all activities but not app -
finishAffinity(); // API 16
Or you can call
finish();
everytime you end an activity.
These do not close Services to best of my knowledge and you programmatically have to stop running Services.
Cheers!
The best way to exit an app is using
finishActivity();
You don't want to kill the whole process, it is not good practice.

Disabling first-run greeter on fresh android emulator

I am writing a test that requires launching application directly from launcher. Because I can't emulate it correctly by launching through intent.
The problem is that when I am running the test on a fresh emulator (I am using Travis CI, but it can be easily reproduced on my home PC) the emulator starts with the "first run" greeter overlay. Which blocks my uiautomator code from correctly launching the application.
I have tried to add some code to close that greeter but unfortunately it can appear with some delay, when my "greeter detecting and closing" code has already stopped working thinking that the coast is clear.
Is there any guaranteed way to disable that greeter? Some preference maybe or just an example of code that will reliably kill the greeter.
Have you tried using PackageManager.getLaunchIntentForPackage(..)? This will allow you to send the same Intent that the launcher uses to start your app. It should be equivalent to clicking on your application's launcher icon.
If you do need to go through the launcher, you can use a UiWatcher to dismiss the first-run overlay. Whenever UiAutomator can't find an element, it will call the checkForCondition(..) method for each registered UiWatcher and give you a chance to dismiss any overlays or dialogs that are getting in the way.
Apparently the greeter is called "cling". Searching though (rather old) code I found the following:
http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android-apps/4.0.2_r1/com/android/launcher2/Launcher.java#Launcher.isClingsEnabled%28%29
private boolean isClingsEnabled() {
// TEMPORARY: DISABLE CLINGS ON LARGE UI
if (LauncherApplication.isScreenLarge()) return false;
// disable clings when running in a test harness
if(ActivityManager.isRunningInTestHarness()) return false;
return true;
}
And next stop is isRunningInTestHarness() at http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.0.2_r1/android/app/ActivityManager.java#ActivityManager.isRunningInTestHarness%28%29
public static boolean isRunningInTestHarness() {
return SystemProperties.getBoolean("ro.test_harness", false);
}
Which in turn leads to adb shell setprop ro.test_harness true. Which just works.

Move back to App after launching another App

I have a situation which I have been working on for close to a week now but can not come up with a working solution.
I have an app, which will launch a terminal window and run a command, the terminal used is Jack Palevich's Android-Terminal-Emulator (source code here) and the code used to launch a window is:
public boolean runCommand(String command) {
Intent intent = new Intent("jackpal.androidterm.RUN_SCRIPT");
intent.addCategory(Intent.CATEGORY_DEFAULT);
intent.putExtra("jackpal.androidterm.iInitialCommand", command);
if (mHandle != null) {
// Identify the targeted window by its handle
intent.putExtra("jackpal.androidterm.window_handle", mHandle);
}
startActivityForResult(intent, REQUEST_WINDOW_HANDLE);
return true;
}
Now this works fine, however the issue is that there are a number of times in the apps life that it will need to pass a command to this terminal window, and no user will be interacting with the device (i.e it will need to be automated).
When you launch a terminal window that window becomes the activity in view, therefore while my app still runs in the background any future calls to runCommand() will not happen until my app is brought back to view.
So I need to find a way to have my app become the app in view again once it has called runCommand() and started the terminal. I have tried a number of routes but with no really success, I guess the only really way forward will be to make changes to the terminal app itself, which I am happy to do (I have the source download and tested) but am just a little stuck as to where to look and what to change.
If you need any more info about my app or anything else, let me know!
Thank you

Catching when the user pressed the Home Button

I would like to know when the user pressed the home button while he was running my app.
BUT:
The problem is that I don't want to edite the existing code.
meaning I don't want to add logic to the existing activities onPause() method.
The only solution I found was to add a service to the application which listens to the Log detecting if there was an intent to run the
HOME: Starting: Intent { act=android.intent.action.MAIN
cat=[android.intent.category.HOME]
Is there any other way to do it or is it really impossible?
The optimal solution would have been to catch an intent in the Manifest.xml, like:
action android:name="android.intent.category.HOME"
and implement a new class to catch it. (But it doesn't seem to catch it).
I would like to know when the user pressed the home button while he was running my app.
What specifically are you trying to achieve?
BUT: The problem is that I don't want to edite the existing code.
By definition, that is impossible.
The only solution I found was to add a service to the application which listens to the Log detecting if there was an intent to run the
That is modifying the code, violating your own requirement. Moreover, it requires a permission that really you should not be asking for.
Is there any other way to do it or is it really impossible?
That depends on what specifically you are trying to achieve.
The optimal solution would have been to catch an intent in the Manifest.xml...and implement a new class to catch it. (But it doesn't seem to catch it).
HOME is a category. It is not an action. Home screens are activities that respond to the MAIN action in the HOME category. However, it is modifying the code, violating your own requirement.
You can use key press event handler
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_HOME) {
// Home key pressed
} else {
return super.onKeyDown(keyCode, event);
}
return false;
}

Categories

Resources