I have Activity
with EditText
and Button
. When the button is clicked, typed text is saved to an attribute of Activity
and the camera is opened with the startActivityForResult()
method.
When the user takes the photo and clicks save, the onActivityResult()
method is called but the attribute is null
.
I've been researching on and found that depending on some settings might prevent the Activity
from being destroyed, but it should only be used in the last instance. I followed the most recommended path and none of the techniques I read in Stackoverflow (except for of SharedPreferences
) worked fine.
Here's what I've 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 as follows
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