requestCode ผิดใน onActivityResult


310

ฉันเริ่มกิจกรรมใหม่จาก Fragment ของฉันด้วย

startActivityForResult(intent, 1);

และต้องการจัดการผลลัพธ์ในกิจกรรมหลักของ Fragment:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    Log.d(TAG, "onActivityResult, requestCode: " + requestCode + ", resultCode: " + resultCode);
    if (requestCode == 1) {
        // bla bla bla
    }
}

ปัญหาคือว่าฉันไม่เคยมีฉันได้โพสต์เพียงเพื่อrequestCodestartActivityForResult()

ผมได้รับสิ่งที่ต้องการ0x40001, 0x20001ฯลฯ กับชุดบิตที่สูงขึ้นแบบสุ่ม เอกสารไม่ได้พูดอะไรเกี่ยวกับเรื่องนี้ ความคิดใด ๆ


เป็นไปได้ที่ซ้ำกันของonActivityResult ที่ไม่ถูกเรียกใช้ใน
แฟรกเมนต์

คำตอบ:


837

คุณโทรจากคุณstartActivityForResult() Fragmentเมื่อคุณทำเช่นนี้requestCodeมีการเปลี่ยนแปลงโดยที่เป็นเจ้าของActivityFragment

ถ้าคุณต้องการให้ถูกต้องresultCodeในกิจกรรมของคุณลองสิ่งนี้:

เปลี่ยนแปลง:

startActivityForResult(intent, 1);

ถึง:

getActivity().startActivityForResult(intent, 1);

44
เพราะควรตัดสินใจว่าส่วนใดจะส่งผลลัพธ์ให้ ดังนั้นเมื่อ The Fragment เรียก StartActivityForResult RequestCode จะถูกเปลี่ยนแปลงโดยกิจกรรมดังนั้นมันจะรู้วิธีการส่งมอบผลลัพธ์ไปยังส่วนใด ถ้าคุณต้องการได้ผลลัพธ์ใน Activiy จริงๆ เพียงเรียกใช้ getActivity () startActivityForResult ()
Changwei Yao

31
เพียงข้อสังเกต: ถ้าคุณใช้startActivityForResultในส่วนและคาดหวังผลลัพธ์จากonActivityResultในส่วนนั้นเพียงให้แน่ใจว่าคุณโทรsuper.onActivityResultในกิจกรรมโฮสต์ (ในกรณีที่คุณแทนที่วิธีนั้นมี) เพราะนี่คือกิจกรรมที่ดูเหมือนว่าจะโทรของชิ้นส่วนonActivityResult onActivityResultนอกจากนี้โปรดทราบว่ารหัสคำขอเมื่อมีการเดินทางผ่านกิจกรรมonActivityResultนั้นมีการเปลี่ยนแปลงตามที่อธิบายในลิงก์ที่ Dimanoid โพสต์ในคำตอบของเขาด้านล่าง คุณอาจไม่จำเป็นต้องรู้สิ่งนี้ แต่คุณไม่มีทางรู้ว่า ...
Ferran Maylinch

31
"requestCode ถูกเปลี่ยนแปลงโดยกิจกรรมที่เป็นเจ้าของ Fragment" - ต้องรักการออกแบบ Android ...
Tiago

13
ข้อมูลสำคัญดังกล่าวที่คุณไม่สามารถหาได้อย่างชัดเจนในเอกสาร ต้องรักการออกแบบ Android ที่ออกแบบมาเพื่อทำให้ชีวิตของคุณเป็นนรก
Driss Bounouar

2
ผู้ชายฉันรักคุณฉันใช้เวลาหลายวันพยายามทำความเข้าใจปัญหานี้และแก้ไขข้อผิดพลาดขอบคุณ!
tinyCoder

35

รหัสขอไม่ผิด เมื่อใช้ v4 สนับสนุนไลบรารีแฟรกเมนต์ดัชนีส่วนจะถูกเข้ารหัสใน 16 บิตด้านบนของรหัสคำขอและรหัสคำขอของคุณอยู่ใน 16 บิตด้านล่าง ดัชนีส่วนย่อยจะถูกใช้ในภายหลังเพื่อค้นหาชิ้นส่วนที่ถูกต้องเพื่อส่งมอบผลลัพธ์

ดังนั้นสำหรับกิจกรรมที่เริ่มต้นจากชิ้นส่วนวัตถุแบบฟอร์มจัดการ onActivityResult RequestCode เช่นด้านล่าง:

originalRequestCode = changedRequestCode - (indexOfFragment << 16)
      6             =      196614        -       (3 << 16)

1
ข้อมูลที่ยอดเยี่ยมที่อธิบายสาเหตุที่แท้จริงของปัญหานี้
Muzikant

คำถามด่วน: indexOfFragment คืออะไร
Louis Tsai

indexOfFragment เป็นดัชนีที่ getSupportFragmentManager (). getFragments () สร้าง
HerberthObregon

25

ง่ายขึ้น:

ชวา : int unmaskedRequestCode = requestCode & 0x0000ffff

Kotlin : val unmaskedRequestCode = requestCode and 0x0000ffff

ตรวจสอบ 16 บิตต่ำกว่าเพียงเปิดโปงมันทำตรรกะและกับ 16 บิตบนเป็นศูนย์

protected void onActivityResult(int requestCode, int resultCode, Intent data) {

    final int unmaskedRequestCode = requestCode & 0x0000ffff

    if(unmaskedRequestCode == ORIGINAL_REQUEST_CODE){
      //Do stuff

    }
}

1
คุณช่วยบอกฉันทีว่าทำไมมันไม่ให้รหัสคำขอเดิม?
K.Sopheak

3
สาเหตุที่ requestCode นั้นเปลี่ยนไปโดยกิจกรรมที่เป็นเจ้าของ Fragment ดูคำตอบของ Ashlesha Sharma
Jaime Agudo

ขอบคุณนี่คือคำตอบที่ฉันกำลังมองหา ฉันไม่เห็นว่าทำไม Android ไม่ควรส่งคืนรหัสคำขอต้นฉบับ
tonisives

สิ่งนี้มีประโยชน์อย่างมากสำหรับฉันในวันนี้และอธิบายปัญหาได้ดีจริงๆ ขอบคุณ!
Billy Lazzaro

6

หากคุณให้บริการอย่างต่อเนื่องทำให้เป็นสาธารณะและใช้งานใน startActivityResult

ตัวอย่าง:

public static final int REQUEST_CODE =1;
getActivity().startActivityForresult(intent, REQUEST_CODE);

2

นอกจากนี้คุณยังสามารถกำหนด
super.onActivityResult(requestCode, resultCode, data)
ในActivity(ถ้าคุณแทนที่onActivityResult) ที่นี้

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    switch (requestCode) {

        ...

        default:
            super.onActivityResult(requestCode, resultCode, data);
    }
}

และโทรstartActivityForResult(intent, requestCode)ภายในของคุณFragment


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.