I am trying to make an app where I can let a user select a picture to display on their profile. I am able to browse and set their selected image on imageview. But the image is lost once the the activity is destroyed. I tried to implement onSaveInstanceState but still it's the same. I'm wondering if I am using it correctly. I hope you can help a newbie like me. Thanks in advance. Here's the code that I'm using:
public class AccountFragment extends Fragment implements OnClickListener {
private LoginDataBaseAdapter loginDataBaseAdapter;
Bitmap image;
Bitmap bitmap;
String picture_location;
TextView textTargetUri;
ImageView targetImage;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_account, container, false);
textTargetUri = (TextView) rootView.findViewById(R.id.targeturi);
targetImage=(ImageView) rootView.findViewById(R.id.profpic);
targetImage.setOnClickListener(new ImageView.OnClickListener(){
@Override
public void onClick(View arg0) {
Intent intent = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, 0);
}});
if (savedInstanceState != null) {
//if there is a bundle, use the saved image resource (if one is there)
image = savedInstanceState.getParcelable("BitmapImage");
targetImage.setImageBitmap(image);
textTargetUri.setText(savedInstanceState.getString("path_to_picture"));
}
return rootView;
}
@Override
public void onSaveInstanceState(Bundle savedInstanceState){
super.onSaveInstanceState(savedInstanceState);
savedInstanceState.putParcelable("BitmapImage", bitmap);
savedInstanceState.putString("path_to_picture", picture_location);
}
@Override
public void onActivityResult( int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK){
Uri targetUri = data.getData();
picture_location = targetUri.toString();
textTargetUri.setText(targetUri.toString());
Bitmap bitmap;
try {
bitmap = BitmapFactory.decodeStream(getActivity().getContentResolver().openInputStream(targetUri));
targetImage.setImageBitmap(bitmap);
}
catch (FileNotFoundException e){
e.printStackTrace();
}
}
}
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
}}
By the way, you may have noticed that instead of using the onRestoreInstanceState after oncreate, I tried to use the different approach. I found an answer from another question that you can also implement it inside the oncreate. I used it since whenever I declare the function onRestoreInstanceState I am being asked to remove the @Override annotation.
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState){
image = savedInstanceState.getParcelable("BitmapImage");
targetImage.setImageBitmap(image);
textTargetUri.setText(savedInstanceState.getString("path_to_picture"));
}
In case of Bitmaps Instance State is not the suggested way to persist info about the selected image.
You can find the explanation here: Handling configuration Changes
I blogged extensively about it here: Retain selected Image during Screen Rotation
Below I paste my implementation of the illustrated solution:
1 - Create a Fragment and configure it to be retained in memory
2 - Use it in your Activity
Using onSaveInstanceState and onCreate/onRestoreInstanceState is for short term activity state preservation - but not to be used for persistent storage of the application's data.
You can read about onSaveInstanceState here
You can read about persistent storage here
codeMagic suggested using SharedPrefs (see persistent storage link) for your long-term persistent storage. If you wanted to do this, I would suggest saving the image URI (the link has a good example of how to do so) in you onActivityResult method, and then call a method to read the SharedPref and load the image that you can call from onCreate as well as from onActivityResult.
You may also want to store your own copy of the image/bitmap in your application's own internal storage (see persistent storage link).
if you are not finishing the activity, you can use
onSavedInstance()
to store thepicture_location
value and bind it back either inonCreate(SavedInst)
/onRestore()
from thepicture_location
value.