簡體   English   中英

如何在按下“返回”按鈕之前保存字符串,並在返回活動時將其取回?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM