2012-03-13

Android Home Key disable / enable App Part 1


UPDATE:
I've decided to create an alternative "launcher" to solve this Home Key problem.  I am working on the code now.  The method I described here DOES disable the Home Key, but it does not allow you to enable it once again.  Being new to android, it seems fishy, and I'm guessing it is not good practice.  The method I am currently working on is more fitted to my needs anyway.  The launcher will take the place of the home screen and when someone hits the home key they will be asked to choose whether to use the standard launcher or my custom launcher.  At that point they will also be asked if they want to set that as the default.  Then the home key won't work inside my launcher and I will override the Back button to bring up a password screen, if they want to log out.  Once you get into a project you learn stuff and the whole project direction changes!



Home Key Lock/UnLock App:
---------------------------
DISCLAIMER:  I am currently trying to figure out how to get Blogger to accept my little html code snippets. It keeps giving me warnings and breaking the formatting. I will erase this message, of course, once I figure it out. 

 Okay a little project here.  Create a very simple app for Froyo 2.2 that will be able to toggle the functionality of the Home Key on and off, and some other things.  This is a very early exploratory exercise leading up to creating an educational app for Android pads.  I need for the children to be required to finish with a learning task before they will be given the opportunity to play their favorite games as a reward.  Meanwhile, they need to be locked into the learning game, so I need the Home key and Back key to be disabled.  That's the large goal.  Below is the simplified version broken into steps.

I'm using some code I got from this tutorial as a template:
http://hackaday.com/2010/07/19/android-development-101-part-2improved-hello-world/

I named it HelloWorldImproved.

Here is a list of the goals and some steps I need to take:

Find a way to lock out the Home and Back buttons altogether.  All entries will be made on the screen.  Some sort of override.

Add (GUI touchscreen) button that will close this app and open another.

Create a copy of the altered app.

In the copy app, change the function of the button so that it leads back to the original app.

Add a button on the app that releases the lock on the back button and home button and returns the funcionality of closing the app.  Actually, make this toggle that function and, when clicked, make it throw up a toast that says "Home Key Disabled" or "Home Key Enabled" depending.

Add a flag to the program that will not allow the change app button to work.

Add a button that flips the flag and releases the lock on the change app button.

Add a button that closes the app.  (This is merely to create code to close the app internally, rather then relying on the standard function of the Back key)

---------------

Okay, so first I made a copy of the whole HelloWorldImproved app that I created in the tutorial.  This left the primary activity named HelloWorldActivity which I didn't like, but after I figured out that it wouldn't be easy to change that, I just left it for now.

Then I made some changes so that I could add a second button.  At first I just wanted a button that did the same thing, but had different text on it ( and of course a separate id in the activity).
Step 1:
I opened the strings.xml (under res/values) and added this line:
<string name="press4app2">Press for App 2</string>

I put that line right under the Press Me! line.
Saved strings.xml

Step 2:
Opened up main.xml (under res/layout).  I copied the entire Button element and pasted the copy right below it.  I changed it so that it looked like this:
<Button
        android:id="@+id/switch1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/press4app2"
/>
As you can see, all I changed was the id (this is essentially the variable name or handle I can use over in the Java) and the text.  Now it refers to the string name that I created over in the strings.xml above, press4app2.

Step 3:
Then I opened up the main Java file, HelloWorldActivity.java.  I copied the entire OnClickListener mAddListener section.  The one with the comment "//Create an anonymous implementation of OnClickListener" at the top.  Be careful to get the one curly brace at the bottom.

I replaced mAddListener with mAddListener2 and I left everything else alone (for now), being that my first goal is merely to create a duplicate button that works.

Step 4:
Then back at the top of the HelloWorldActivity.java file...
We need to actually create the button.  So copy the four lines of code starting with "//Capture our button from layout"

  // Capture our button from layout
  Button button = (Button)findViewById(R.id.go);
  // Register the onClick listener with the implementation above
  button.setOnClickListener(mAddListener);

and paste them directly below themselves.  Now make them look like this:

  // Capture the switch button from layout
  Button switch1 = (Button)findViewById(R.id.switch1);
  // Register the onClick listener with switch1
  switch1.setOnClickListener(mAddListener2);

Changes?  Changed the comments to tell the truth.  Changed "Button button" to "Button swich1".  Changed "(R.id.button)" to "(R.id.switch1).  Changed button.setOnClickListener to switch1.setOnClickListener and changed that last parameter to mAddListener2 instead of mAddListener.

Step 5: (check for errors, make sure all is saved)
Make sure you save all of the files we changed:  main.xml, strings.xml and HelloWorldActivity.java.  Now run app and you will have two buttons that create toasts using the text you enter in the text field!  Woo hoo, it worked.

Now to create a button that will toggle the home key back on ( or back off again if hit twice )

Step 1:
edited the strings.xml file
Added this to the bottom of the file:
<string name="toggle_home">Toggle HomeKey ON-OFF</string>

Step 2:
Edited the main.xml file.  Added this under the last button:
<Button 
        android:id="@+id/toggleHome"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/toggle_home"
/>
Step 3:
Copied the OnClickListener and changed to mAddListener3

 // Create an anonymous implementation of OnClickListener
    private OnClickListener mAddListener3 = new OnClickListener()
    {
    public void onClick(View v)
    {
    long id = 0;
    // do something when the button is clicked
    try
    {
    helloName = (EditText)findViewById(R.id.helloName);
   
    Context context = getApplicationContext();
    CharSequence text = "Hello " + helloName.getText() + "!";
    int duration = Toast.LENGTH_LONG;
   
    Toast toast = Toast.makeText(context, text, duration);
    toast.show();
    }
    catch (Exception ex)
    {
    Context context = getApplicationContext();
    CharSequence text = ex.toString() + "ID = " + id;
    int duration = Toast.LENGTH_LONG;
   
    Toast toast = Toast.makeText(context, text, duration);
    toast.show();
    }
 
   
    }
    };

Step 4:
Edit Jave file and add onClickListener for the new button:
// Capture the toggleHome button from layout
        Button toggleHome = (Button)findViewById(R.id.toggleHome);
        // Register the onClick listener with switch1
        toggleHome.setOnClickListener(mAddListener3);

Step 5:  Check work, save, and see if it works.  (After that we will change what it doees to toggling that homeKey on/off)

Okay, that works.  Now to figure out how to give it the functionality I want.  I found this code laying around the interwebs...
-----------------------------------------------------
@Override
public void onAttachedToWindow()
{
   Log.i("TESTE", "onAttachedToWindow");
   this.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD);
   super.onAttachedToWindow();
}

public boolean onKeyDown(int keyCode, KeyEvent event) {
   if (keyCode == KeyEvent.KEYCODE_HOME) {
       Log.i("TESTE", "BOTAO HOME");
       return true;
   }
   return super.onKeyDown(keyCode, event);  
}
------------------------
Let's see what I can do with it.

The first thing I did was to implement that code and shut down the Home Key, without yet worrying about creating a button to turn it on and off.  I needed to import some things to make his code work.  Namely:

import android.util.Log;
import java.lang.Object;
import android.view.WindowManager;
import android.view.KeyEvent;
import android.view.ViewGroup.LayoutParams;

I added all of those to the top of the HelloWorldActivity.java file, where you always find lots of imports.
How did I know what to import?  I didn't!  lol!

I went over to the Android SDK site, http://developer.android.com/sdk/index.html, and I opened the "Reference" tab at the top.  This will take you to http://developer.android.com/reference/packages.html

In the upper right is a search engine for the whole reference section.  My friend!

For each of the variables in the code I was adapting I looked up something relevant and kept reading until I found our what package(s) I needed to import.  I actually did a little google searching too when I came up empty, until I figured it all out.  Believe it or not, I got lucky this time and it only took about 15 minutes to track down the appropriate packages.

I keep doing this enough and I just might learn something...

So, with all those imported, all of my little red X's disappeared and I ran it.  It worked!  At least inside the Android Virtual Device, the Home key is no longer functional.

Next, I need to find a way to turn that code on or off.  I'm thinking I'll create a flag, a boolean that will determine if the code is executed or not.  Then I'll make the button toggle that flag on and off.

UPDATE:
I've decided to create an alternative "launcher" to solve this Home Key problem.  I am working on the code now.  The method I described here DOES disable the Home Key, but it does not allow you to enable it once again.  Being new to android, it seems fishy, and I'm guessing it is not good practice.  The method I am currently working on is more fitted to my needs anyway.  The launcher will take the place of the home screen and when someone hits the home key they will be asked to choose whether to use the standard launcher or my custom launcher.  At that point they will also be asked if they want to set that as the default.  Then the home key won't work inside my launcher and I will override the Back button to bring up a password screen, if they want to log out.  Once you get into a project you learn stuff and the whole project direction changes!

2 comments:

  1. This code doesn't work on API 14+.

    ReplyDelete
  2. Yeah, as I mentioned in the update, I decided to go with a completely different solution. The code is really a hack and it doesn't surprise me that it doesn't work everywhere. A much better way is to do what I said under UPDATE above. It is not as hard to implement a simple launcher as it sounds, which will subsequently give you control over the home and back keys. Cheers!

    ReplyDelete

Let me know what you think!