onRequestPermissionsResult ไม่ถูกเรียกใช้ในส่วนถ้ากำหนดไว้ในส่วนและกิจกรรม


167

ฉันมีแฟรกเมนต์ที่ฉันมี recyclerview และตั้งค่าข้อมูลใน recyclerview นี้โดยใช้อะแดปเตอร์ recyclerview

ตอนนี้ฉันมีปุ่มในรายการของอะแดปเตอร์คลิกที่ฉันต้องตรวจสอบสิทธิ์ READ_EXTERNAL_STORAG ​​E ใน Android สำหรับรูปแบบการอนุญาตใหม่ใน Android

ฉันได้สร้างฟังก์ชั่นใหม่ในส่วนของอะแดปเตอร์นี้เพื่อตรวจสอบว่าได้รับอนุญาตหรือไม่และขออนุญาตหากยังไม่ได้รับอนุญาต

ฉันได้ผ่าน MyFragment.this เป็นพารามิเตอร์ในอะแดปเตอร์และเรียกวิธีการส่วนของการคลิกปุ่มในอะแดปเตอร์

ฉันได้ใช้รหัสด้านล่างเพื่อโทรไปขอการอนุญาตเป็นส่วน ๆ

if(ContextCompat.checkSelfPermission(mContext, Manifest.permission.READ_EXTERNAL_STORAGE)
            != PackageManager.PERMISSION_GRANTED){
       requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
                ConstantVariables.READ_EXTERNAL_STORAGE);
    }

ฉันได้ลบล้างonRequestPermissionsResultวิธีการในส่วนโดยใช้รหัสด้านล่าง:

@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
    switch (requestCode) {
        case ConstantVariables.READ_EXTERNAL_STORAGE:
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                // permission was granted, proceed to the normal flow.
                startImageUploading();
            } else {}

แต่มันไม่ได้ถูกเรียกแทนเมธอด onRequestPermissionsResult ของกิจกรรมนี้กำลังถูกเรียก

ฉันได้กำหนดเมธอด onRequestPermissionsResult เดียวกันในกิจกรรมพาเรนต์ของแฟรกเมนต์ด้วยและจะถูกเรียกใช้

ฉันไม่สามารถลบเมธอด onRequestPermissionsResult ของกิจกรรม แต่ต้องการเรียกเมธอด onRequestPermissionsResult ของแฟรกเมนต์เมื่อฉันขอสิทธิ์จากแฟรกเมนต์ ฉันจะทำสิ่งนี้ได้อย่างไร ฉันกำลังทำอะไรผิดที่นี่โปรดช่วยฉันถ้าใครมีความคิดที่นี่


1
อ้างอิงลิงค์สิทธิ์การใช้งานในส่วนนี้เป็นทางออกที่แน่นอน
Antony jackson

คำตอบ:


373

แก้ไขคำตอบเพื่อให้ครอบคลุมปัญหาที่กว้างขึ้น

ฉันคิดว่าคุณสับสนวิธีการแยกส่วนและกิจกรรม มีปัญหาที่คล้ายกันในโครงการของฉันเมื่อเดือนที่แล้ว โปรดตรวจสอบว่าคุณมีดังต่อไปนี้:

  1. ใน AppCompatActivity ใช้เมธอดActivityCompat.requestpermissions
  2. ในส่วนสนับสนุน v4 คุณควรใช้requestpermissions
  3. Catch คือถ้าคุณโทรหา AppcompatActivity.requestpermissions ในแฟรกเมนต์ของคุณการโทรกลับจะมาที่กิจกรรมและไม่ใช่แฟรกเมนต์
  4. ให้แน่ใจว่าจะโทรจากกิจกรรมsuper.onRequestPermissionsResultonRequestPermissionsResult

ดูว่ามันช่วย


9
เพียงตรวจสอบอีกครั้งตรวจสอบให้แน่ใจว่าคุณได้รับคะแนนยอดเยี่ยมในกิจกรรมของคุณ
VarunJoshi129

27
เพิ่มsuper.onrequestpermissionresultในการเรียก onrequestpermissionresult กิจกรรม onrequestpermissionresult requestpermissionsส่วนเมื่อผมขออนุญาตใช้ มันใช้งานได้ดีในตอนนี้ขอบคุณมาก .. :)
Prithniraj Nicyone

1
super.onrequestpermissionresult หายไปจากการเรียกกลับกิจกรรมทำให้การโทรกลับส่วนของฉันไม่ได้รับการโทร
sakis kaliakoudas

4
requestPermissions ()ต้องการ API ระดับ 23 มีวิธีอื่นที่เข้ากันได้ย้อนหลังสำหรับ API ระดับ 21 หรือไม่
Adam Hurwitz

2
@ msc87 1. ใน onRequestPermissionsResult ของกิจกรรมและแฟรกเมนต์บรรทัดแรกควรเป็น: super.onRequestPermissionsResult (requestCode, การอนุญาต, grantResults); 2. ในแฟรกเมนต์ที่คุณรับรู้ถึงการอนุญาตที่ไม่ได้รับเพียงแค่เรียกเมธอดrequestPermission
AREF

122

ฉันขออนุญาตใช้ตำแหน่งจากแฟรกเมนต์และในแฟรกเมนต์ฉันต้องเปลี่ยนสิ่งนี้:

            ActivityCompat.requestPermissions(getActivity(), new String[]{
                Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, LOCATION_REQ_CODE);

สำหรับสิ่งนี้:

            requestPermissions(new String[]{
                Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, LOCATION_REQ_CODE);

ดังนั้นจึงเรียกว่า onRequestPermissionsResult ในแฟรกเมนต์


2
ทำงานเหมือนจับใจ :)
อันโตนิโอ Vlasic

1
มันใช้งานไม่ได้กับ kotlin คุณสามารถช่วยฉันได้ด้วยเหมือนกันที่นี่ใช้คำขอนี้การอนุญาต (บริบทเป็นกิจกรรม, permissionList.toTypedArray (), MY_PERMISSIONS_REQUEST)
Arbaz.in

ขอบคุณ :) คุณประหยัดเวลาของฉัน
Axrorxo'ja Yodgorov

19

นี่เป็นข้อผิดพลาดทั่วไปที่ผู้คนทำเมื่อเขียนโค้ดให้มาร์ชเมลโล่

เมื่ออยู่ใน AppCompatActivity คุณควรใช้ ActivityCompat.requestPermissions เมื่ออยู่ใน android.support.v4.app.Fragment คุณควรใช้ requestPermissions เพียงครั้งเดียว (นี่เป็นวิธีอินสแตนซ์ของ android.support.v4.app.Fragment) หากคุณเรียก ActivityCompat.requestPermissions ในการเรียกกลับแบบ onRequest กิจกรรมและไม่ใช่ชิ้นส่วน

requestPermissions(permissions, PERMISSIONS_CODE);

หากคุณกำลังเรียกรหัสนี้จากส่วนมันเป็นของตัวเอง requestPermissions วิธีการ

ดังนั้นแนวคิดพื้นฐานคือถ้าคุณอยู่ในกิจกรรมแล้วโทร

ActivityCompat.requestPermissions(this,
                            new String[]{Manifest.permission.CAMERA},
                            MY_PERMISSIONS_REQUEST_CAMERA);

และถ้าอยู่ใน Fragment เพียงแค่โทรหา

requestPermissions(new String[]{Manifest.permission.CAMERA},
                            MY_PERMISSIONS_REQUEST_CAMERA);

สำหรับการอ้างอิงฉันได้รับคำตอบจากลิงค์นี้https://www.coderzheaven.com/2016/10/12/onrequestpermissionsresult-not-called-on-fragments/


6

เมธอดrequestPermissionsบน Fragments ต้องการ API ระดับ 23 หรือสูงกว่า
หากแอปของคุณกำหนดเป้าหมายเวอร์ชันที่ต่ำกว่าคุณสามารถใช้

FragmentCompat.requestPermissions(this,
            new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
            ConstantVariables.READ_EXTERNAL_STORAGE);

ก่อนอื่นคุณต้องเพิ่มการพึ่งพา support-v13:

implementation "com.android.support:support-v13:$supportLibVersion"

FragmentCompat เลิกใช้แล้วจากรุ่น 27.1.0
Raj kannan Iyyappan

6

เปลี่ยนสิ่งนี้:

ActivityCompat.requestPermissions(
    activity,
    arrayOf(Manifest.permission.READ_CONTACTS),
    PERMISSIONS_REQUEST_READ_CONTACTS
)

สำหรับสิ่งนี้ :

requestPermissions(
     arrayOf(Manifest.permission.READ_CONTACTS),
     PERMISSIONS_REQUEST_READ_CONTACTS
)

ส่วนล่างสำหรับใช้ในแฟรกเมนต์ (onRequestPermissionsResult ถูกเรียกเป็นแฟรกเมนต์) เวอร์ชัน ActivityCompat ใช้สำหรับใช้เมื่อ onRequestPermissionsResult จัดอยู่ในกิจกรรม
คำรามGrønmo

1
private void showContacts() {
 if (getActivity().checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE)
         != PackageManager.PERMISSION_GRANTED) {
     requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
             PERMISSIONS_REQUEST_READ_STORAGE);
 } else {
     doShowContacts();
 }
}

 @Override
 public void onRequestPermissionsResult(int requestCode, String[] permissions,
     int[] grantResults) {
 if (requestCode == PERMISSIONS_REQUEST_READ_STORAGE
         && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
     doShowContacts();
 }
 }

เปลี่ยนการอนุญาต


2
สวัสดี user2002721; รหัสของคุณอาจถูกต้อง แต่ด้วยบริบทบางอย่างมันจะทำให้คำตอบที่ดีกว่า; ตัวอย่างเช่นคุณสามารถอธิบายได้ว่าทำไมการเปลี่ยนแปลงที่เสนอนี้จะแก้ไขปัญหาของผู้ถามได้อย่างไรรวมถึงลิงค์ไปยังเอกสารที่เกี่ยวข้อง สิ่งนี้จะทำให้มีประโยชน์มากขึ้นสำหรับพวกเขาและยังเป็นประโยชน์ต่อผู้อ่านไซต์อื่น ๆ ที่กำลังมองหาวิธีแก้ไขปัญหาที่คล้ายกัน
Vince Bowdren

โปรแกรมอาจส่งออกข้อยกเว้นขอบเขตมากมายถ้าคุณลองและเข้าถึงดัชนี 0 ของ grantResults โดยไม่ตรวจสอบความยาวก่อน มันเกิดขึ้นกับโปรแกรมของฉัน ฉันแยกคำสั่ง if สำหรับ grantResults เป็นคำสั่ง if ภายในเพื่อป้องกันไม่ให้เกิดขึ้นและทำงานได้ดีในขณะนี้
Peter Griffin

1

คำตอบที่ได้รับการยอมรับนี้ใช้ไม่ได้สำหรับฉันดังนั้นฉันจึงพบวิธีแก้ปัญหาของตัวเองอธิบายด้านล่าง:

1. ก่อนอื่นฉันสร้างวิธีในส่วน:

public static void MyOnRequestPermissionResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults){
        if (requestCode == 1 && grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            Log.d(TAG, "Permission: true");
        } else {
            Log.d(TAG, "permission: false");
        }
}

2. แล้วเรียกมันจากกิจกรรมพื้นฐาน:

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    if(requestCode ==1){
        SignupFragment.MyOnRequestPermissionResult(requestCode, permissions, grantResults);
    }
}

และมันกำลังทำงาน ...


0

ตรวจสอบว่าทั้งPERMISSION_REQUEST_CODEในonRequestPermissionsResultและภายในของคุณFragmentมีค่าเดียวกัน


0

สำหรับ tragetSDK 28 การตรวจสอบ SDK (> 23) และ requestpermissions จากแฟรกเมนต์จะทำงานได้ ActivityCompat.requestPermissions ล้มเหลว (หากคุณตั้งรหัสการร้องขอด้านล่าง 65536 กล่องโต้ตอบการอนุญาตจะปรากฏขึ้นและหากผู้ใช้อนุญาตการอนุญาตการอนุญาตจะได้รับ แต่จะไม่มีการเรียกกลับ แต่ถ้าคุณตั้งค่าที่สูงกว่า 65536, ActivityCompat.requestPermissions จะ ล้มเหลวทันทีฉันไม่ทราบเหตุผลเบื้องหลังตรรกะนี้อาจเป็นข้อผิดพลาดหรือเจตนา)

รหัสการทำงาน:

  if (Build.VERSION.SDK_INT >= 23) {
                        requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, LOCATION_ACCESS_REQUEST);
                    }

คุณไม่จำเป็นต้องทำการตรวจสอบเวอร์ชั่น ในรุ่นที่ต่ำกว่า 23 มันจะคืนค่า 'สิทธิ์ที่ได้รับ' ตัวเลือกของนักพัฒนาซอฟต์แวร์ที่นี่: หลีกเลี่ยงการบล็อก 'if' เพื่อความเรียบง่ายหรือหลีกเลี่ยงการร้องขอเมื่อไม่ต้องการ
Psest328

0

หากคุณกำลังทำงานกับ Kotlin คุณควรระบุอย่างชัดเจนว่าคุณกำลังเรียกวิธีการแยกส่วนไม่ใช่กิจกรรม

 fragment.requestPermissions(permissions, PERMISSIONS_CODE);

สิทธิ์ Android M: ไม่ได้เรียก onRequestPermissionsResult ()

ขอสิทธิ์รันไทม์จาก v4.Fragment และโทรกลับไปที่ Fragment หรือไม่


0

ฉันมีปัญหาเดียวกัน แฟรกเมนต์ของคุณสามารถเริ่มต้นได้จากโครงร่างกิจกรรม เช่นนั้น:

main_activty.xml

<fragment
    android:id="@+id/fragment"
    android:name="com.exampe.SomeFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

ปัญหานี้แก้ไขได้สำหรับฉันเมื่อฉันใช้FragmentTransactionแทน


0

ใน API ด้านล่าง 23 คุณสามารถสร้างอินเทอร์เฟซในกิจกรรมจากนั้นนำไปใช้ในส่วนย่อยของลูกและเมื่อคุณได้รับผลการร้องขอสิทธิ์ในกิจกรรมผ่านมันไปยังอินเทอร์เฟซที่นำมาใช้ในส่วน มันง่ายนี้ :)


0

คุณสามารถเรียกวิธีการแยกส่วนด้านล่าง

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    switch (requestCode) {
        case REQUEST_CODE:
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0 &&
                    grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // Permission is granted. Continue the action or workflow
                // in your app.
                doActionBecauseNowYouCanBro();
            } else {
                // Explain to the user that the feature is unavailable because
                // the features requires a permission that the user has denied.
                // At the same time, respect the user's decision. Don't link to
                // system settings in an effort to convince the user to change
                // their decision.
                showWhyRequestPermissionsAndDontBlockUserItsCalledManners();
            }
            return;
    }
    // Other 'case' lines to check for other
    // permissions this app might request.

}

-5

ปัญหานี้เกิดขึ้นจริงจาก NestedFragments โดยทั่วไปส่วนใหญ่เราได้ขยาย HostedFragment ซึ่งจะขยาย CompatFragment การมีชิ้นส่วนซ้อนกันเหล่านี้ทำให้เกิดปัญหาซึ่งในที่สุดก็ถูกแก้ไขโดยผู้พัฒนารายอื่นในโครงการ

เขากำลังทำสิ่งที่อยู่ในระดับต่ำเช่นการสลับบิตเพื่อให้ได้งานนี้ดังนั้นฉันจึงไม่แน่ใจเกี่ยวกับทางออกสุดท้ายจริง ๆ


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