onRequestPermissionsResult không được gọi trong đoạn nếu được định nghĩa trong cả đoạn và hoạt động


167

Tôi có một đoạn trong đó tôi có recyclerview và thiết lập dữ liệu trong recyclerview này bằng cách sử dụng bộ chuyển đổi recyclerview.

Bây giờ, tôi có một nút trong mục danh sách của bộ điều hợp nhấp vào mà tôi cần kiểm tra quyền READ_EXTERNAL_STORAGE trong Android để biết mô hình cấp phép mới trong Android.

Tôi đã tạo một chức năng mới trong đoạn của bộ điều hợp này để kiểm tra xem có được phép hay không và yêu cầu cho phép nếu chưa được cấp.

Tôi đã thông qua MyFragment.this như một tham số trong bộ điều hợp và gọi phương thức của đoạn trên nút bấm trong bộ điều hợp.

Tôi đã sử dụng đoạn mã dưới đây để gọi requestPermission trong đoạn.

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

Tôi đã ghi đè onRequestPermissionsResultphương thức trong đoạn bằng cách sử dụng đoạn mã dưới đây:

@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 {}

Nhưng nó không được gọi, thay vì phương thức onRequestPermissionsResult của Activity này đang được gọi.

Tôi cũng đã định nghĩa phương thức onRequestPermissionsResult tương tự trong hoạt động chính của đoạn và nó cũng được gọi.

Tôi không thể xóa phương thức onRequestPermissionsResult của hoạt động nhưng muốn gọi phương thức onRequestPermissionsResult của phân đoạn khi tôi yêu cầu sự cho phép của phân đoạn. Tôi có thể làm cái này như thế nào? Tôi có làm điều gì sai ở đây không, xin hãy giúp tôi nếu có ai có ý tưởng ở đây.


1
tham khảo liên kết này cho phép thời gian chạy trong đoạn Đây là giải pháp chính xác
Antony jackson

Câu trả lời:


372

Chỉnh sửa câu trả lời để bao quát các vấn đề rộng lớn hơn

Tôi nghĩ rằng bạn đang nhầm lẫn phương pháp cho phân đoạn và hoạt động. Có một vấn đề tương tự dự án của tôi tháng trước. Vui lòng kiểm tra nếu cuối cùng bạn có những điều sau đây:

  1. Trong AppCompatActivity, sử dụng phương thức ActivityCompat.requestpermissions
  2. Trong đoạn hỗ trợ v4, bạn nên sử dụng requestpermissions
  3. Bắt là nếu bạn gọi AppcompatActivity.requestpermissions trong đoạn của bạn thì cuộc gọi lại sẽ đến hoạt động và không phải là đoạn
  4. Hãy chắc chắn để gọi super.onRequestPermissionsResulttừ các hoạt động onRequestPermissionsResult.

Xem nếu nó giúp.


9
Chỉ cần kiểm tra kỹ, đảm bảo bạn có super.onrequest allowresult trong hoạt động của mình
VarunJoshi129

27
Thêm super.onrequestpermissionresultvào hoạt động onrequest allowresult gọi cho onrequest allowresult khi tôi yêu cầu sự cho phép sử dụng requestpermissions. Điều này hiện đang hoạt động tốt, cảm ơn bạn rất nhiều .. :)
Prithniraj Nicyone 15/03/2016

1
Super.onrequest allowresult đã bị thiếu trong cuộc gọi lại hoạt động, dẫn đến cuộc gọi lại đoạn của tôi không được gọi
sakis kaliakoudas

4
requestPermissions () yêu cầu API cấp 23. Có giải pháp nào khác tương thích ngược với API cấp 21 không?
Adam Hurwitz

2
@ msc87 1. trong onRequestPermissionsResult của hoạt động và đoạn, dòng đầu tiên phải là: super.onRequestPermissionsResult (requestCode, allow, GrantResults); 2. trong đoạn mà bạn nhận ra quyền không được cấp chỉ cần gọi phương thức requestPermission như thế này: requestPermissions (Chuỗi mới [] {Manifest-01.CALL_PHONE}, MY_PERMISSIONS_REQUEST_CALL_PHONE);
KHU

122

Tôi đã yêu cầu sự cho phép vị trí từ một mảnh và trong đoạn đó, tôi cần thay đổi điều này:

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

đến đây:

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

sau đó onRequestPermissionsResult được gọi trong đoạn.


2
Hoạt động như một bùa mê :)
Antonio Vlasic

1
nó không làm việc với Kotlin bạn có thể xin vui lòng giúp đỡ tôi cho cùng đây được sử dụng này requestPermissions (bối cảnh như Hoạt động, permissionList.toTypedArray (), MY_PERMISSIONS_REQUEST)
Arbaz.in

Cảm ơn :), bạn tiết kiệm thời gian của tôi
Axrorxo'ja Yodgorov

19

Đây là một lỗi phổ biến mà mọi người mắc phải khi mã hóa cho marshmallow.

Khi ở AppCompatActivity, bạn nên sử dụng ActivityCompat.requestPermissions; Khi ở trong android.support.v4.app.Fragment, bạn chỉ nên sử dụng requestPermissions đơn giản (đây là một phương thức ví dụ của android.support.v4.app.Fragment) Nếu bạn gọi ActivityCompat.requestPermissions trong một đoạn, cuộc gọi lại onRequestPermissionsResult được gọi các hoạt động và không phải là các mảnh.

requestPermissions(permissions, PERMISSIONS_CODE);

Nếu bạn đang gọi mã này từ một đoạn thì nó có phương thức requestPermissions riêng.

Vì vậy, khái niệm cơ bản là, Nếu bạn đang ở trong một Hoạt động, hãy gọi

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

và nếu trong một mảnh, chỉ cần gọi

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

Để tham khảo, tôi đã nhận được câu trả lời từ liên kết này https://www.coderzheaven.com/2016/10/12/onrequestpermissionsresult-not-called-on-fragments/


6

Phương pháp requestPermissionstrên Fragment yêu cầu API cấp 23 trở lên.
Nếu ứng dụng của bạn nhắm mục tiêu phiên bản thấp hơn, bạn có thể sử dụng

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

Trước tiên, bạn cần thêm phụ thuộc hỗ trợ-v13:

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

FragmentCompat không được dùng nữa từ phiên bản 27.1.0
Raj kannan Iyyappan

6

thay đổi điều này :

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

đến đây:

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

Phiên bản thấp hơn được sử dụng trong một đoạn (onRequestPermissionsResult được gọi là phân đoạn), phiên bản ActivityCompat được sử dụng khi onRequestPermissionsResult được đặt trong Activity.
Roar 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();
 }
 }

thay đổi quyền


2
Xin chào người dùng2002721; mã của bạn có thể đúng, nhưng với một số ngữ cảnh, nó sẽ trả lời tốt hơn; ví dụ: bạn có thể giải thích cách thức và lý do thay đổi được đề xuất này sẽ giải quyết vấn đề của người hỏi, có lẽ bao gồm một liên kết đến tài liệu liên quan. Điều đó sẽ làm cho nó hữu ích hơn đối với họ và cũng hữu ích hơn đối với những người đọc trang web khác đang tìm giải pháp cho các vấn đề tương tự.
Vince Bowdren

Chương trình có thể loại bỏ một mảng ra khỏi giới hạn ngoại lệ nếu bạn thử và truy cập chỉ số 0 của GrantResults mà không kiểm tra độ dài trước. Nó đã xảy ra với chương trình của tôi. Tôi đã tách câu lệnh if cho GrantResults thành câu lệnh if bên trong để ngăn điều đó xảy ra và bây giờ nó hoạt động tốt.
Peter Griffin

1

Câu trả lời được chấp nhận này không hiệu quả với tôi, vì vậy tôi đã tìm ra giải pháp của riêng mình, giải thích bên dưới:

1.Đầu tiên tôi đã tạo ra một phương thức, trong đoạn:

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.Và sau đó gọi nó từ hoạt động cơ bản của nó:

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

Và nó đang hoạt động ...


0

Xác minh rằng cả PERMISSION_REQUEST_CODEtrong onRequestPermissionsResultvà bên trong của bạn Fragmentđều chứa cùng một giá trị.


0

Đối với tragetSDK 28, Kiểm tra SDK (> 23) và yêu cầu từ phân đoạn sẽ hoạt động. ActivityCompat.requestPermissions không thành công (nếu bạn đặt mã yêu cầu dưới 65536, hộp thoại cấp phép sẽ xuất hiện và nếu người dùng cho phép, các quyền được cung cấp, nhưng sẽ không có cuộc gọi lại nào xảy ra. Nhưng nếu bạn đặt trên 65536, ActivityCompat.requestPermissions sẽ thất bại ngay lập tức. Tôi không biết lý do đằng sau logic này. Có thể là một lỗi hoặc cố ý).

Mã làm việc:

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

bạn không cần phải kiểm tra phiên bản. trong các phiên bản dưới 23, nó sẽ trả về giá trị 'được cấp phép'. Lựa chọn của nhà phát triển tại đây: tránh khối 'nếu' để đơn giản hoặc tránh cuộc gọi yêu cầu khi không cần thiết
Psest328


0

Tôi gặp vấn đề tương tự. Đoạn của bạn có thể được khởi tạo từ bố trí hoạt động. Như thế

main_activty.xml

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

Vấn đề này đã được giải quyết cho tôi khi tôi sử dụng FragmentTransactionthay thế


0

trong các API dưới 23, bạn có thể tạo giao diện trong hoạt động sau đó triển khai nó trong đoạn con và khi bạn nhận được yêu cầu cấp phép, kết quả sẽ chuyển giao diện đó sang giao diện đã triển khai. Nó đơn giản thôi :)


0

bạn có thể gọi phương thức Fragment bên dưới

@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

Vấn đề này thực sự đã được gây ra bởi NestedFragments. Về cơ bản hầu hết các phân đoạn, chúng tôi đã mở rộng một HostedFragment, lần lượt mở rộng một CompatFragment. Việc các đoạn lồng nhau này gây ra các vấn đề mà cuối cùng đã được giải quyết bởi một nhà phát triển khác trong dự án.

Anh ấy đã làm một số thứ cấp thấp như chuyển bit để làm việc này vì vậy tôi không chắc lắm về giải pháp cuối cùng thực sự


3
Thay vì sao chép câu trả lời, bạn chỉ có thể cung cấp một liên kết - stackoverflow.com/a/33081173/630833
jayeffkay
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.