Another Android Blog

Insights into those hard to solve Android Development problems

Skip to: Content | Sidebar | Footer

Extending from Two Activities (sort of)

3 January, 2013 (15:03) | Uncategorized | By: Randall Mitchell

There are generally very few reasons to need to mimic multiple inheritance of activities. One example that *may* find use of this sort of thing is a situation where a library that has a base activity is used when the project already has a base class. Generally, you will want your base class to extends the library activity, but sometimes that is not possible. Then, it *may* be efficient to use the code I present here. Beat this code with a yard stick before considering its use. There is probably an alternative solution that is more elegant. Do you need to feel that your code in both acitivies must be tied to those activities or can code from one of the activies fall into a worker class that handles this extra code? It will probably be easier for the next guy to figure out what you did if you use a worker class instead.

ORIGINAL BASE ACTIVITES

// If we want to inherit from both of the below classes.
// methodThree has an argument to help understand how the arguments will work.
public class BaseActivityAlpha extends Activity {
    public void methodOne() {
    	// do something
    }
 
    public void methodTwo() {
    	// do something else
    }
}
public class BaseActivityBeta extends Activity {
    public void methodThree(int argument) {
        // do a third thing
    }
 
    public void methodFour() {
    	// do a fourth thing
    }
}

UPDATED BASE ACTIVITES

Create an interface for BaseAcitivtyB to some other class and move the code to some other class. Notice the interface methods accept a reference to an activity. This is because a lot of methods inside of an Activity require calls to the superclass Activity. Also notice the use of two interfaces to help ensure no methods are left behind. Making the conversion to BaseActivityB will not break any existing code either.

public class BaseActivityAlpha extends Activity {
    public void methodOne() {
    	// do something
    }
 
    public void methodTwo() {
    	// do something else
    }
}
public class BaseActivityB extends Activity implements BaseActivityBetaI {
    private BaseActivityBetaImplementation mImplementation;
    @Override public methodThree(int argument) {
        mImplementation.methodThree(this, argument);
    }
 
    @Override public methodFour(int argument) {
    	mImplementation.methodFour();
    }
 
}
public interface BaseActivityBetaI {
    public void methodThree(int argument);
    public void methodFour();
}
public interface BaseActivityBetaImplementationI {
    public void methodThree(Activity activity, int argument);
        public void methodFour(Activity activity);
    }
}
public class BaseActivityBetaImplementation implements BaseActivityBetaImplementationI {
    @Override public void methodThree(Activity activity, int argument) {
 	// do a third thing
    }
 
    @Override public void methodFour() {
	// do a forth thing
    }
}

NEW ACTIVITY THAT GETS FUNCTIONALITY FROM WHAT WAS TWO OTHER ACTIVITES

Notice that the following activity looks almost identical to BaseActivityB. We still have duplicate code; however, any implementation is only written once.

public class ActivityOfActivities extends BaseActivityAlpha implements BaseActivityBetaI {
    private BaseActivityBetaImplementation mImplementation;
 
    // methodOne and methodTwo are inherited
 
    @Override public methodThree(int argument) {
    	mImplementation.methodThree(this, argument);
    }
 
    @Override public methodFour(int argument) {
    	mImplementation.methodFour();
    }
 
    private void methodFive() {
    	// do my own thing
    }
}

Passing Toast Message to a New Activity

30 December, 2011 (21:25) | Activity, Messaging | By: Randall Mitchell

Greetings readers. I have implemented a “very basic” messaging system within one of my applications. An example use case is as follows:

1. User arrives at an activity.
2. The activity realizes that the user needs to be in another activity.
3. The activity posts a user message to the application and sends the user on their way to the other activity.

Here is why I made it for my application: In my Pitching Coach application, the user arrives at the pitch chart when a game is opened. If a pitcher has not yet been created for the game, the pitch chart sees this and sends the user to the create pitcher activity. The pitch chart posts a message similar to “you need to create a pitcher in order to start the game.” to the system and now the create pitcher activity tells the user why they are on that activity. Lets look at how I did this…


I create a custom application class by extending android.app.Application. This class will be live and accessible any time an activity for the app is visible. It’s as simple as creating an object that extends Application and putting the code inside of the root package directory for the app. Inside of the AndroidManifest I edit the application tag to contain the name of the new custom class. This hooks up your application to the new application class. Here is the snippet from the Android Manifest.

The AndroidManifest.xml file

<manifest
	...
	>
	...
	<application
		android:name="CustomApplication"
		...
	>
	...
	</application>
<manifest>

Inside of the new application class, I create a couple of methods. One for posting a message and one for displaying and deleting the message. I also create a member of type string named applicationMessage. Here is the code:

(Note: Since the work of posting a toast message is done here already, I also add the showToastMessage() method so I can quickly post a toast message to the user at any time. Extra little bonus :) )

The CustomApplication.java class

package com.mywebsite.myapplication;
 
import android.app.Activity;
import android.app.Application;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;
 
public class CustomApplication extends Application {
 
	public CustomApplication() {
		super();
	}
 
	/** ----------------------- MESSAGE HANDLING ----------------------- */
 
	private String message = "";
 
	public void setApplicationMessage(String messageText) {
		message = messageText;
	}
 
	public void showAndDeleteApplicationMessage(Activity activity) {
		if (message.length() > 0) {
			LayoutInflater inflater = activity.getLayoutInflater();
			View toastLayout = inflater.inflate(
					R.layout.toast_layout,
					(ViewGroup) activity.findViewById(R.id.toast_layout_root)
					);
			TextView text = (TextView) toastLayout.findViewById(R.id.toastlayout_text);
			text.setText(message);
			message = "";
			Toast toast = new Toast(this);
			toast.setDuration(Toast.LENGTH_LONG);
			toast.setView(toastLayout);
			toast.show();
		}
	}
 
	public void showToastMessage(Activity activity, Message messageText) {
		message = messageText;
		showAndDeleteApplicationMessage(activity);
	}
}


Now when I want to post a message for an activity I am going to launch. I simply call a reference to my application inside of the first activity and send it a message. Then, in an activity that may be receiving a message, I make a call to showAndDeleteApplicationMessage() inside of onResume() – or onCreate(). If the message string is empty, it does nothing. Here is some brief code on embedding the application class and posting the message:

package com.mymojosport.pitchingcoach;
 
import com.mywebsite.myapplication.R;
import com.mywebsite.myapplication.CustomApplication;
 
import android.app.Activity;
 
public class CustomActivity extends Activity {
 
    /** ------------------------ INITIALIZATION ------------------------- */
 
	private CustomApplication app;
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		// create a reference to the custom activity
		app = (CustomApplication) getApplication();
		// show any messages posted to the application
		app.showAndDeleteApplicationMessage(this);
	}
}

Now calling the activity and sending it a message is as simple as (from the calling activity):

app.setApplicationMessage("You need to create a pitcher in order to start the game.");
Intent intent = new Intent(this, CustomActivity.class);
startActivity(intent);

Hope this helps the world out there!
Randall

Are you an unemployed Junior Java Type?

8 October, 2011 (06:50) | Java | By: Randall Mitchell

I chanced upon this thread that might help to lift your spirits:

http://lnkd.in/a5Y9tV

It’s about looking for your first job.

Cheers,
Randall

Using Shared Preferences Explained

14 July, 2011 (17:09) | Data Storage | By: Randall Mitchell

This post explains further the example code on the Android Developer site:

http://developer.android.com/guide/topics/data/data-storage.html

I am trying to dumb this down as best as I can, so some useful options may be left out. Here is the code found on that page as of July 14, 2011:

public class Calc extends Activity {
    public static final String PREFS_NAME = "MyPrefsFile";
 
    @Override
    protected void onCreate(Bundle state){
       super.onCreate(state);
       . . .
 
       // Restore preferences
       SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
       boolean silent = settings.getBoolean("silentMode", false);
       setSilent(silent);
    }
 
    @Override
    protected void onStop(){
       super.onStop();
 
      // We need an Editor object to make preference changes.
      // All objects are from android.context.Context
      SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
      SharedPreferences.Editor editor = settings.edit();
      editor.putBoolean("silentMode", mSilentMode);
 
      // Commit the edits!
      editor.commit();
    }
}


Android has made storing application settings as simple as possible. Using the SharedPreferences object and a few methods build into the Activity class, we can quickly handle application settings.

First, we need to give our settings a name. In the example, Google names them MyPrefsFile. Changing the name will result in not finding your existing settings, so don’t change this ever.

public static final String PREFS_NAME = "MyPrefsFile";

Let’s look at the following line of code…

SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);

We need to create a SharedPreferences object. This is basically just a list of key-value pairs similar to a java HashTable. Think of it as a named array list. Our Activity has a built in method called getSharedPreferences() that will retrieve our existing settings for us. If they are not there already, Android will create one for us. All the heavy lifting is done without our help. We pass it the name of the preferences “file” we chose earlier. Remember, Android handles the “file”, all we do is pretend it’s there and Android will do the rest. The getSharedPreferences() method returns our key-value pairs object so calling…

SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);

.. creates a SharedPreferences object based on the settings named “MyPrefsFile”. We now have a list of all our existing settings. Lets get a setting.

boolean silent = settings.getBoolean("silentMode", false);
setSilent(silent);

We need the setting “silentMode”. We create a boolean object named “silent” and set it equal to the setting “silentMode” in our SharedPreferences we created earlier. The “false” is the default value…meaning if “silentMode” has not already been set, “silent” will be set to false.

The line “setSilent(silent)” is a call to a method we create in the Activity that tells our application to be silent. It is just an example of using the setting that we retrieved.

Now Lets look at how to store settings. In the example given by the Android team, settings are stored in onClose(). This means that any time an activity is closed the settings are stored. When we collected settings last time, we used SharedPreferences. That is a key/value pair holder. We need to do things a little differently to store/update new data… but we need to get the current settings and add them to any settings we are going to add or change. Lets grab the current application settings.

SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);


Now we need to create an object that handles storing and changing of settings. We create this “settings editor” using our existing settings. Let’s look at the code:

SharedPreferences.Editor editor = settings.edit();

Our SharedPreferences has built in functionality to create a “settings editor”. Explaining this line thoroughly would require a discussion on builders. Just know that we are creating an object of the form “SharedPreferences.Editor”. We name it “editor” and we use the edit() method of “settings” to create it with all of our current application settings ready to go. We now have a “settings editor”. Let’s use it.

Sometime during the life of our program, we set our “silentMode” setting to true. We want it to stay that way the next time the application opens. We call “putBoolean()” in our editor, passing in the name of our setting, “silentMode”. The mSilentMode is the boolean value that we need our setting set to, in this case it is equal to “true”.

editor.putBoolean("silentMode", mSilentMode);

With our new value stored in our settings editor, lets commit the changes.

editor.commit();

We write that one line of code, Android does the rest. Our settings have been stored. The next time this Activity runs, it will go to the top of the code discussed in the post, only this time it will find the value of silentMode is set to true and calling setSilent(silent) will be passing in true.

Let me know if there is any part of this post you don’t understand!

Randall

Protecting Your Android Application

8 July, 2011 (15:39) | Android Development, Security | By: Randall Mitchell

I was just thinking to myself, I need to make my published apps more secure. I found this post enlightening and a good start. It’s from the guy that wrote Android Wireless Application Development and covers obfuscation, using the Android License Verification Library, and SSL encryption for connected apps. Good stuff!

http://www.informit.com/articles/article.aspx?p=1725260

Custom Spinner Style

1 July, 2011 (14:35) | Uncategorized | By: Randall Mitchell

I’ll have to do this later on, so this post is just a “bookmark”. It seems to be the better one that I found on the subject.

http://www.mokasocial.com/2011/03/easily-create-a-default-custom-styled-spinner-android/

Button Hit Area for Custom Graphics

1 July, 2011 (14:13) | Components, UI Design | By: Randall Mitchell

I decided to create an “irregularly shaped” and small arrow image to be used as a button. The problem was, when I set it as a background image, the hit area only reported when the actual image was being hit. The quick fix is to use a drawable inset to create a bounding box around the image. Here’s my setup and the example image. This post is short and sweet. Leave a comment if you need further help – I’ll try to answer.

Button XML code:

/res/layout/batting_lineup_list_item.xml

...
<Button
    android:id="@+id/battinglineuplistitem_upbutton"
    android:layout_weight="40"
    android:layout_width="0dip"
    android:layout_height="40dip"
    android:background="@drawable/arrow_up_inset_drawable"
    >
</Button>
...

The Drawable Inset

/res/drawable/arrow_up_inset_drawable.xml

<?xml version="1.0" encoding="utf-8"?>
<inset
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/arrow_up"
    android:insetTop="16dp"
    android:insetBottom="12dp"
    android:insetLeft="8dp"
    android:insetRight="8dp"
    >
</inset>

The Button Graphic PNG Image

The @drawable/arrow_up reference is pointing to the drawable png file inside of the resources directory…

/res/drawable-hdpi/arrow_up.png
/res/drawable-ldpi/arrow_up.png
/res/drawable-mdpi/arrow_up.png

End Result

Have a great one!
Randall

Drop Shadow LinearLayout

29 June, 2011 (09:23) | Components, UI Design | By: Randall Mitchell

I thought I would share this quick tip I just cooked up. To create a drop shadow below a layout component, you can add a “view” of the same width immediately below that component and set the background of that view to a drawable xml file containing a gradient.

Here is an example layout file containing the item in need of a drop shadow. We want to place a drop shadow below the LinearLayout with id “some_layout_item” (see below). I place a generic view below some_layout_item and specify what ever height I would like. In this case, I set the height for 5dip. That is how high my drop shadow will be. I then set the view’s background to the drawable drop_shadow.

<RelativeLayout
    android:background="@color/cream"
    android:layout_height="wrap_content"
    android:layout_width="fill_parent"
    >
    <LinearLayout
        android:id="@+id/some_layout_item"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        >
        ...
    </LinearLayout>
    <View
        android:layout_below="@id/some_layout_item"
        android:layout_width="fill_parent"
        android:layout_height="5dip"
        android:background="@drawable/drop_shadow"
        >
    </View>
    ...
</RelativeLayout>

Now lets create that drop shadow drawable. We do this by creating the file “res/drawable/drop_shadow.xml” as coded below (if you don’t have a folder named drawable in the res directory, just right click res and create it). All that is in the file is a specification for a shape with a gradient. The startColor is the darker part of the shadow that sits below and touching the LinearLayout. All I did was make a darker color similar to the background color specified in the parent container. The endColor is the color of the parent container’s background.

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android=”http://schemas.android.com/apk/res/android”>    
    <gradient
        android:startColor="@color/cream_dark"
        android:endColor="@color/cream"
        android:angle="270"
        >
    </gradient>
</shape>

Suddenly, we have a drop shadow that just works. The beauty of using this inside of a relative layout is you can insert the drop shadow without changing a anything else inside of layout file.

Cheers,
Randall

Calling Activity for Result

9 June, 2011 (14:40) | Activity | By: Randall Mitchell

I was going to write one up but this site did the work as well as I could have: See the tutorial here

It’s really a relatively simple problem with a relatively simple solution. Like I prefer to do in my posts, however, the solution has been completely explained.

Ps. Nice blog template Sai :)

Passing Data With an Intent

27 May, 2011 (01:47) | Snippets | By: Randall Mitchell

This is the code to pass data from one activity to another through an Intent.

This is the code used to create and pass data into an Intent.

String dataToPass = "The next activity needs this sentence.";
...
Intent intent = new Intent(this, NextActivity.class);
intent.putExtras("KeyToAccessData", dataToPass);
startActivity(intent);

And this is how you catch that data from the receiving activity:

String dataToCollect;
...
Intent intent = getIntent();
dataToCollect = intent.getStringExtra("KeyToAccessData");

Note that the getIntent() method is part of the Android Activity class. Every Activity knows it’s own intent. We are just creating a way to reference it easily. You can also collect Integers (getIntExtra()) and other various data types using this method.


This post is part of a new snippet series I will be adding to my blog. Basically, it’s a way for me to quickly look up code when my brain decides to bury it. If I have to look it up more than once, I’ll try to add it here as well.