Android app loses data when changing orientation

I have an application that I copied from a tutorial that captures an image using MediaStore.ACTION_IMAGE_CAPTURE. I have some kind of weirdness when I run the application on my phone.

The camera application itself flips its orientation a couple of times during operation, even if I do not move the phone. He soon goes into landscape mode before returning to the training application. Consequently, the training application returns to portrait mode after the control returns, and the image is lost. I tried to adjust the orientation of the camera activity to the landscape, and the image is not lost.

But the layout of the application is for portrait mode. Or, if I hold the camera in landscape orientation while capturing a photo, I can rotate the phone after my application returns to focus and does not lose the image.

I looked on the Internet several times. Someone from Stackoverflow noted that the change in orientation caused additional challenges onCreate. "The reason onCreate()you get called is because when you trigger camera activity during portrait orientation, it will change orientation and destroy the previous activity." I started the application in debug mode with breakpoints set in onCreate and in methods onActivityResult. Indeed true whenonCreateCalled when I take a photo in portrait mode. The order of calls is onCreate, onActivityResult, onCreate. If I take a photo in landscape mode (where the application for my camera ends), onCreate will not be called. Now that I have an idea of ​​what is happening, how can I get rid of this problem? Now, what does the application look like:

package com.example.testapp;

import java.io.IOException;
import java.io.InputStream;

import android.app.Activity;
import android.app.WallpaperManager;
import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ImageView;

public class CameraActivity extends Activity implements View.OnClickListener {

    ImageButton ib;
    Button b;
    ImageView iv;
    Intent i;
    final static int cameraData = 0;
    Bitmap bmp;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.photo_activity);
        initialize();
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        // TODO Auto-generated method stub
        super.onConfigurationChanged(newConfig);
        setContentView(R.layout.photo_activity);
        initialize();
    }

    private void initialize() {
        iv = (ImageView)findViewById(R.id.imageViewReturnedPicture);
        ib = (ImageButton)findViewById(R.id.imageButtonTakePicture);
        b = (Button)findViewById(R.id.buttonSetWallpaper);
        b.setOnClickListener(this);
        ib.setOnClickListener(this);
    }

    @Override
    public void onClick(View arg0) {
        switch (arg0.getId()) {

        case R.id.buttonSetWallpaper:
            try {
                WallpaperManager wm = WallpaperManager.getInstance(getApplicationContext());
                wm.setBitmap(bmp);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            break;

        case R.id.imageButtonTakePicture:
            i = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
            startActivityForResult(i, cameraData);
            break;
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        // TODO Auto-generated method stub
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_OK) {
            Bundle extras = data.getExtras();
            bmp = (Bitmap)extras.get("data");
            iv.setImageBitmap(bmp);
        }
    }
}

And here is what I have in the manifest for this activity:

                android: name = "com.example.testapp.CameraActivity"
                android: label = "Camera Activity"
                android: configChanges = "orientation"
                android: screenOrientation = "portrait" 

I have done a significant search, but much of what I think has no concrete examples. I need to know how the code looks, not just which function to use.

- LG Motion. - ? ?

+5
7

, configChanges:

 <activity
        android:name=".MainActivity"
        android:configChanges="screenLayout|orientation|screenSize">

, .

+8

onRetainNonConfigurationInstance getLastNonConfigurationInstance / .

:

// during onCreate(Bundle), after initialise()
bmp = getLastNonConfigurationInstance();
if(bmp!=null){ iv.setImageBitmap(bmp); }
else { /* the image was not taken yet */ }

u :

@Override
public Object onRetainNonConfigurationInstance (){
     return bmp;
}

"" .

onSaveInstanceState, , , :

public class SomethingSomething extends Activity{

    String name="";
    int page=0;

    // This is called when the activity is been created
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

            // if you saved something on outState you can recover them here
            if(savedInstanceState!=null){
                name = savedInstanceState.getString("name");
                page = savedInstanceState.getInt("page");
            }
    }

    // This is called before the activity is destroyed
@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);

            outState.putString("name", name);
            outState.putInt("page", page);
    }
}

, , , , Android Bundle Android , , , Parcelable ( ). , Bitmaps, Parcelable, , Bitmap Bitmap .

, setRetainInstance ( , \sdk\extras\android\support\samples\Support4Demos\src\com\example\android\supportv4\app\FragmentRetainInstanceSupport.Java.

, .

// This fragment will be managed by the framework but we won't built a UI for it.
public class FragRetained extends Fragment{
   public static final String TAG = "TAG.FragRetained";
   private Bitmap bitmap;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Tell the framework to try to keep this fragment around
        // during a configuration change.
        setRetainInstance(true);
    }
    public Bitmap getBitmap() { return bitmap; }
    public void setBitmap(Bitmap bmp) { bitmap = bmp; }
}

public class MyActivity extends Activity{

    private FragRetained myFragRetained;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
            // set the content view
            img = (ImageView)findViewById(R.id.byImgV);


            myFragRetained = getFragmentManger.findFragmentByTag(FragRetained.TAG);
            if(myFragRetained == null){
                myFragRetained = new FragRetained ();
            }else{
               Bitmap b = myFragRetained.getBitmap();
               if(b==null){
                  // the user still did not choose the photo
               }else{
                  img.setImageBitmap(b);
               }
            }
    }


    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_OK) {
            Bundle extras = data.getExtras();
            bmp = (Bitmap)extras.get("data");
            iv.setImageBitmap(bmp);
            myFragRetained.setBitmap(bmp);
        }
    }

}

android:configChanges="orientation" , , , , ,

. . , " " . , - .

+7

. , , . , , , ( ) : http://android-er.blogspot.com/2011/10/share-bitmap-between-activities-as.html

, , . :

package com.example.testapp;
 
import android.graphics.Bitmap;
 
public class CommonResources {
        public static Bitmap cameraBmp = null;
}

bmp CameraActivity.java CommonResources.cameraBmp.

, CommonResources.cameraBmp , ImageView.

onCreate initialize :

@Override
protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
              super.onCreate(savedInstanceState);
        setContentView(R.layout.photo_activity);
        initialize();
}

private void initialize() {
        iv = (ImageView)findViewById(R.id.imageViewReturnedPicture);
        ib = (ImageButton)findViewById(R.id.imageButtonTakePicture);
        b = (Button)findViewById(R.id.buttonSetWallpaper);
        if (CommonResources.cameraBmp != null) {
                   iv.setImageBitmap(CommonResources.cameraBmp);
           }
        b.setOnClickListener(this);
        ib.setOnClickListener(this);
}

, , onPause :

@Override
protected void onPause() {
        // TODO Auto-generated method stub
              super.onPause();
        if (isFinishing()) {
                   // Save the bitmap.
                        CommonResources.cameraBmp = null;
           }
}

: ?

+3

, , . onSaveInstanceState, , , onCreate. , . , parcellable , BitMaps.

, .

+1

, - , , , !

public Uri imageURI = null; Activity, URI ImaveView, ; onCreate() onSaveInstanceState()

@Override
protected void onCreate(Bundle savedInstanceState) 
{   
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_thisactivity);

    //restore the bitmap for the image
    if (savedInstanceState!=null)
    {
        imageURI=savedInstanceState.getParcelable("imageURI");
        ImageView photo=(ImageView)findViewById(R.id.image);
        photo.setImageURI(imageURI);
    }
}

@Override
public void onSaveInstanceState(Bundle savedInstanceState)
{
    super.onSaveInstanceState(savedInstanceState);
    savedInstanceState.putParcelable("imageURI", imageURI);
}

, - - , .

+1

android: launchMode = "singleTop" , . , , , , , .

        <activity 
            android:name=".FacebookActivity" 
            android:label="@string/facebook_app_name"
            android:launchMode="singleTop"
            android:configChanges="keyboardHidden|orientation"
            >
        </activity>
0

Use onSaveInstanceState and then the argument that you get through onCreate, or set in the manifest that you will process orientation changes using configChanges and specify which cases you want to handle yourself (for example, the orientation | screenSize | screenLayout).

0
source

All Articles