java - Android M अनुमतियाँ: onRequestPimsResult() नहीं कहा जा रहा है




permissions android-permissions (16)

मैं नए एम अनुमतियाँ प्रणाली का उपयोग करने के लिए हमारे ऐप को अपडेट कर रहा हूं। यह सब onRequestPimsResult () के अलावा काम कर रहा है। मुझे एक बटन प्रेस पर एक अनुमति की जांच करने की आवश्यकता है, और यदि यह सफल है, तो एक पाठ संदेश भेजें। जब मैं इसे करने की अनुमति देता हूं, तो संवाद बंद हो जाता है, लेकिन जब तक मैं फिर से बटन दबाता हूं, तब तक यह पाठ को ट्रिगर नहीं करता है।

मैंने डिबग किया है और ब्रेकप्वाइंट को onRequestPeaksResult () विधि में सेट किया है, लेकिन यह कभी इसमें नहीं जाता है।

इस विधि को पहले कहा जाता है:

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

और फिर मेरा कॉलबैक इस तरह दिखता है:

    @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);
                }
            }
        }
    }
}

क्या कोई भी एक समान मुद्दे में भाग गया है? इस के साथ किसी भी मदद की सराहना करते हैं। धन्यवाद


विवरण

  • कोटलिन 1.2.70
  • minSdkVersion 19 में जाँच की गई
  • एंड्रॉइड स्टूडियो 3.1.4

कलन विधि

मॉड्यूल - कैमरा, स्थान, ...।

  1. जांचें कि क्या हैसिस्टमफिट्योर (यदि मॉड्यूल फोन में मौजूद है)
  2. जांचें कि क्या उपयोगकर्ता के पास मॉड्यूल तक पहुंच है
  3. अनुमति अनुरोध भेजें (उपयोगकर्ता से मॉड्यूल उपयोग की अनुमति मांगें)

विशेषताएं

  1. क्रियाएँ और टुकड़े के साथ काम करें
  2. केवल एक परिणाम प्रतिक्रिया है
  3. एक अनुरोध में कई मॉड्यूल की जांच कर सकते हैं

उपाय

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()
        }
    }
}

गतिविधि में उपयोग (एक ही टुकड़े में)

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

अद्यतन: गतिविधि में Super.onRequestPermissionResult () को कॉल करने के बारे में किसी और के उत्तर को देखा और जो मेरे द्वारा उल्लिखित अनुरोध कोड समस्या को ठीक करता है और खंड के onRequestPermissionResult को कॉल करता है।

इस सामान को अनदेखा करें:

मेरे लिए यह गतिविधि के onRequestPermissionResult को कॉल करने के बावजूद मेरे टुकड़े टुकड़े होने के बावजूद।

सौभाग्य से यह एकमात्र अनुमति है जो हम उस स्क्रीन पर अनुरोध करते हैं इसलिए मैं केवल अनुरोध कोड को अनदेखा करता हूं (यह पता लगाने का समय नहीं है कि यह अभी क्यों नहीं है)


आप यह कोशिश कर सकते हैं:

requestPermissions(permissions, PERMISSIONS_CODE);

यदि आप एक खंड से इस कोड को बुला रहे हैं, तो इसका स्वयं का अनुरोध तरीका है। मेरा मानना ​​है कि समस्या यह है कि आप स्थैतिक विधि कह रहे हैं।

यदि आप चाहते हैं कि प्रो टिप एक टुकड़े में onRequestPermissionsResult() : FragmentCompat.requestPermissions(Fragment fragment, String[] permissions, int requestCode)


आपके पास FragmentCompat में पूर्व मार्शमैलो उपकरणों के लिए चेकपाइन्स फ़ंक्शन है। मैं इस तरह का उपयोग करें:

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

टुकड़े के अंदर, आपको कॉल करने की आवश्यकता है:

FragmentCompat.requestPermissions(permissionsList, RequestCode)

नहीं:

ActivityCompat.requestPermissions(Activity, permissionsList, RequestCode);

मुझे उम्मीद है कि यह ठीक काम करेगा

गतिविधि के लिए:

 ActivityCompat.requestPermissions(this,permissionsList,REQUEST_CODE);

टुकड़े के लिए:

 requestPermissions(permissionsList,REQUEST_CODE);

मुझे भी इस समस्या का सामना करना पड़ा। यदि आप ऐसी गतिविधि चाहते हैं, जो इतिहास / रीसेंट में अनुमतियों को नहीं संभालती है, तो आपको अपनी AndroidManifest.xml प्रविष्टि बदलने का प्रलोभन दिया जाएगा।

यदि आप उस गतिविधि को सेट करते हैं जिसे आप requestPermissions या requestPermissions साथ कहते हैं

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

आपके AndroidManifest.xml onRequestPermissionsResult() नहीं कहा जाएगा। यह सच है यदि आपकी गतिविधि Activity या AppCompatActivity से ली गई है।

इसके बजाय 'AndroidManifest.xml' से दोनों झंडे हटाकर और इसके बजाय finishAndRemoveTask() साथ अपनी गतिविधि समाप्त करके इसे ठीक किया जा सकता है।


मेरे पास इसे प्राप्त करने के लिए एक अद्भुत समाधान है इस तरह एक बेसएक्टिविटी बनाएं।

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();
            }
        }
    }
}

}

अब यो इस तरह की अनुमति के लिए कोड को कॉल कर सकता है

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

अब हर बार यह कहीं भी होता है चाहे आपके टुकड़े में या किसी गतिविधि में आधार गतिविधि कहा जाता हो।

धन्यवाद


मैं एक ही मुद्दे में भाग गया और मुझे सिर्फ समाधान मिला। सपोर्ट लाइब्रेरी का उपयोग करते समय, आपको सही विधि कॉल का उपयोग करना होगा। उदाहरण के लिए:

  • जब AppCompatActivity में , आपको एक्टिविटी Compat.requestPims का उपयोग करना चाहिए;
  • जब android.support.v4.app.Fragment में , आपको बस अनुरोधों का उपयोग करना चाहिए (यह android.support.v4.app.Fragment का एक उदाहरण तरीका है)

यदि आप गतिविधिकंपत्ति को एक टुकड़े में कॉल करते हैं, तो OnRequestPcriResult कॉलबैक गतिविधि पर कॉल किया जाता है, न कि टुकड़ा।

उम्मीद है की यह मदद करेगा!


यदि आप एक खंड से इस कोड को बुला रहे हैं, तो इसका स्वयं का अनुरोध तरीका है।

इसलिए मूल अवधारणा है, यदि आप किसी गतिविधि में हैं, तो कॉल करें

ActivityCompat.requestPermissions(this,
                            permissionsList,
                            permissionscode);

और अगर एक टुकड़ा में, बस फोन

requestPermissions(permissionsList,
                            permissionscode);

यदि आपके पास गतिविधि और खंड दोनों में onRequestPermissionsResult है, तो गतिविधि में 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);
    }
...

यह समस्या वास्तव में NestedFragments के कारण हो रही थी। मूल रूप से सबसे अधिक टुकड़े हम एक HostedFragment का विस्तार करते हैं जो बदले में एक संगतता को बढ़ाता है। इन नीडिंत अंशों के होने के कारण समस्याएँ पैदा हुईं जो अंततः परियोजना के किसी अन्य डेवलपर द्वारा हल की गईं।

वह इस काम को पाने के लिए बिट स्विचिंग जैसे कुछ निम्न स्तर के सामान कर रहा था इसलिए मैं वास्तविक अंतिम समाधान के बारे में सुनिश्चित नहीं हूं


यहां मैं अपना कोड दिखाना चाहता हूं कि मैंने इसे कैसे प्रबंधित किया।

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;
   }
}

यहाँ इस वर्ग में मैं अनुमति दी गई जाँच करना चाहता हूँ या नहीं। नहीं है तो मैं अपने MainActivity से अनुमति की तरह कहूंगा

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;
                }
            }
    }
}

अब onCreate पद्धति में आपको requestForPermission () फ़ंक्शन को कॉल करने की आवश्यकता है।

यही है। इसके अलावा, आप एक बार में कई अनुमति का अनुरोध कर सकते हैं।


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();
    }
}

 /* 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);





android-permissions