Uprawnienia systemu Android M: nie wywoływano onRequestPermissionsResult ()

291

Aktualizuję naszą aplikację, aby korzystać z nowego systemu uprawnień do uruchamiania M. Wszystko działa oprócz onRequestPermissionsResult (). Muszę sprawdzić uprawnienia po naciśnięciu przycisku, a jeśli się powiedzie, wyślij wiadomość tekstową. Po udzieleniu pozwolenia okno to zamyka się, ale nie uruchamia wysyłania tekstu, dopóki ponownie nie naciśnie przycisku.

Debugowałem i ustawiłem punkty przerwania w metodzie onRequestPermissionsResult (), ale nigdy do niej nie wchodzi.

Ta metoda jest wywoływana jako pierwsza:

    private void askForPermission() {
    String[] permissions = new String[]{Manifest.permission.SEND_SMS};
    ActivityCompat.requestPermissions(getActivity(), permissions, PERMISSIONS_CODE);
}

A potem mój telefon zwrotny wygląda następująco:

    @Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);

    if (requestCode == PERMISSIONS_CODE) {
        for (int i = 0; i < permissions.length; i++) {
            String permission = permissions[i];
            int grantResult = grantResults[i];

            if (permission.equals(Manifest.permission.SEND_SMS)) {
                if (grantResult == PackageManager.PERMISSION_GRANTED) {
                    onPPSButtonPress();
                } else {
                    requestPermissions(new String[]{Manifest.permission.SEND_SMS}, PERMISSIONS_CODE);
                }
            }
        }
    }
}

Czy ktoś napotkał podobny problem? Doceń wszelką pomoc w tym zakresie. Dzięki

AndyOHart
źródło

Odpowiedzi:

576

Natrafiłem na ten sam problem i właśnie znalazłem rozwiązanie. Korzystając z biblioteki pomocy technicznej, musisz użyć poprawnych wywołań metod. Na przykład:

  • Będąc w AppCompatActivity , powinieneś użyć ActivityCompat.requestPermissions ;
  • Będąc w android.support.v4.app.Fragment , powinieneś użyć po prostu requestPermissions (jest to metoda instancji android.support.v4.app.Fragment)

Jeśli wywołasz ActivityCompat.requestPermissions we fragmencie, wywołanie zwrotne onRequestPermissionsResult jest wywoływane dla działania, a nie fragmentu.

Mam nadzieję że to pomoże!

yavor87
źródło
13
Występuje również w przypadku działań noHistory: code.google.com/p/android-developer-preview/issues/…
Anthony Bobenrieth
11
„W Android.support.v4.app.Fragment powinieneś użyć po prostu requestPermissions” - dziękuję!
Tigran Sarkisian
5
@AnthonyBobenrieth, więc jakie jest tutaj rozwiązanie dla działań noHistory? Po prostu nie możemy prosić o uprawnienia?
Dean Wild
2
Link jest uszkodzony @AnthonyBobenrieth. Czy jest jakieś rozwiązanie dla braku historii?
fersarr
3
Podczas używania Fragment.requestPermissions()działanie nadrzędne faktycznie otrzymuje onRequestPermissionsResult(). (To jest z biblioteką wsparcia 23.3.0)
Ktoś gdzieś
101

Możesz spróbować:

requestPermissions(permissions, PERMISSIONS_CODE);

Jeśli wywołujesz ten kod z fragmentu, ma on własną metodę requestPermissions. Uważam, że problem polega na tym, że wywołujesz metodę statyczną.

Pro Wskazówka, jeśli chcesz onRequestPermissionsResult()fragmentu: FragmentCompat.requestPermissions(Fragment fragment, String[] permissions, int requestCode)

Tieru
źródło
Dzięki za pomoc. Zauważyłem, że istnieje metoda requestPermissions, jeśli znajduje się we fragmencie. Jestem fragmentem i próbowałem wywołać tylko requestPermissions, niestety to nie zadziałało. Próbowałem też tego, o czym wspomniałeś, i to też nie działało.
AndyOHart
To zadziałało dla mnie w Androidzie M. Ale zastanawiam się, czy spowodowałoby to jakieś problemy na urządzeniach Pre-M?
Bala Vishnu
4
@goodgamerguy upewnij się, że nie używasz kodu żądania w onRequestPermissionsResult działania. jeśli twoja aktywność korzysta również z wywołania zwrotnego onRequestPermissionsResult, powinieneś podać wartość domyślną: super.onRequestPermissionsResult (requestCode, uprawnienia, grantResults);
Timmy Simons,
68

Mam nadzieję, że działa dobrze

Do działania:

 ActivityCompat.requestPermissions(this,permissionsList,REQUEST_CODE);

Dla fragmentu:

 requestPermissions(permissionsList,REQUEST_CODE);
Sanjay Mangaroliya
źródło
Co z SDK 15 i niższymi wersjami?
zulkarnain shah
4
Nie potrzebujesz pozwolenia na SDK 15, potrzebujesz tylko Marshmallow i nowszych wersji ..
Sanjay Mangaroliya
50

Też napotkałem ten problem. Jeśli chcesz, aby działanie, które obsługuje uprawnienia, którego nie ma w historii / ostatnich, będzie Cię kusiło, aby zmienić AndroidManifest.xmlwpis.

Jeśli ustawisz aktywność, do której dzwonisz requestPermissionslub za AppCompatActivity.requestPermissionspomocą

android:noHistory="true"
android:excludeFromRecents="true"

w waszych AndroidManifest.xmlczasach onRequestPermissionsResult()nie będziecie wezwani. Dzieje się tak, jeśli twoja działalność pochodzi z Activitylub AppCompatActivity.

Można to naprawić, usuwając obie flagi z „AndroidManifest.xml” i finishAndRemoveTask()zamiast tego kończąc swoją aktywność .

Simon Featherstone
źródło
Wolałbym nie usuwać atrybutu noHistory, ale to rozwiązanie działało dla mnie. Dzięki!
Eric Schlenz
1
Miałem problem na Marshmallow, ale nie na Nougat, dziękuję, że zadziałał dla mnie
Yohan Dahmani
37

Jeśli masz onRequestPermissionsResultzarówno aktywność, jak i fragment, pamiętaj, aby wywołać super.onRequestPermissionsResultaktywność. Nie jest wymagany fragmentem, ale jest aktywny.

Dusan Zivkovic
źródło
Zauważ też, że jeśli celujesz w API (na przykład 19), nadal będziesz w starym systemie modeli uprawnień, a zatem nie będziesz otrzymywać wywołań funkcji związanych z uprawnieniami
Bonatti
zobacz moją odpowiedź, jeśli rozszerzyłeś inne działanie, które nie wywołuje super
TouchBoarder
3
Natknąłem się na to. FragmentActivity.onRequestPermissionsResult(..)jest to miejsce, do którego onRequestPermissionsResult(..)przekazywane jest wezwanie do fragmentu .
JanPl
@Bonatti Więc jeśli spróbuję poprosić o pozwolenie w Androidzie 4.4.2, nie dostanę rezultatu? Dlatego nie mogę zmienić uprawnień, tylko je zobaczyć?
Alex Fragotsis
@AlexanderFragotsis Otrzymasz wynik. Jedyną różnicą jest to, że nie zostaniesz poproszony o zgodę, zamiast tego zostaniesz automatycznie przyznany przez system.
Dusan Zivkovic
33

Nieaktualne odpowiedzi znajdują się na stronie : https://developer.android.com/training/permissions/requesting

Wewnątrz fragmentu musisz wywołać:

FragmentCompat.requestPermissions(permissionsList, RequestCode)

Nie:

ActivityCompat.requestPermissions(Activity, permissionsList, RequestCode);
Ben.Slama.Jihed
źródło
2
Odnosi się do android.support.v13.app.FragmentCompat
Udi Oshi,
1
FragmentCompat jest przestarzałe od API 27.1.0.
Big McLargeHuge
moja odpowiedź jest nieaktualna, proszę odnieść się do: developer.android.com/training/permissions/requesting
Ben.Slama.Jihed
15

Jeśli używasz requestPermissions we fragmentach, akceptuje 2 parametry zamiast 3.

Powinieneś użyć requestPermissions(permissions, PERMISSIONS_CODE);

AkKi
źródło
1
W rzeczywistości daje odpowiedź na pytanie. Wywołanie metody requestPermissions (instancja metody fragmentu) zamiast ActivityCompat.requestPermissions, uruchamiana jest metoda wynikowa. Co jest tutaj głównym problemem. Dziękuję Don
Waclock,
15

Jeśli z jakiegoś powodu rozszerzyłeś niestandardowe działanie znajdujące się w bibliotece zewnętrznej, która nie wywołuje super, będziesz musiał ręcznie wywołać Fragment super.onRequestPermissionsResult sam w swoim działaniu onRequestPermissionsResult.

YourActivity extends SomeActivityNotCallingSuperOnRequestPermissionsResult{
Fragment requestingFragment;//the fragment requesting the permission
...
@Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if(requestingFragment!=null)
            requestingFragment.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }
...
TouchBoarder
źródło
12

Masz funkcję checkPermissions dla urządzeń przed Marshmallow w FragmentCompat . Używam w ten sposób:

FragmentCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                    MY_PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);
Marta Rodriguez
źródło
2
Działa to tylko wtedy, gdy w android.app.fragment pojawi się prośba o pozwolenie i musisz zaimportować bibliotekę support-v13!
MohammadReza
4
FragmentCompat.requestPermissions () nie działa z android.support.v4.app.Fragment. Każdy wie, jak sobie z tym poradzić.
Jutikorn
12

Odkryłem, że ważne jest, gdzie dzwonisz android.support.v4.app.Fragment.requestPermissions.

Jeśli to zrobisz onCreate(), onRequestPermissionsResult()nigdy nie zostanie wywołane.

Rozwiązanie: Zadzwoń onActivityCreated();

@Override
public void onActivityCreated(Bundle savedInstanceState) {

    super.onActivityCreated(savedInstanceState);

    if (ContextCompat.checkSelfPermission(context, Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_DENIED) 
        requestPermissions(new String[]{Manifest.permission.READ_CONTACTS}, 0);

}
Almisoft
źródło
1
Mam ten sam problem, ale nie mogę dostać się onActivityCreated()do mojego kodu. SDK 23.
kAmol
Nie jestem fragmentem, staram się to zrobić w dniu Utwórz działanie
kAmol
Hmm, czy użyć onPause()?
almisoft
10

Ten problem był spowodowany przez NestedFragments. Zasadniczo większość fragmentów rozszerzyliśmy HostedFragment, który z kolei rozszerza CompatFragment. Posiadanie tych zagnieżdżonych fragmentów spowodowało problemy, które ostatecznie zostały rozwiązane przez innego programistę w projekcie.

Robił pewne rzeczy na niskim poziomie, takie jak przełączanie bitów, aby to zadziałało, więc nie jestem zbyt pewien ostatecznego rozwiązania

AndyOHart
źródło
Pomogło mi to rozwiązać problem: musiałem przekierować onRequestPermissionsResult z fragmentu nadrzędnego do fragmentu podrzędnego (zagnieżdżonego). Dzięki za wskazówkę!
Murphy
9
 /* use the object of your fragment to call the 
 * onRequestPermissionsResult in fragment after
 * in activity and use different request Code for 
 * both Activity and Fragment */

   if (isFragment)
    mFragment.requestPermissions(permissions.toArray(new
    String[permissions.size()]),requestPermission);

   else
    ActivityCompat.requestPermissions(mActivity,permissions.toArray(new
    String[permissions.size()]),requestPermission);
Shahab Rauf
źródło
6

To zadziała ...

@Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }
Sumit khare
źródło
super implementacja nazywa implementację fragmentów, a nie ramy
Mohammad Yahia
5

Jeśli wywołujesz ten kod z fragmentu, ma on własną metodę requestPermissions.

Podstawowa koncepcja brzmi: jeśli jesteś w działaniu, zadzwoń

ActivityCompat.requestPermissions(this,
                            permissionsList,
                            permissionscode);

a jeśli we fragmencie, po prostu zadzwoń

requestPermissions(permissionsList,
                            permissionscode);
PounKumar Purushothaman
źródło
1
Wymaga interfejsu API na poziomie 23 ... we wcześniejszych wersjach FragmentCompat.requestPermissions().
Minas Mina,
5

Miałem podobny problem, z wyjątkiem tego, że naciskałem przycisk, aby nawiązać połączenie, co wyzwala interwał połączenia. Najpierw sprawdziłem uprawnienia, jeśli nie otrzymałem, proszę o pozwolenie, a onRequestPermissionResult wywołuję uprawnienie do sprawdzania i ponownie dzwonię.

 @Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
    switch (requestCode) {
        case Constants.PERMISSIONS_REQUEST_CALL_PHONE: {
            if ( grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                checkPermissionsAndCall();
            }
        }
    }
}

public void checkPermissionsAndCall(){
    if (Build.VERSION.SDK_INT > 22) {
        if(ContextCompat.checkSelfPermission(getContext(),
                Manifest.permission.CALL_PHONE)
                != PackageManager.PERMISSION_GRANTED){
            requestPermissions( new String[]{Manifest.permission.CALL_PHONE}, Constants.PERMISSIONS_REQUEST_CALL_PHONE);
        }
        else{
            callIntent();
        }
    }
}
Ndheti
źródło
3

Na podstawie odpowiedzi goodgamerguy rozwiązanie jest następujące:

myFragment.this.requestPermissions(....)
Havabon
źródło
2

Zanim sprawdzisz wszystko zgodnie z powyższymi odpowiedziami, upewnij się, że kod żądania nie jest równy 0 !!!

sprawdź kod onRequestPermissionsResult () w FragmentActivity.java:

public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
        @NonNull int[] grantResults) {
    int index = (requestCode>>16)&0xffff;
    if (index != 0) {
        index--;

        String who = mPendingFragmentActivityResults.get(index);
        mPendingFragmentActivityResults.remove(index);
        if (who == null) {
            Log.w(TAG, "Activity result delivered for unknown Fragment.");
            return;
        }
        Fragment frag = mFragments.findFragmentByWho(who);
        if (frag == null) {
            Log.w(TAG, "Activity result no fragment exists for who: " + who);
        } else {
            frag.onRequestPermissionsResult(requestCode&0xffff, permissions, grantResults);
        }
    }
}
Kupiec
źródło
2
private void showContacts() {
    if (getActivity().checkSelfPermission(Manifest.permission.READ_CONTACTS)
        != PackageManager.PERMISSION_GRANTED) {
        requestPermissions(new String[]{Manifest.permission.READ_CONTACTS}, PERMISSIONS_REQUEST_READ_CONTACTS);
    } else {
        doShowContacts();
    }
}

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    if (requestCode == PERMISSIONS_REQUEST_READ_CONTACTS && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
        doShowContacts();
    }
}
użytkownik2002721
źródło
2

Mam niesamowite rozwiązanie, aby to osiągnąć, wykonaj BaseActivity w ten sposób.

public class BaseActivity extends AppCompatActivity {

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // Thread.setDefaultUncaughtExceptionHandler(new MyExceptionHandler(this));


}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) {
    switch (requestCode) {
        case 1: {
            if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                CustomToast.getInstance().setCustomToast("Now you can share the Hack.");

            } else {
                Toast.makeText(this, "Permission denied to read your External storage", Toast.LENGTH_SHORT).show();
            }
        }
    }
}

}

Teraz możesz zadzwonić na kod, aby poprosić o pozwolenie w ten sposób

 ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);

Teraz za każdym razem, gdy dzieje się to gdziekolwiek, czy to w twoim fragmencie, czy w jakiejkolwiek aktywności, wywoływana jest aktywność podstawowa.

Dzięki

Abhishek Dubey
źródło
1

Możesz użyć requestPermissions(PERMISSIONS, MULTIPLE_PERMISSIONS_CODE);. Nie używaj FragmentCompat, jeśli używasz v4.

Remario
źródło
Proszę wyjaśnić dlaczego.
Placeable
1

Detale

  • Kotlin 1.2.70
  • sprawdzone w minSdkVersion 19
  • Android studio 3.1.4

Algorytm

moduł - kamera, lokalizacja, ....

  1. Sprawdź, czy hasSystemFeature (jeśli moduł istnieje w telefonie)
  2. Sprawdź, czy użytkownik ma dostęp do modułu
  3. Wyślij żądanie uprawnień (poproś użytkownika o zezwolenie na użycie modułu )

funkcje

  1. Praca z działaniami i fragmentami
  2. Ma tylko jedną odpowiedź wyniku
  3. Może sprawdzić kilka modułów w jednym żądaniu

Rozwiązanie

class PermissionType(val manifest_permission: String, val packageManager: String) {
    object Defined {
        val camera = PermissionType(Manifest.permission.CAMERA, PackageManager.FEATURE_CAMERA)
        val currentLocation = PermissionType(Manifest.permission.ACCESS_FINE_LOCATION, PackageManager.FEATURE_LOCATION_GPS)
    }
}

class  Permission {

    enum class PermissionResult {
        ACCESS_ALLOWED, ACCESS_DENIED, NO_SYSTEM_FEATURE;
    }

    interface ManagerDelegate {
        fun permissionManagerDelegate(result: Array<Pair<String, PermissionResult>>)
    }

    class Manager internal constructor(private val delegate: ManagerDelegate?) {

        private var context: Context? = null
        private var fragment: Fragment? = null
        private var activity: AppCompatActivity? = null
        private var permissionTypes: Array<PermissionType> = arrayOf()
        private val REQUEST_CODE = 999
        private val semaphore = Semaphore(1, true)
        private var result: Array<Pair<String, PermissionResult>> = arrayOf()


        constructor(permissionType: PermissionType, delegate: ManagerDelegate?): this(delegate) {
            permissionTypes = arrayOf(permissionType)
        }

        constructor(permissionTypes: Array<PermissionType>, delegate: ManagerDelegate?): this(delegate) {
            this.permissionTypes = permissionTypes
        }

        init {
            when (delegate) {
                is Fragment -> {
                    this.fragment = delegate
                    this.context = delegate.context
                }

                is AppCompatActivity -> {
                    this.activity = delegate
                    this.context = delegate
                }
            }
        }

        private fun hasSystemFeature(permissionType: PermissionType) : Boolean {
            return context?.packageManager?.hasSystemFeature(permissionType.packageManager) ?: false
        }

        private fun hasAccess(permissionType: PermissionType) : Boolean {
            return if (Build.VERSION.SDK_INT < 23) true else {
                context?.checkSelfPermission(permissionType.manifest_permission) == PackageManager.PERMISSION_GRANTED
            }
        }

        private fun sendRequest(permissionTypes: Array<String>) {

            if (fragment != null) {
                fragment?.requestPermissions(permissionTypes, REQUEST_CODE)
                return
            }

            if (activity != null){
                ActivityCompat.requestPermissions(activity!!, permissionTypes, REQUEST_CODE)
            }
        }

        fun check() {

            semaphore.acquire()
            AsyncTask.execute {
                var permissionsForSendingRequest: Array<String> = arrayOf()
                this.result = arrayOf()

                for (it in permissionTypes) {
                    if (!hasSystemFeature(it)) {
                        result += Pair(it.manifest_permission, PermissionResult.NO_SYSTEM_FEATURE)
                        continue
                    }

                    if (hasAccess(it)) {
                        result += Pair(it.manifest_permission, PermissionResult.ACCESS_ALLOWED)
                    } else {
                        permissionsForSendingRequest += it.manifest_permission
                    }
                }

                if (permissionsForSendingRequest.isNotEmpty()) {
                    sendRequest(permissionsForSendingRequest)
                } else {
                    delegate?.permissionManagerDelegate(result)
                }
            }
        }

        fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
            when (requestCode) {
                REQUEST_CODE -> {
                    if (grantResults.isEmpty()) {
                        return
                    }
                    for ((i,permission) in permissions.withIndex()) {
                        for (item in this.permissionTypes) {
                            if (permission == item.manifest_permission && i < grantResults.size) {
                                result += if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
                                    Pair(item.manifest_permission, PermissionResult.ACCESS_ALLOWED)
                                } else {
                                    Pair(item.manifest_permission, PermissionResult.ACCESS_DENIED)
                                }
                                break
                            }
                        }
                    }
                    delegate?.permissionManagerDelegate(result)
                }
            }
            semaphore.release()
        }
    }
}

Wykorzystanie w działaniu (w tym samym fragmencie)

class BaseActivity : AppCompatActivity(), Permission.ManagerDelegate {

    private lateinit var permissionManager: Permission.Manager

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.base_activity)

        permissionManager = Permission.Manager(arrayOf(PermissionType.Defined.camera, PermissionType.Defined.currentLocation), this)
        permissionManager.check()
    }

    override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        permissionManager.onRequestPermissionsResult(requestCode, permissions, grantResults)
    }


    override fun permissionManagerDelegate(result: Array<Pair<String, Permission.PermissionResult>>) {
        result.forEach {
            println("!!! ${it.first} ${it.second}")
//            when (it.second) {
//                Permission.PermissionResult.NO_SYSTEM_FEATURE -> {
//                }
//
//                Permission.PermissionResult.ACCESS_DENIED  -> {
//                }
//
//                Permission.PermissionResult.ACCESS_ALLOWED -> {
//                }
//            }
        }
    }
}
Wasilij Bodnarchuk
źródło
1

Tutaj chcę pokazać mój kod, jak to zrobiłem.

public class CheckPermission {

public Context context;

public static final int PERMISSION_REQUEST_CODE =  200;

public CheckPermission(Context context){
    this.context = context;
}

public boolean isPermissionGranted(){
    int read_contact = ContextCompat.checkSelfPermission(context.getApplicationContext() , READ_CONTACTS);
    int phone = ContextCompat.checkSelfPermission(context.getApplicationContext() , CALL_PHONE);

    return read_contact == PackageManager.PERMISSION_GRANTED && phone == PackageManager.PERMISSION_GRANTED;
   }
}

Tutaj w tej klasie chcę sprawdzić, czy zezwolenie zostało udzielone czy nie. Czy nie zadzwonię po pozwolenie z mojej MainActivity jak

public void requestForPermission() {
       ActivityCompat.requestPermissions(MainActivity.this, new String[]    {READ_CONTACTS, CALL_PHONE}, PERMISSION_REQUEST_CODE);
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    switch (requestCode) {
        case PERMISSION_REQUEST_CODE:
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                if (shouldShowRequestPermissionRationale(ACCESS_FINE_LOCATION)) {
                    showMessageOKCancel("You need to allow access to both the permissions",
                            new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) {
                                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                                        requestPermissions(new String[]{Manifest.permission.READ_CONTACTS, Manifest.permission.CALL_PHONE},
                                                PERMISSION_REQUEST_CODE);
                                    }
                                }
                            });
                    return;
                }
            }
    }
}

Teraz w metodzie onCreate musisz wywołać funkcję requestForPermission ().

To wszystko. Możesz także poprosić o wiele uprawnień jednocześnie.

pavel
źródło
1

AKTUALIZACJA: zobaczyłem czyjąś odpowiedź na temat wywołania super.onRequestPermissionResult()w działaniu i to naprawia problem z kodem żądania, o którym wspomniałem i wywołuje onRequestPermissionResult fragmentu.

zignoruj ​​te rzeczy:

Dla mnie to wywoływało onRequestPermissionResultdziałanie pomimo mojego wywołania fragment.requestPermission(...), ALE zwróciło wynik z niepoprawnym kodem żądania (111 zmieniło się w 65647 dlaczego ??? Nigdy się nie dowiem).

Na szczęście jest to jedyne zezwolenie, którego żądamy na tym ekranie, więc po prostu zignoruję kod żądania (nie mam czasu, aby dowiedzieć się, dlaczego jest on teraz nieprawidłowy)

grgrssll
źródło
Dodaj 65536 i 111, a dostaniesz. Wynika to z masek bitowych. Zobacz niektóre tematy.
CoolMind,
0

Zetknąłem się również z problemem, który nawet jeśli wywołasz poprawne polecenie requestPermissions, nadal może mieć ten problem. Problem polega na tym, że aktywność rodzica może zastąpić tę metodę bez wywoływania super. Dodaj super, a zostanie to naprawione.

Włodzimierz
źródło