deucalion0 deucalion0 - 1 year ago 73
Android Question

String variable ends up null, and I do not know why

I have been trying hard to create an activity which allows a user to take a photo and email this image using intents. I create the file name and store it in a string, but it eventually gets it value taken away. When it was being reset to null I ended up creating another string variable to hold its value so I could ensure nothing had access to changing its value, but the second string also ends up as null. I use the value of the string and pass it to the intent in order to add the just taken image as an attachment. Can anyone see why and how this variable is having its value changed?

Here is my class, with comments:

public class ImproveActivity extends Activity implements OnClickListener{
private static final String JPEG_FILE_PREFIX = "Improve_";
private static final String JPEG_FILE_SUFFIX = ".jpg";
private Bitmap mImageBitmap;
private ImageView mImageView;
private File storageDir;
private String mCurrentPhotoPath;
Button share, capture;
private String _path;
private File f;
//This variable holds file name
private String imageFileName;
//I am storing the file name variable here to keep its value
private String temp;

protected void onCreate(Bundle savedInstanceState) {
mImageView = (ImageView)findViewById(;
capture = (Button)findViewById(;
share = (Button)findViewById(;



private void dispatchTakePictureIntent() {

if(isIntentAvailable(getApplicationContext(), MediaStore.ACTION_IMAGE_CAPTURE)){

Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
try {
//f is the image
f = createImageFile();

takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f));
startActivityForResult(takePictureIntent, 1);
} catch (IOException e) {
// TODO Auto-generated catch block
Toast.makeText(getApplicationContext(), "error creating image", Toast.LENGTH_LONG).show();

Toast.makeText(getApplicationContext(), "no camera available", Toast.LENGTH_LONG).show();


public void onActivityResult(int requestCode, int resultCode, Intent intent){
Toast.makeText(getApplicationContext(), "returning", Toast.LENGTH_LONG).show();

if (requestCode == 1) {

mImageBitmap = BitmapFactory.decodeFile(mCurrentPhotoPath);
if (mImageBitmap == null) {
// bitmap still null
} else {
// set bitmap in imageview


private File createImageFile() throws IOException {
// Create an image file name
String timeStamp =
new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
imageFileName = JPEG_FILE_PREFIX + timeStamp + "_";
//display the current image file name
Toast.makeText(getApplicationContext(), imageFileName, Toast.LENGTH_LONG).show();

File file = new File(getAlbumDir().getAbsolutePath());
Toast.makeText(getApplicationContext(), imageFileName, Toast.LENGTH_LONG).show();
File image = File.createTempFile(

mCurrentPhotoPath = image.getAbsolutePath();
temp = imageFileName;
return image;


private File getAlbumDir() {
return storageDir = new File(

public static boolean isIntentAvailable(Context context, String action) {
final PackageManager packageManager = context.getPackageManager();
final Intent intent = new Intent(action);
List<ResolveInfo> list =
packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
return list.size() > 0;

public void onClick(View v) {
case :
//displaying the value of the string imageFileName, it is what it should be, the file name
Toast.makeText(getApplicationContext(), imageFileName, Toast.LENGTH_LONG).show();

//displaying the file name in temp at this point it is still the file name I need
Toast.makeText(getApplicationContext(), "temp is " +temp, Toast.LENGTH_LONG).show();
//Once the image is saved, clicking share to open chooser

//displaying the temp string the file name is gone it is now null ????
Toast.makeText(getApplicationContext(), "temp is " +temp, Toast.LENGTH_LONG).show();

Intent picMessageIntent = new Intent(android.content.Intent.ACTION_SEND);
File downloadedPic = new File(
"Camera/"+ temp+"jpg"); //I want to use the file name string to send the image via email
picMessageIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(downloadedPic));
startActivity(Intent.createChooser(picMessageIntent, "Send your picture using:"));

If anyone could shed some light on how this is happening I would be grateful.

Here is the logcat, I open the activity, take a photo, save it, then it goes back to the activity view, I press share and the toast displays the value of temp while the chooser opens.

11-25 17:56:34.573: D/dalvikvm(12037): GC_EXTERNAL_ALLOC freed 1176 objects / 87312 bytes in 53ms
11-25 17:56:39.313: W/IInputConnectionWrapper(12037): showStatusIcon on inactive InputConnection
11-25 17:56:49.803: W/System.err(12037): java.lang.NullPointerException: Argument must not be null
11-25 17:56:49.808: W/System.err(12037): at<init>(
11-25 17:56:49.808: W/System.err(12037): at<init>(
11-25 17:56:49.808: W/System.err(12037): at
11-25 17:56:49.808: W/System.err(12037): at
11-25 17:56:49.808: W/System.err(12037): at
11-25 17:56:49.808: W/System.err(12037): at
11-25 17:56:49.808: W/System.err(12037): at
11-25 17:56:49.808: W/System.err(12037): at
11-25 17:56:49.808: W/System.err(12037): at
11-25 17:56:49.813: W/System.err(12037): at
11-25 17:56:49.813: W/System.err(12037): at
11-25 17:56:49.813: W/System.err(12037): at$2400(
11-25 17:56:49.813: W/System.err(12037): at$H.handleMessage(
11-25 17:56:49.818: W/System.err(12037): at android.os.Handler.dispatchMessage(
11-25 17:56:49.818: W/System.err(12037): at android.os.Looper.loop(
11-25 17:56:49.818: W/System.err(12037): at
11-25 17:56:49.818: W/System.err(12037): at java.lang.reflect.Method.invokeNative(Native Method)
11-25 17:56:49.818: W/System.err(12037): at java.lang.reflect.Method.invoke(
11-25 17:56:49.823: W/System.err(12037): at$
11-25 17:56:49.823: W/System.err(12037): at
11-25 17:56:49.823: W/System.err(12037): at dalvik.system.NativeStart.main(Native Method)
11-25 17:56:50.273: D/dalvikvm(12037): GC_EXTERNAL_ALLOC freed 1920 objects / 108152 bytes in 136ms

Sam Sam
Answer Source

You should permanently save your Strings in a SharedPreferences, a database, or a generic file.

When you leave your Activity to take a photo with the built-in camera app, your app goes into the background. Any app in the background runs the risk of being killed by the OS if extra memory is needed. If this happens all of your variables are reset to their default null values...

From your LogCat:

java.lang.NullPointerException: Argument must not be null

I'm guessing that line 94 is:

mImageBitmap = BitmapFactory.decodeFile(mCurrentPhotoPath);

which makes sense if the app is destroyed and restarted behind the scenes. When the app is completely restarted like this, only onCreate() is called, not createImageFile() or any other methods.

Save mCurrentPhotoPath in the SharedPreferences as well imageFileName and restore these values in onActivityResult() whenever mCurrentPhotoPath is null.

Using SharedPreferences
Add these methods to your Activity:

private void savePreferences(){
    // We need an Editor object to make preference changes.
    SharedPreferences.Editor editor = getPreferences(MODE_PRIVATE).edit();
    editor.putString("imageFileName", imageFileName);
    editor.putString("mCurrentPhotoPath", mCurrentPhotoPath);

    // Commit the edits!

private void restorePreferences() {
    SharedPreferences settings = getPreferences(MODE_PRIVATE);
    imageFileName = settings.getString("imageFileName", "");
    mCurrentPhotoPath = settings.getString("mCurrentPhotoPath", "");

I ignored temp, as you said it was just a duplicate of imageFileName while you were debugging.
Now we need to call these methods at appropriate times. First lets save both Strings just before leaving the Activity to take a picture:

try {
    startActivityForResult(takePictureIntent, 1);

Then check if you need to reload these values in onActivityResult():

if (requestCode == 1) {
    if(mCurrentPhotoPath == null)

    mImageBitmap = BitmapFactory.decodeFile(mCurrentPhotoPath);
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download