1

I want to create a very simple Android application called "Loyalty Card" to display the bar-code image for my food store on a telephone screen. The bar-code reader at the food store check-out can see this image and recognize me. I've tested this concept and it seems to work well.

However, since I only visit the food store weekly there's no reason to leave the application running (or even idle) in the background after the bar-code is scanned. It seems sensible to me to end, terminate, annihilate the application once I've checked out. And I think a reasonable user could see value in having a "close" button to do that.

By using onClick in the application XML and finish() within the Java method I've managed to get the close button to return from where it came. (By that I mean if the application was launched from the home screen by a shortcut then my close button returns to the home screen. If the application was launched from the app drawer the close button return to the app drawer.) In either case the application list still contains the running/idle application. I really, really want the application to end, stop, self-destruct, so to speak.

In reading about this topic I recognize that many people think this attempt to close an application using a button is not good practice. But for this use particular case the user likely won't want to pull up the bar-code again until next week, when he/she shops for food.

  • In my humble opinion I'd like the user to be able to click on the close button (a single step) and have the application itself completely stop itself.

  • The alternative is to expect the user to tap the back-button (or home), then the application-list button, perhaps scroll to numerous running other running applications, then a right-swipe to manually halt the application (four steps).

I don't know about you but I usually have a long list of running applications and seeing an extra application unused laying around is kind of a nuisance. Especially since in this use-case the user isn't likely to want to see that bar-code again for a week.

With that said, I'll admit I'm new to Java programming, much less programming for the Android platform. I'd like a suggestion for how to rewrite the Java code shown below so the closeIt method completely and absolutely destroys itself and (I'm guessing here) the main process.

Here's the Java code I've coded, based on searching this topic:

package com.example.loyaltycard;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
    /* Close the application without leaving it in the activity list */
    public void closeIt (View view) {
        finish();
        return;
    }
}

The XML to go with this Java code is shown here:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.loyaltycard.MainActivity">
    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/barcodeimage" />
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal= "true"
        android:onClick="closeIt"
        android:text="Close" />
</RelativeLayout>

Finally, thank you in advance for allowing me to write a long and detailed question. And I'm hoping we can avoid the discussion of whether this is a good practice. Rather I'd like to find a solution. And I promise not just to cut/paste your ideas, but research why what you suggest should work. So, you know, I truly learn from you.

EDIT: I'm using Android Studio as a development environment, which may complicate this, I think.

Scully
  • 39
  • 2
  • 1
    Back when they decided to not let you destroy activities I had a hard time accepting it, but they know their system better than you and I so just let it go. – ziondreamt Aug 09 '16 at 05:59
  • @ziondreamt I completely understand sometimes I may need to cut my losses and live with it. But I'm hoping I can learn something by along the way. Also I forgot in my original post to say that I was thinking of saving the main process ID and trying to kill that process in the child (which I think would kill the parent). If that is a useful strategy help me code something along those lines. I've tried myself with no success. Thank you – Scully Aug 09 '16 at 06:06
  • Well it looks from the below answer that I was wrong, I thought they deprecated/removed System.exit(), so cheers. – ziondreamt Aug 09 '16 at 06:11
  • Possible duplicate of [How to quit android application programmatically](http://stackoverflow.com/questions/6330200/how-to-quit-android-application-programmatically) – ישו אוהב אותך Aug 09 '16 at 06:14
  • @Scully check my answer – Sohail Zahid Aug 09 '16 at 06:30

2 Answers2

2
  public void closeIt (View view) {
        //super.finish();
        finish();
        android.os.Process.killProcess(android.os.Process.myPid());
        System.exit(1);
        return;
    }

Update: If you have 10,20 multiple Activities running and you want to finish all them and exit from system.

Create a static array in application class or constants class.

Constants

public class Constants {

public static ArrayList<Activity> activities = new ArrayList<Activity>();

}

MainActivity Add current activity reference in this array

activity = MainActivity.this; Constants.activities.add(activity);

public class MainActivity extends Activity {

    private ImageView ImageButton;
    private Activity activity;


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        activity = MainActivity.this;
        Constants.activities.add(activity);

        ImageButton = (ImageView) findViewById(R.id.camera);
        ImageButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                // existing app.
                if (Constants.activities != null) {
                    for (int i = 0; i < Constants.activities.size(); i++) {
                        Activity s = Constants.activities.get(i);
                        s.finish();
                    }
                }
                //super.finish();
                finish();
                android.os.Process.killProcess(android.os.Process.myPid());
                System.exit(1);
            }
        });
    }
}
Sohail Zahid
  • 8,099
  • 2
  • 25
  • 41
  • Does that still work? Are you sure Google doesn't send someone to break kneecaps when they see this? – ziondreamt Aug 09 '16 at 06:09
  • @ziondreamt yes it is. – Sohail Zahid Aug 09 '16 at 06:10
  • [System.exit() does not kill the Android Application if there is more than one activity](http://stackoverflow.com/questions/2033914/quitting-an-application-is-that-frowned-upon/2043734#2043734) – ישו אוהב אותך Aug 09 '16 at 06:13
  • @isnotmenow if you see i commented the `super.finish();` if you have super class you should also have to finish them. – Sohail Zahid Aug 09 '16 at 06:15
  • @SohailZahid: imho, it can't close multiple activities on the stack. It only close the activity where it resides. – ישו אוהב אותך Aug 09 '16 at 06:24
  • That `if (Constants.activities != null)` isn't going to be false much because you initialize `activities` with a new `ArrayList` in the declaration. – Arjan Aug 09 '16 at 06:38
  • @Arjan you are right but its good approach to always validate for avoiding exceptional cases. – Sohail Zahid Aug 09 '16 at 06:41
  • @Sohail Zahid: Thank you for the suggested code. I'm using Android Studio to implement my application. And the changes don't seem to change the user experience. While running debug traces it appears to my untrained eye that Android Studio is enveloping my code in a lot of other Java methods, which seem to handle the interaction of the application I write with the Android operating system. Android Studio calls my Java code "main" but I suspect that really, my code is far down the list of processes. If that's true I may not be able to kill all the parents on my own. I need to test more... – Scully Aug 11 '16 at 00:08
0

Instead of finish(), use finishAffinity() in your close-button

(note: Android 4.1+)

TWL
  • 6,228
  • 29
  • 65
  • @TML: I tried Sohail Zahid's suggested code using both `finish();` and `finishAffinity();` and the user experience is the same (the app doesn't close it merely is hidden and remains in the application list). I'll test more and report any additional findings. Thank you for your comment. – Scully Aug 11 '16 at 00:12
  • Im surprised Sohails method didnt work for you, the killprocess + sys exit shouldve done it. Go back out there and refine your google search for a programmatic force stop + removing from activity history. – TWL Aug 12 '16 at 07:00