![](/img/trans.png)
[英]Save state of Activity that contains Buttons when you press back button android
[英]How to save a string before a Back button press, and retrieve it when you go back to the activity?
我正在開發一個用於比較兩張照片的應用程序。 在主屏幕上,有兩個按鈕,一個按鈕可引導您進行活動以從“照片”中選擇一張照片,另一個按鈕對第二張照片執行相同的操作。
問題是,當用戶選擇第一張照片並按“返回”按鈕返回主屏幕進入第二張照片時,第一張照片被刪除。
我首先嘗試將uri轉換為字符串並將其存儲在SharePreference中,但是然后出現一個錯誤,因為我沒有Manifest.permission.MANAGE_DOCUMENT,這從未像我這樣授予第三方應用程序。
因此,我希望使用onSaveInstanceState()將字符串保存在saveInstanceState Bundle對象中,以便在onCreate()中進行檢索。 但是我了解到,按下后退按鈕時,永遠不會執行onSaveInstanceState()。
所以我嘗試手動調用它:
@Override
public void onBackPressed(){
Bundle bundle=new Bundle();
bundle.putString("photoUri",stringUri);
onSaveInstanceState(bundle);
super.onBackPressed();
}
@Override
public void onSaveInstanceState(Bundle outState){
super.onSaveInstanceState(outState);
}
但是現在,問題在於后退按鈕不再起作用。
編輯:這是我的整個Java代碼:
public class Photo1 extends AppCompatActivity implements View.OnClickListener{
Button btnPhoto1Picker;//The button that you click to open select photo menu
private int PICK_IMAGE_REQUEST = 1;
SharedPreferences pref;//for permanent storage
SharedPreferences.Editor editor;//for tapping into permanent storage
ImageView imageView;//for displaying selected photo
@Override
/**
* @throws NullPointerException For the very time and the only time after the try statement is written, there is nothing in "encoded" variable
* so it is null. If there is no catch statement, the app will crash.
*/
protected void onCreate(Bundle savedInstanceState){
//Initializing permanent storage and its editor
pref=getApplicationContext().getSharedPreferences("MyPref",MODE_PRIVATE);
editor=pref.edit();
super.onCreate(savedInstanceState);
setContentView(R.layout.photo1);
//setting up displaying image view and the select button
imageView = (ImageView) findViewById(R.id.displayPhoto1View);
btnPhoto1Picker=(Button) findViewById(R.id.pickPhoto1Button);
btnPhoto1Picker.setOnClickListener(this);
try {
String stringUri = pref.getString("photo1String", null);
Uri uri=Uri.parse(stringUri);
setImageView(uri);
} catch (IOException e) {
}
}
/**
* This method is triggered when the select image button is clicked. It sends a request for a select photo window to be opened.
* @param v the button view
*/
@Override
public void onClick(View v){
Intent intent = new Intent();
// Show only images, no videos or anything else
intent.setType("image/*");//indicate an explicit MIME data type to return
intent.setAction(Intent.ACTION_GET_CONTENT);//set general action to perform
// Always show the chooser (if there are multiple options available)
startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE_REQUEST);
}
/**
*When an activity you launched exits, giving you the requestCode you started it with.
* @param requestCode PICK_IMAGE-REQUEST, the integer request code originally supplied to startActivityForResult(),
* used to identify who the result come from
* @param resultCode an integer return by child activity through
* @param data The data use to get the photo selected.
*/
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK && data != null && data.getData() != null) {
Uri uri = data.getData();
String stringUri=uri.toString();
editor.putString("photo1String",stringUri).apply();
try {
setImageView(uri);
} catch (IOException e) {
e.printStackTrace();
}
}
}//onActivity ends
private void setImageView(Uri uri) throws IOException{
Bitmap bitmap1= MediaStore.Images.Media.getBitmap(getContentResolver(), uri);//this is the photo selected
// Log.d(TAG, String.valueOf(bitmap));
imageView.setImageBitmap(bitmap1);
}
}
這是錯誤消息:
06-21 10:13:14.274 21113-21113/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.android.sidebyside, PID: 21113
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.android.sidebyside/com.example.android.sidebyside.Photo1}: java.lang.SecurityException: Permission Denial: opening provider com.android.providers.media.MediaDocumentsProvider from ProcessRecord{6297a23 21113:com.example.android.sidebyside/u0a170} (pid=21113, uid=10170) requires android.permission.MANAGE_DOCUMENTS or android.permission.MANAGE_DOCUMENTS
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2678)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2743)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1490)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6165)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:888)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:778)
Caused by: java.lang.SecurityException: Permission Denial: opening provider com.android.providers.media.MediaDocumentsProvider from ProcessRecord{6297a23 21113:com.example.android.sidebyside/u0a170} (pid=21113, uid=10170) requires android.permission.MANAGE_DOCUMENTS or android.permission.MANAGE_DOCUMENTS
at android.os.Parcel.readException(Parcel.java:1684)
at android.os.Parcel.readException(Parcel.java:1637)
at android.app.ActivityManagerProxy.getContentProvider(ActivityManagerNative.java:4279)
at android.app.ActivityThread.acquireProvider(ActivityThread.java:5517)
at android.app.ContextImpl$ApplicationContentResolver.acquireUnstableProvider(ContextImpl.java:2239)
at android.content.ContentResolver.acquireUnstableProvider(ContentResolver.java:1517)
at android.content.ContentResolver.openTypedAssetFileDescriptor(ContentResolver.java:1131)
at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:984)
at android.content.ContentResolver.openInputStream(ContentResolver.java:704)
at android.provider.MediaStore$Images$Media.getBitmap(MediaStore.java:872)
at com.example.android.sidebyside.Photo1.setImageView(Photo1.java:100)
at com.example.android.sidebyside.Photo1.onCreate(Photo1.java:56)
at android.app.Activity.performCreate(Activity.java:6687)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1140)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2631)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2743)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1490)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6165)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:888)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:778)
如果在寫入SharedPreference時遇到該錯誤,則說明您確實做錯了。 您不需要任何權限即可寫入共享首選項。
您永遠不要手動調用onSaveInstanceState。 這是一個生命周期函數,將在適當的時候由框架調用。 手動調用將無法完成您希望執行的操作。 返回共享首選項。
在大多數情況下,硬件onBackPressed
將觸發finish()
,這意味着將基於launchMode
重新創建launchMode
。 另外請檢查android開發人員docs中的onSaveInstanceState。它明確指出:
onSaveInstanceState() is not called when the user explicitly closes the activity or in other cases when finish()is called.
您應該考慮將其存儲在不會丟失數據的地方。一種可能的解決方案是在Application
類中具有一個屬性並相應地使用它。
使用SharedPreference不需要任何許可,是存儲小型集合的絕佳選擇。您可以按以下方式存儲數據
SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit();
editor.putString("Photo_Uri", stringUri);
editor.commit();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.