0
I have a Activity
with a EditText
and a Button
. When the button is clicked, the typed text is saved in a Activity
and the camera is opened with the method startActivityForResult()
.
When the user takes the photo and clicks save, the method onActivityResult()
is called but the attribute is null
.
I researched about and found that depending on some settings can prevent the Activity
to be destroyed, but should only be used as a last resort. I then followed the most recommended way and none of the techniques I read on Stackoverflow (except SharedPreferences
) worked out.
Below is what I tried:
package cadastro.caelum.com.br.testfragment;
import android.app.Activity;
import android.app.FragmentManager;
import android.content.Intent;
import android.os.PersistableBundle;
import android.provider.MediaStore;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
public class MainActivity extends ActionBarActivity {
private String parameter;
private RetainedFragment dataFragment;
private static final int CONFIGURATION_CHANGE = 1335;
private static final String EXTRA_KEY = "extrakey";
private static final String SHARED_KEY = "sharedkey";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// find the retained fragment on activity restarts
FragmentManager fm = getFragmentManager();
dataFragment = (RetainedFragment) fm.findFragmentByTag("data");
// create the fragment and data the first time
if (dataFragment == null) {
// add the fragment
dataFragment = new RetainedFragment();
fm.beginTransaction().add(dataFragment, "data").commit();
// load the initial value of the String
dataFragment.setData("My String");
}
// the data is available in dataFragment.getData()
// On button clicked, open the camera for testing cofiguration changes
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Try to save the typed value at parameter
EditText editText = (EditText) findViewById(R.id.edit);
parameter = editText.getText().toString();
// Open the camera
Intent openCamera = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
openCamera.putExtra(EXTRA_KEY, editText.getText().toString());
startActivityForResult(openCamera, MainActivity.CONFIGURATION_CHANGE);
}
});
}
@Override
public void onDestroy() {
super.onDestroy();
// store the data in the fragment
// saves the EditText's value into the fragment's data
EditText edit = (EditText)findViewById(R.id.edit);
dataFragment.setData(edit.getText().toString());
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == CONFIGURATION_CHANGE){
if(resultCode == Activity.RESULT_OK){
// Try to get the fragment String
String string = dataFragment.getData();
if(string == null){
Log.i("happens", "fragment string is null");
}else {
Log.i("happens", "fragment string = "+string);
}
// Try to get the extras String
Bundle extras = data.getExtras();
string = extras.getString(EXTRA_KEY);
if(string == null){
Log.i("happens", "extra string is null");
}else {
Log.i("happens", "extra string = "+string);
}
// Try to get the parameter String
string = parameter;
if(string == null){
Log.i("happens", "parameter string is null");
}else {
Log.i("happens", "parameter string = "+string);
}
}
}
}
@Override
public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {
super.onSaveInstanceState(outState, outPersistentState);
outState.putString("myName", "Felipe");
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
EditText edit = (EditText) findViewById(R.id.text);
String string = savedInstanceState.getString("myName");
if(string==null){
Log.i("happens", "bundle string is null");
}else {
edit.setText(string);
Log.i("happens", "bundle string = " +string);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
And the class RetainedFragment
:
package cadastro.caelum.com.br.testfragment;
import android.app.Fragment;
import android.os.Bundle;
/**
* Created by WindowsLipe on 05/08/2015.
*/
public class RetainedFragment extends Fragment {
// data object we want to retain
private String data;
// this method is only called once for this fragment
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// retain this fragment
setRetainInstance(true);
}
public void setData(String data) {
this.data = data;
}
public String getData() {
return data;
}
}
The logcat was the following
08-06 13:22:23.059 20736-20736/cadastro.caelum.com.br.testfragment I/happens﹕ bundle string is null
08-06 13:22:23.059 20736-20736/cadastro.caelum.com.br.testfragment I/happens﹕ fragment string is null
08-06 13:22:23.069 20736-20736/cadastro.caelum.com.br.testfragment I/happens﹕ extra string is null
08-06 13:22:23.069 20736-20736/cadastro.caelum.com.br.testfragment I/happens﹕ parameter string is null
What do you intend to do with
openCamera.putExtra(EXTRA_KEY, editText.getText().toString());
?– ramaral
@ramaral Pass the value of
EditText
to the camera because I think they will be returned automatically in the methodonActivityResult
ofMainActivity
within the parameterIntent data
.– Filipizaum
What will this Edittext have? It is the way to the photo?
– ramaral
@ramaral No, I just want to save the values of my attributes
MainActivity
why when the camera is opened, theActivity
is destroyed and loses all its attributes. I tried to follow the tutorial of the android site called Handling Runtime Changes but there is a class (DataFragment
) that they do not show the code and that it seems to be a subclass of the class they create (RetainedFragment
) because they do the attribute of the typeRetainedFragment
receive an instant from thisDataFragment
. Replaces then Data->Retained.– Filipizaum
There are many values you want to keep?
– ramaral
@ramaral Actually no, just a string.
– Filipizaum
I just noticed the attribute
parameter
remains intact if and only if the person takes the photo without ending in a different orientation from when started. So it seems that actually open the camera does not destroy theMainActivity
: she keeps spinning foreground. When the person finishes with the camera, goes back to the previous Activity and changes the orientation, and as the Activities are destroyed when they change orientation, the attribute is lost.– Filipizaum