13
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;

public class MainActivity extends Activity {

    ImageView iv;
    Bitmap bTemp;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);




        Button cameraClick = (Button) findViewById(R.id.click);
        iv = (ImageView) findViewById(R.id.imageView1);

        final Bitmap data = (Bitmap) getLastNonConfigurationInstance();
        if (data == null) { 

           iv.setImageBitmap(bTemp);
        }


        cameraClick.setOnClickListener(myhandler);

    }


    OnClickListener myhandler = new OnClickListener() {
        public void onClick(View v) {
            Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
            startActivityForResult(intent, 0);
        }
      };


    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        Bitmap bm = (Bitmap) data.getExtras().get("data");
        iv.setImageBitmap(bm);

    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }




    @Override
    @Deprecated
    public Object onRetainNonConfigurationInstance() {
        bTemp = iv.getDrawingCache();
        return bTemp;
    }


}

I'm using a imageview to store the image which is captured using the Camera Intent but when the screen rotates the image is lost. I tried using onRetainNonConfigurationInstance() but its not working

And i don't want to write the image to afile.

oomkiller
  • 169
  • 3
  • 11

6 Answers6

13

You can avoid recreating the activity by setting the orientation and screensize flag in your Manifest file

android:configChanges="keyboard|orientation|screenSize"

If needed you can implement onConfigurationChanged() which will be called when the orientation changes. More information is in http://developer.android.com/guide/topics/resources/runtime-changes.html#HandlingTheChange

Bharath Kumar
  • 541
  • 3
  • 10
  • while this solved my problem, other factors like the keyboard appearing, etc. can also cause the problem. Append necessary conditions using the `'|'` operator (eg. `android:configChanges="keyboard|orientation|screenSize"`) – Kewal Shah Jul 04 '18 at 21:26
  • Thank Kewal, keyboard is an important parameter. Updated the same! – Bharath Kumar Jul 05 '18 at 05:46
6

this may help you...

@Override
protected void onSaveInstanceState(Bundle outState) {
    BitmapDrawable drawable = (BitmapDrawable) imageView.getDrawable();
    Bitmap bitmap = drawable.getBitmap();
    outState.putParcelable("image", bitmap);
    super.onSaveInstanceState(outState);
}

protected void onCreate(Bundle savedInstanceState) {
     if(savedInstanceState != null) {
        Bitmap bitmap = savedInstanceState.getParcelable("image");
        imageView.setImageBitmap(bitmap);
     }
}
Gopal Gopi
  • 11,101
  • 1
  • 30
  • 43
4

The reason why your image disappears when screen rotates is that the activity is destroyed and recreated. During such process, the selected image is not retained as you can read here

Caution: Your activity will be destroyed and recreated each time the user rotates the screen. When the screen changes orientation, the system destroys and recreates the foreground activity because the screen configuration has changed and your activity might need to load alternative resources (such as the layout).

If you want to retain the selected image you should not use Instance State as you can read here.

Bundle that the system saves for you with the onSaveInstanceState() callback—it is not designed to carry large objects (such as bitmaps) and the data within it must be serialized then deserialized, which can consume a lot of memory and make the configuration change slow. In such a situation, you can alleviate the burden of reinitializing your activity by retaining a Fragment when your activity is restarted due to a configuration change. This fragment can contain references to stateful objects that you want to retain.

I implemented this solution and you can find the code in my answer to this other question

Community
  • 1
  • 1
ilmatte
  • 1,732
  • 16
  • 12
0

getLastNonConfigurationInstance() returns an activity instance. You can fetch the previous value from that instance:

in your onCreate():

YourActivity prevActivity = (YourActivity) getLastNonConfigurationInstance();

if(prevActivity!= null) { 
      this.bTemp = prevActivity.bTemp;
   }

and your onRetainNonConfigurationInstance() method should be:

@Override
@Deprecated
public Object onRetainNonConfigurationInstance() {
    return bTemp;
}

and your 'onActivityResult()` method should be:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    bTemp = (Bitmap) data.getExtras().get("data");
    iv.setImageBitmap(bTemp);
}
Anup Cowkur
  • 20,443
  • 6
  • 51
  • 84
  • sorry. Missed some prefixes. Check it now. And you need to return the bitmap as Sherif said. – Anup Cowkur Nov 08 '13 at 10:29
  • Getting a cast Exception MainActivity prevActivity = (MainActivity) getLastNonConfigurationInstance(); if(prevActivity!= null) { this.bTemp = (Bitmap)prevActivity.bTemp; iv.setImageBitmap(this.bTemp); } – oomkiller Nov 08 '13 at 11:08
  • that's probably cause you're setting bTemp in the first place. Check updated code now. – Anup Cowkur Nov 08 '13 at 11:43
0

Instead of returning the DrawingCache which you did not even build (btw), return the Bitmap


Implementation:

In your onActivityResult, keep the bitmap in bTemp:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    bTemp = (Bitmap) data.getExtras().get("data");
    iv.setImageBitmap(bTemp);

}

In your configuration saving, save this bitmap:

@Override
@Deprecated
public Object onRetainNonConfigurationInstance() {
    return bTemp;
}
Sherif elKhatib
  • 45,786
  • 16
  • 89
  • 106
0

just use this in manifest file in activity tag of your activity

android:configChanges="orientation"
Rohit Lalwani
  • 529
  • 7
  • 14