Android ขออนุญาต Marshmallow?


165

ฉันกำลังทำงานกับแอปพลิเคชันที่ต้องได้รับการอนุญาต "อันตราย" หลายอย่าง ดังนั้นฉันจึงลองเพิ่ม "ขออนุญาต" ตามต้องการใน Android Marshmallow (ระดับ API 23) แต่ไม่สามารถหาวิธีทำได้

ฉันจะขออนุญาตใช้รูปแบบการอนุญาตใหม่ในแอพของฉันได้อย่างไร


1
ดูที่นี่นี่คือทั้งหมดที่คุณต้องการ: developer.android.com/training/permissions/requesting.html
Thomas R.

1
ลองดูที่นี่ในthecheesefactory.com/blog/…
Dory

คุณดูตัวอย่างจาก GitHub repo ของ Google หรือไม่
IgorGanapolsky

เห็นจาก developer.android.com/training/permissions/requesting.html ในเวลานั้นฉันยังใหม่กับ Android และ Android เร็ว ๆ นี้ Marshmallow มาและการฝึกอบรมของ Google ทำให้ฉันสับสนมากขึ้นและไม่สามารถหาบทเรียนเกี่ยวกับเรื่องนี้ได้
Nilabja

ฉันสร้างห้องสมุดสำหรับมันแล้ว มันใช้งานง่ายโดยขั้นตอนง่าย ๆ github.com/Kishanjvaghela/Ask-Permission
Kishan Vaghela

คำตอบ:


240

เปิดกล่องโต้ตอบโดยใช้รหัสด้านล่าง:

 ActivityCompat.requestPermissions(MainActivity.this,
                    new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
                    1);

รับผลกิจกรรมดังต่อไปนี้:

@Override
public void onRequestPermissionsResult(int requestCode,
                                       String permissions[], int[] grantResults) {
    switch (requestCode) {
        case 1: {

          // If request is cancelled, the result arrays are empty.
          if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                // permission was granted, yay! Do the
                // contacts-related task you need to do.          
            } else {

                // permission denied, boo! Disable the
                // functionality that depends on this permission.
                Toast.makeText(MainActivity.this, "Permission denied to read your External storage", Toast.LENGTH_SHORT).show();
            }
            return;
        }

        // other 'case' lines to check for other
        // permissions this app might request
    }
}

ข้อมูลเพิ่มเติม: https://developer.android.com/training/permissions/requesting.html


3
ฉันสร้างห้องสมุดสำหรับมันแล้ว มันใช้งานง่ายโดยขั้นตอนง่าย ๆ github.com/Kishanjvaghela/Ask-Permission
Kishan Vaghela

รวมถึงส่วนนี้หากผู้ใช้คลิกยกเลิก: อื่นถ้า (grantResults.length> 0 && GrantResults [0] == PackageManager.PERMISSION_DENIED)
mehmet

จะActivityCompat.requestPermissionsเลิก? (ใน Nugat)
ThunderWiring

คุณได้รับตัวแปรนั้นอยู่ที่ไหน ActivityCompat?
gumuruh

@gumuruh ตัวแปรอะไร
CoolMind

61

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

int MyVersion = Build.VERSION.SDK_INT;
if (MyVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
                if (!checkIfAlreadyhavePermission()) {
                    requestForSpecificPermission();
                }
}

โมดูล checkIfAlreadyhavePermission () มีการใช้งานเป็น:

private boolean checkIfAlreadyhavePermission() {
    int result = ContextCompat.checkSelfPermission(this, Manifest.permission.GET_ACCOUNTS);
    if (result == PackageManager.PERMISSION_GRANTED) {
        return true;
    } else {
        return false;
    }
}

โมดูล requestForSpecificPermission () มีการใช้งานเป็น:

private void requestForSpecificPermission() {
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.GET_ACCOUNTS, Manifest.permission.RECEIVE_SMS, Manifest.permission.READ_SMS, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, 101);
}

และแทนที่ในกิจกรรม:

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    switch (requestCode) {
        case 101:
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                //granted
            } else {
                //not granted
            }
            break;
        default:
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }
}

อ้างถึงลิงค์นี้สำหรับรายละเอียดเพิ่มเติม: http://revisitingandroid.blogspot.in/2017/01/how-to-check-and-request-for-run-time.html


ข้อเสนอแนะที่เป็นมิตร: แทนที่คำสั่ง if checkIfAlreadyhavePermissionเป็นreturn result == PackageManager.PERMISSION_GRANTED;
Ellen Spertus

19

ฉันใช้ wrapper นี้ (แนะนำ) เขียนโดยนักพัฒนาของ Google มันใช้งานง่ายสุด ๆ

https://github.com/googlesamples/easypermissions

ฟังก์ชั่นการจัดการกับการตรวจสอบและขออนุญาตหากจำเป็น

public void locationAndContactsTask() {
    String[] perms = { Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.READ_CONTACTS };
    if (EasyPermissions.hasPermissions(this, perms)) {
        // Have permissions, do the thing!
        Toast.makeText(this, "TODO: Location and Contacts things", Toast.LENGTH_LONG).show();
    } else {
        // Ask for both permissions
        EasyPermissions.requestPermissions(this, getString(R.string.rationale_location_contacts),
                RC_LOCATION_CONTACTS_PERM, perms);
    }
}

Happy coding :)


1
@Farhan ฉันเข้าใจดีว่า :) ฉันหวังว่า API ของ Android จะง่ายขึ้นดังนั้นเราจึงไม่ต้องใช้ตัวห่อหุ้ม
คุณน

ฉันไม่เห็นว่า "RC_CAMERA_AND_LOCATION" มาจากไหนหรือจะหาการอนุญาตอื่นใดจากที่อื่นคุณรู้หรือไม่ว่ามาจากไหน
Fonix

17

เริ่มต้นใน Android Marshmallow เราจำเป็นต้องขอสิทธิ์การใช้งานเฉพาะผู้ใช้ นอกจากนี้เรายังสามารถตรวจสอบรหัสผ่านหากได้รับอนุญาตแล้ว นี่คือรายการสิทธิ์ที่จำเป็นทั่วไป:

  • android.permission_group.CALENDAR

    • android.permission.READ_CALENDAR
    • android.permission.WRITE_CALENDAR
  • android.permission_group.CAMERA

    • android.permission.CAMERA
  • android.permission_group.CONTACTS

    • android.permission.READ_CONTACTS
    • android.permission.WRITE_CONTACTS
    • android.permission.GET_ACCOUNTS
  • android.permission_group.LOCATION

    • android.permission.ACCESS_FINE_LOCATION
    • android.permission.ACCESS_COARSE_LOCATION
  • android.permission_group.MICROPHONE

    • android.permission.RECORD_AUDIO
  • android.permission_group.PHONE

    • android.permission.READ_PHONE_STATE
    • android.permission.CALL_PHONE
    • android.permission.READ_CALL_LOG
    • android.permission.WRITE_CALL_LOG
    • android.permission.ADD_VOICEMAIL
    • android.permission.USE_SIP
    • android.permission.PROCESS_OUTGOING_CALLS
  • android.permission_group.SENSORS

    • android.permission.BODY_SENSORS
  • android.permission_group.SMS

    • android.permission.SEND_SMS
    • android.permission.RECEIVE_SMS
    • android.permission.READ_SMS
    • android.permission.RECEIVE_WAP_PUSH
    • android.permission.RECEIVE_MMS
    • android.permission.READ_CELL_BROADCASTS
  • android.permission_group.STORAGE

    • android.permission.READ_EXTERNAL_STORAGE
    • android.permission.WRITE_EXTERNAL_STORAGE

นี่คือตัวอย่างรหัสเพื่อตรวจสอบการอนุญาต:

if (ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_CALENDAR) != PackageManager.PERMISSION_GRANTED) {
    if (ActivityCompat.shouldShowRequestPermissionRationale((Activity) context, Manifest.permission.WRITE_CALENDAR)) {
        AlertDialog.Builder alertBuilder = new AlertDialog.Builder(context);
        alertBuilder.setCancelable(true);
        alertBuilder.setMessage("Write calendar permission is necessary to write event!!!");
        alertBuilder.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
            @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
            public void onClick(DialogInterface dialog, int which) {
                ActivityCompat.requestPermissions((Activity)context, new String[]{Manifest.permission.WRITE_CALENDAR}, MY_PERMISSIONS_REQUEST_WRITE_CALENDAR);
            }
        });
    } else {
        ActivityCompat.requestPermissions((Activity)context, new String[]{Manifest.permission.WRITE_CALENDAR}, MY_PERMISSIONS_REQUEST_WRITE_CALENDAR);
    }
}

14

ระดับของฉันสำหรับการร้องขอสิทธิ์ใน runtime ActivityหรือFragment

นอกจากนี้ยังช่วยให้คุณแสดงเหตุผลหรือเปิดการตั้งค่าเพื่อเปิดใช้งานการอนุญาตหลังจากที่ผู้ใช้ปฏิเสธตัวเลือกการอนุญาต (พร้อม / ไม่มีNever ask again) ได้ง่ายขึ้น

class RequestPermissionHandler(private val activity: Activity? = null,
                               private val fragment: Fragment? = null,
                               private val permissions: Set<String> = hashSetOf(),
                               private val listener: Listener? = null
) {
    private var hadShowRationale: Boolean = false

    fun requestPermission() {
        hadShowRationale = showRationaleIfNeed()
        if (!hadShowRationale) {
            doRequestPermission(permissions)
        }
    }

    fun retryRequestDeniedPermission() {
        doRequestPermission(permissions)
    }

    private fun showRationaleIfNeed(): Boolean {
        val unGrantedPermissions = getPermission(permissions, Status.UN_GRANTED)
        val permanentDeniedPermissions = getPermission(unGrantedPermissions, Status.PERMANENT_DENIED)
        if (permanentDeniedPermissions.isNotEmpty()) {
            val consume = listener?.onShowSettingRationale(unGrantedPermissions)
            if (consume != null && consume) {
                return true
            }
        }

        val temporaryDeniedPermissions = getPermission(unGrantedPermissions, Status.TEMPORARY_DENIED)
        if (temporaryDeniedPermissions.isNotEmpty()) {
            val consume = listener?.onShowPermissionRationale(temporaryDeniedPermissions)
            if (consume != null && consume) {
                return true
            }
        }
        return false
    }

    fun requestPermissionInSetting() {
        val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
        val packageName = activity?.packageName ?: run {
            fragment?.requireActivity()?.packageName
        }
        val uri = Uri.fromParts("package", packageName, null)
        intent.data = uri
        activity?.apply {
            startActivityForResult(intent, REQUEST_CODE)
        } ?: run {
            fragment?.startActivityForResult(intent, REQUEST_CODE)
        }
    }

    fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>,
                                   grantResults: IntArray) {
        if (requestCode == REQUEST_CODE) {
            for (i in grantResults.indices) {
                if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
                    markNeverAskAgainPermission(permissions[i], false)
                } else if (!shouldShowRequestPermissionRationale(permissions[i])) {
                    markNeverAskAgainPermission(permissions[i], true)
                }
            }
            var hasShowRationale = false
            if (!hadShowRationale) {
                hasShowRationale = showRationaleIfNeed()
            }
            if (hadShowRationale || !hasShowRationale) {
                notifyComplete()
            }
        }
    }

    fun onActivityResult(requestCode: Int) {
        if (requestCode == REQUEST_CODE) {
            getPermission(permissions, Status.GRANTED).forEach {
                markNeverAskAgainPermission(it, false)
            }
            notifyComplete()
        }
    }

    fun cancel() {
        notifyComplete()
    }

    private fun doRequestPermission(permissions: Set<String>) {
        activity?.let {
            ActivityCompat.requestPermissions(it, permissions.toTypedArray(), REQUEST_CODE)
        } ?: run {
            fragment?.requestPermissions(permissions.toTypedArray(), REQUEST_CODE)
        }
    }

    private fun getPermission(permissions: Set<String>, status: Status): Set<String> {
        val targetPermissions = HashSet<String>()
        for (p in permissions) {
            when (status) {
                Status.GRANTED -> {
                    if (isPermissionGranted(p)) {
                        targetPermissions.add(p)
                    }
                }
                Status.TEMPORARY_DENIED -> {
                    if (shouldShowRequestPermissionRationale(p)) {
                        targetPermissions.add(p)
                    }
                }
                Status.PERMANENT_DENIED -> {
                    if (isNeverAskAgainPermission(p)) {
                        targetPermissions.add(p)
                    }
                }
                Status.UN_GRANTED -> {
                    if (!isPermissionGranted(p)) {
                        targetPermissions.add(p)
                    }
                }
            }
        }
        return targetPermissions
    }

    private fun isPermissionGranted(permission: String): Boolean {
        return activity?.let {
            ActivityCompat.checkSelfPermission(it, permission) == PackageManager.PERMISSION_GRANTED
        } ?: run {
            ActivityCompat.checkSelfPermission(fragment!!.requireActivity(), permission) == PackageManager.PERMISSION_GRANTED
        }
    }

    private fun shouldShowRequestPermissionRationale(permission: String): Boolean {
        return activity?.let {
            ActivityCompat.shouldShowRequestPermissionRationale(it, permission)
        } ?: run {
            ActivityCompat.shouldShowRequestPermissionRationale(fragment!!.requireActivity(), permission)
        }
    }

    private fun notifyComplete() {
        listener?.onComplete(getPermission(permissions, Status.GRANTED), getPermission(permissions, Status.UN_GRANTED))
    }

    private fun getPrefs(context: Context): SharedPreferences {
        return context.getSharedPreferences("SHARED_PREFS_RUNTIME_PERMISSION", Context.MODE_PRIVATE)
    }

    private fun isNeverAskAgainPermission(permission: String): Boolean {
        return getPrefs(requireContext()).getBoolean(permission, false)
    }

    private fun markNeverAskAgainPermission(permission: String, value: Boolean) {
        getPrefs(requireContext()).edit().putBoolean(permission, value).apply()
    }

    private fun requireContext(): Context {
        return fragment?.requireContext() ?: run {
            activity!!
        }
    }

    enum class Status {
        GRANTED, UN_GRANTED, TEMPORARY_DENIED, PERMANENT_DENIED
    }

    interface Listener {
        fun onComplete(grantedPermissions: Set<String>, deniedPermissions: Set<String>)
        fun onShowPermissionRationale(permissions: Set<String>): Boolean
        fun onShowSettingRationale(permissions: Set<String>): Boolean
    }

    companion object {
        const val REQUEST_CODE = 200
    }
}

ใช้ในสิ่งที่Activityชอบ

class MainActivity : AppCompatActivity() {
    private lateinit var smsAndStoragePermissionHandler: RequestPermissionHandler

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

        smsAndStoragePermissionHandler = RequestPermissionHandler(this@MainActivity,
                permissions = setOf(Manifest.permission.RECEIVE_SMS, Manifest.permission.READ_EXTERNAL_STORAGE),
                listener = object : RequestPermissionHandler.Listener {
                    override fun onComplete(grantedPermissions: Set<String>, deniedPermissions: Set<String>) {
                        Toast.makeText(this@MainActivity, "complete", Toast.LENGTH_SHORT).show()
                        text_granted.text = "Granted: " + grantedPermissions.toString()
                        text_denied.text = "Denied: " + deniedPermissions.toString()
                    }

                    override fun onShowPermissionRationale(permissions: Set<String>): Boolean {
                        AlertDialog.Builder(this@MainActivity).setMessage("To able to Send Photo, we need SMS and" + " Storage permission")
                                .setPositiveButton("OK") { _, _ ->
                                    smsAndStoragePermissionHandler.retryRequestDeniedPermission()
                                }
                                .setNegativeButton("Cancel") { dialog, _ ->
                                    smsAndStoragePermissionHandler.cancel()
                                    dialog.dismiss()
                                }
                                .show()
                        return true // don't want to show any rationale, just return false here
                    }

                    override fun onShowSettingRationale(permissions: Set<String>): Boolean {
                        AlertDialog.Builder(this@MainActivity).setMessage("Go Settings -> Permission. " + "Make SMS on and Storage on")
                                .setPositiveButton("Settings") { _, _ ->
                                    smsAndStoragePermissionHandler.requestPermissionInSetting()
                                }
                                .setNegativeButton("Cancel") { dialog, _ ->
                                    smsAndStoragePermissionHandler.cancel()
                                    dialog.cancel()
                                }
                                .show()
                        return true
                    }
                })

        button_request.setOnClickListener { handleRequestPermission() }
    }

    private fun handleRequestPermission() {
        smsAndStoragePermissionHandler.requestPermission()
    }

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

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        smsAndStoragePermissionHandler.onActivityResult(requestCode)
    }
}

รหัสบน Github

การสาธิต


3
ทางออกที่ดีที่สุดเกี่ยวกับการขออนุญาตซึ่งฉันสามารถหาได้
DolDurma

@Phan คุณมีข้อมูลโค้ดเพื่อขออนุญาตและการจัดการที่ไม่ได้รับอนุญาตหรือไม่
binrebin

10

Android-M เช่น API 23 ได้เปิดใช้งานการอนุญาตรันไทม์เพื่อลดข้อบกพร่องด้านความปลอดภัยในอุปกรณ์ Android ซึ่งผู้ใช้สามารถจัดการสิทธิ์การใช้งานแอพได้โดยตรงที่ runtime ดังนั้นหากผู้ใช้ปฏิเสธการอนุญาตเฉพาะแอปพลิเคชันของคุณ ที่คุณพูดถึงในแบบสอบถามของคุณ

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

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

                // permission was granted, yay! Do the
                // contacts-related task you need to do.

               } else {

                // permission denied, boo! Disable the
                // functionality that depends on this permission.
            }
            return;
        }

        // other 'case' lines to check for other
        // permissions this app might request
    }
}

ดังนั้นในที่สุดมันก็เป็นแนวปฏิบัติที่ดีที่จะทำการเปลี่ยนแปลงพฤติกรรมหากคุณวางแผนที่จะทำงานกับเวอร์ชันใหม่เพื่อหลีกเลี่ยงการบังคับปิด :)

สิทธิ์ปฏิบัติที่ดีที่สุด

คุณสามารถไปถึงแอพพลิเคตัวอย่างเป็นทางการที่นี่


โปรดจำไว้ว่าเราต้องมี noHistory = falseเพื่อรับการติดต่อกลับ โปรดอ้างถึงสิ่งนี้ในกรณีที่คุณไม่ได้รับการติดต่อกลับ ฉันเสียเวลาหลายชั่วโมงในการคิดออก
Atul

6

จาก Android Marshmallow (API 23) ขึ้นไปโดยค่าเริ่มต้นการอนุญาตที่เป็นอันตรายทั้งหมด (ตามเอกสารอย่างเป็นทางการของ doc อย่างเป็นทางการ ) ถูกปิดใช้งาน หลังจากการติดตั้งเมื่อเปิดแอปเป็นครั้งแรกคุณจะต้องให้สิทธิ์ใน Run Time

ฉันบรรลุวิธีต่อไปนี้:

public class MarshMallowPermission {

    public static final int EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE_BY_GALLERY = 0;
    public static final int EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE_BY_CAMERA = 1;
    public static final int EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE_BY_LOAD_PROFILE = 2;
    public static final int CAMERA_PERMISSION_REQUEST_CODE = 3;
    public static final int LOCATION_PERMISSION_REQUEST_CODE = 4;
    Activity activity;
    Context mContext;

    public MarshMallowPermission(Activity activity) {
        this.activity = activity;
        this.mContext = activity;
    }

    public boolean checkPermissionForExternalStorage(){
        int result = ContextCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);
        if (result == PackageManager.PERMISSION_GRANTED){
            return true;
        } else {
            return false;
        }
    }

    public boolean checkPermissionForCamera(){
        int result = ContextCompat.checkSelfPermission(activity, Manifest.permission.CAMERA);
        if (result == PackageManager.PERMISSION_GRANTED){
            return true;
        } else {
            return false;
        }
    }

    public boolean checkLocationPermission(){

        int result = ActivityCompat.checkSelfPermission(activity, Manifest.permission.ACCESS_FINE_LOCATION);
        if (result == PackageManager.PERMISSION_GRANTED){
            return true;
        } else {
            return false;
        }
    }

    public void requestPermissionForExternalStorage(int requestCode){
        if (ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE)){
            Toast.makeText(mContext.getApplicationContext(), "External Storage permission needed. Please allow in App Settings for additional functionality.", Toast.LENGTH_LONG).show();
        } else {
            ActivityCompat.requestPermissions(activity,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},requestCode);
        }
    }

    public void requestPermissionForCamera(){
        if (ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.CAMERA)){
            Toast.makeText(mContext.getApplicationContext(), "Camera permission needed. Please allow in App Settings for additional functionality.", Toast.LENGTH_LONG).show();
        } else {
            ActivityCompat.requestPermissions(activity,new String[]{Manifest.permission.CAMERA},CAMERA_PERMISSION_REQUEST_CODE);
        }
    }
    public void requestPermissionForLocation(){
        if (ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.ACCESS_FINE_LOCATION) && ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.ACCESS_COARSE_LOCATION)){
            Toast.makeText(mContext.getApplicationContext(), "Location permission needed. Please allow in App Settings for additional functionality.", Toast.LENGTH_LONG).show();
        } else {
            ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.ACCESS_FINE_LOCATION,Manifest.permission.ACCESS_COARSE_LOCATION}, LOCATION_PERMISSION_REQUEST_CODE);
        }
    }
}

ในชั้นเรียนกิจกรรมของคุณ:

 public class MainActivity extends AppCompatActivity{

   private MarshMallowPermission marshMallowPermission;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        Log.d("NavHome", "Oncreate_nav");
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        marshMallowPermission = new MarshMallowPermission(MainActivity.this);



        if (!marshMallowPermission.checkPermissionForExternalStorage()) {
            marshMallowPermission.requestPermissionForExternalStorage(MarshMallowPermission.EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE_BY_LOAD_PROFILE);
        }
    }

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

        switch (requestCode) {
            case MarshMallowPermission.EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE_BY_LOAD_PROFILE:
                if (grantResults.length > 0
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                    //permission granted successfully

                } else {

                 //permission denied

                }
                break;
    }
    }

}

5

เพิ่มการอนุญาตให้กับ AndroidManifest.xml

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application ...>
 ....
</application>

เพื่อตรวจสอบเวอร์ชั่น Android ว่าต้องการการอนุญาตรันไทม์หรือไม่

if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1) {
    askForPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE, 1);
}

ขอให้ผู้ใช้อนุญาตหากไม่ได้รับอนุญาต

private void askForPermission(String permission, int requestCode) {
    if (ContextCompat.checkSelfPermission(c, permission)
            != PackageManager.PERMISSION_GRANTED) {
        if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, permission)) {
            Toast.makeText(c, "Please grant the requested permission to get your task done!", Toast.LENGTH_LONG).show();
            ActivityCompat.requestPermissions(MainActivity.this, new String[]{permission}, requestCode);
        } else {
            ActivityCompat.requestPermissions(MainActivity.this, new String[]{permission}, requestCode);
        }
    }
}

ทำอะไรบางอย่างถ้าได้รับอนุญาตหรือไม่

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    switch (requestCode) {
        case 1:
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                //permission with request code 1 granted
                Toast.makeText(this, "Permission Granted" , Toast.LENGTH_LONG).show();
            } else {
                //permission with request code 1 was not granted
                Toast.makeText(this, "Permission was not Granted" , Toast.LENGTH_LONG).show();
            }
            break;
        default:
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }
}

4

ฉันใช้สิ่งนี้เป็นคลาส Fragment พื้นฐาน ฉันขอสิทธิ์จากส่วนเท่านั้น แต่คุณสามารถ refactor มันและทำให้รุ่นของกิจกรรมที่คล้ายกัน

public class BaseFragment extends Fragment {

    private static final int PERMISSION_REQUEST_BLOCK_INTERNAL = 555;
    private static final String PERMISSION_SHARED_PREFERENCES = "permissions";

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        if (requestCode == PERMISSION_REQUEST_BLOCK_INTERNAL) {
            boolean allPermissionsGranted = true;

            for (int iGranting : grantResults) {
                if (iGranting != PermissionChecker.PERMISSION_GRANTED) {
                    allPermissionsGranted = false;
                    break;
                }
            }

            if (allPermissionsGranted && permissionBlock != null) {
                permissionBlock.run();
            }

            permissionBlock = null;
        }
    }

    public void runNowOrAskForPermissionsFirst(String permission, Runnable block) {
        if (hasPermission(permission)) {
            block.run();
        } else if (!hasPermissionOrWillAsk(permission)) {
            permissionBlock = block;
            askForPermission(permission, PERMISSION_REQUEST_BLOCK_INTERNAL);
        }
    }

    public boolean hasPermissionOrWillAsk(String permission) {
        boolean hasPermission = hasPermission(permission);
        boolean hasAsked = hasPreviouslyAskedForPermission(permission);
        boolean shouldExplain = shouldShowRequestPermissionRationale(permission);

        return hasPermission || (hasAsked && !shouldExplain);
    }

    private boolean hasPermission(String permission) {
        return (ContextCompat.checkSelfPermission(getContext(), permission) == PackageManager.PERMISSION_GRANTED);
    }

    private boolean hasPreviouslyAskedForPermission(String permission) {
        SharedPreferences prefs = getContext().getSharedPreferences(PERMISSION_SHARED_PREFERENCES, Context.MODE_PRIVATE);
        return prefs.getBoolean(permission, false);
    }

    private void askForPermission(String permission, int requestCode) {
        SharedPreferences.Editor editor = getContext().getSharedPreferences(PERMISSION_SHARED_PREFERENCES, Context.MODE_PRIVATE).edit();

        editor.putBoolean(permission, true);
        editor.apply();

        requestPermissions(new String[] { permission }, requestCode);
    }
}

มีวิธีการสำคัญสองวิธีที่คุณควรใช้:

  • hasPermissionOrWillAsk - ใช้สิ่งนี้เพื่อดูว่ามีการขออนุญาตและปฏิเสธโดยผู้ใช้ที่ไม่ต้องการถูกขออีกครั้งหรือไม่ สิ่งนี้มีประโยชน์สำหรับการปิดการใช้งาน UI เมื่อผู้ใช้ได้รับคำตอบสุดท้ายเกี่ยวกับการไม่ต้องการฟีเจอร์

  • runNowOrAskForPermissionsFirst - ใช้เพื่อเรียกใช้โค้ดบางอย่างที่ต้องการการอนุญาต หากผู้ใช้ได้อนุญาตแล้วรหัสจะทำงานทันที มิฉะนั้นรหัสจะทำงานในภายหลังหากผู้ใช้ได้รับอนุญาต หรือไม่เลย มันดีเพราะคุณระบุรหัสในที่เดียว

นี่คือตัวอย่าง:

mFragment.runNowOrAskForPermissionsFirst(Manifest.permission.ACCESS_FINE_LOCATION, new Runnable() {
    @Override
    public void run() {
        ...do something if we have permission...
    }
});

ยินดีที่จะรับข้อเสนอแนะเกี่ยวกับเรื่องนี้ ไม่ว่าตัวอย่างเฉพาะนี้ง่ายขึ้นเล็กน้อยซึ่งคุณต้องตรวจสอบเพื่อดูว่าบริการตำแหน่งเปิดใช้งานบนอุปกรณ์หรือไม่ (ซึ่งแตกต่างจากการอนุญาต) นอกจากนี้ยังรองรับการอนุญาตครั้งละหนึ่งครั้งเท่านั้น แต่จะง่ายต่อการแก้ไขหากคุณต้องการการสนับสนุนมากกว่าหนึ่งครั้ง


4

มันอาจเป็นวิธีที่สะอาดกว่า เพิ่มการอนุญาตทั้งหมดของคุณในอาเรย์

private static final String[] INITIAL_PERMS={
            android.Manifest.permission.ACCESS_FINE_LOCATION,
            android.Manifest.permission.ACCESS_COARSE_LOCATION
    };
    private static final int INITIAL_REQUEST=1337;

สิ่งที่ใบอนุญาตของคุณคือการสร้างวิธีการสำหรับแต่ละใบอนุญาต

@RequiresApi(api = Build.VERSION_CODES.M)
private boolean canAccessFineLocation() {
    return(hasPermission(Manifest.permission.ACCESS_FINE_LOCATION));
}

@RequiresApi(api = Build.VERSION_CODES.M)
private boolean canAccessCoarseLocation() {
    return(hasPermission(Manifest.permission.ACCESS_COARSE_LOCATION));
}

@RequiresApi(api = Build.VERSION_CODES.M)
private boolean hasPermission(String perm) {
    return(PackageManager.PERMISSION_GRANTED == checkSelfPermission(perm));
}

เรียกวิธีนี้ในonCreate

 if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
      if(!canAccessCoarseLocation() || !canAccessFineLocation()){
            requestPermissions(INITIAL_PERMS, INITIAL_REQUEST);
        }
 }

ตอนนี้แทนที่onRequestPermissionsResult

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

    if(requestCode == INITIAL_REQUEST){
        if (canAccessFineLocation() && canAccessCoarseLocation())  {
            //call your method
        }
        else {
            //show Toast or alert that this permissions is neccessary
        }
    }
}

1
ไม่มี requireApi และฉันได้รับข้อผิดพลาดในกิจกรรมของฉันฉันใช้หมายเหตุประกอบ
TragetApi

@Jawad วิธีนี้ใช้ได้ผลดีกว่าหากคุณเพิ่มการปฏิเสธการโทรกลับที่ได้รับอนุญาต
Binrebin

3

สำหรับการอนุญาตหลายครั้งคุณสามารถใช้สิ่งนี้ งานนี้สำหรับฉัน .. ฉันมีวิธีแก้ไขปัญหาอื่น ถ้าคุณให้เป้าหมายของคุณ SDK รุ่น 22 ร้องมันทำงานให้ฉันได้ และมันทำงานเหมือนได้รับอนุญาตจาก manifest.xml ผ่านการทดสอบและใช้งานได้สำหรับฉัน

final private int REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS = 124;

    private void insertDummyContactWrapper() {
        List<String> permissionsNeeded = new ArrayList<String>();

        final List<String> permissionsList = new ArrayList<String>();
        if (!addPermission(permissionsList, Manifest.permission.ACCESS_FINE_LOCATION))
            permissionsNeeded.add("GPS");
        if (!addPermission(permissionsList, Manifest.permission.READ_CONTACTS))
            permissionsNeeded.add("Read Contacts");
        if (!addPermission(permissionsList, Manifest.permission.WRITE_CONTACTS))
            permissionsNeeded.add("Write Contacts");

        if (permissionsList.size() > 0) {
            if (permissionsNeeded.size() > 0) {
                // Need Rationale
                String message = "You need to grant access to " + permissionsNeeded.get(0);
                for (int i = 1; i < permissionsNeeded.size(); i++)
                    message = message + ", " + permissionsNeeded.get(i);
                showMessageOKCancel(message,
                        new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                requestPermissions(permissionsList.toArray(new String[permissionsList.size()]),
                                        REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS);
                            }
                        });
                return;
            }
            requestPermissions(permissionsList.toArray(new String[permissionsList.size()]),
                    REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS);
            return;
        }

        insertDummyContact();
    }

    private boolean addPermission(List<String> permissionsList, String permission) {
        if (checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {
            permissionsList.add(permission);
            // Check for Rationale Option
            if (!shouldShowRequestPermissionRationale(permission))
                return false;
        }
        return true;
    }






@Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        switch (requestCode) {
            case REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS:
                {
                Map<String, Integer> perms = new HashMap<String, Integer>();
                // Initial
                perms.put(Manifest.permission.ACCESS_FINE_LOCATION, PackageManager.PERMISSION_GRANTED);
                perms.put(Manifest.permission.READ_CONTACTS, PackageManager.PERMISSION_GRANTED);
                perms.put(Manifest.permission.WRITE_CONTACTS, PackageManager.PERMISSION_GRANTED);
                // Fill with results
                for (int i = 0; i < permissions.length; i++)
                    perms.put(permissions[i], grantResults[i]);
                // Check for ACCESS_FINE_LOCATION
                if (perms.get(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
                        && perms.get(Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_GRANTED
                        && perms.get(Manifest.permission.WRITE_CONTACTS) == PackageManager.PERMISSION_GRANTED) {
                    // All Permissions Granted
                    insertDummyContact();
                } else {
                    // Permission Denied
                    Toast.makeText(MainActivity.this, "Some Permission is Denied", Toast.LENGTH_SHORT)
                            .show();
                }
                }
                break;
            default:
                super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }

สำหรับรายละเอียดเพิ่มเติม ตรวจสอบลิงค์ร้อง

https://inthecheesefactory.com/blog/things-you-need-to-know-about-android-m-permission-developer-edition/en


การตั้งค่า targetSdkVersion bellow 22 จะใช้งานได้ แต่จะเกิดอะไรขึ้นในผู้ใช้ที่ใช้ android M ปฏิเสธการอนุญาตเพียงหนึ่งเดียวจากการตั้งค่า
Nilabja

ใช่ .. คุณถูกต้องสำหรับเวลานี้แอพจะพัง ดังนั้นเวลาที่คุณต้องตรวจสอบการอนุญาตอีกครั้งปฏิเสธหรือไม่จากผู้ใช้ .. ฉันไม่ได้ทดสอบ แต่ฉันหวังว่ามันจะทำงาน แบบฟอร์มทุกการกระทำจากผู้ใช้มันจะดีกว่าที่จะตรวจสอบการอนุญาตจะได้รับหรือไม่
Tariqul

3

เพื่อจัดการสิทธิ์อนุญาตรันไทม์ google ได้จัดทำโครงการห้องสมุด คุณสามารถตรวจสอบได้จากที่นี่https://github.com/googlesamples/easypermissions

EasyPermissions ได้รับการติดตั้งโดยเพิ่มการพึ่งพาต่อไปนี้ในไฟล์ build.gradle ของคุณ:

dependencies {
compile 'pub.devrel:easypermissions:0.3.0'
}

ในการเริ่มต้นใช้งาน EasyPermissions ให้ Activity (หรือ Fragment) ของคุณแทนที่เมธอด onRequestPermissionsResult:

public class MainActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
}

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

    // Forward results to EasyPermissions
    EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
}

@Override
public void onPermissionsGranted(int requestCode, List<String> list) {
    // Some permissions have been granted
    // ...
}

@Override
public void onPermissionsDenied(int requestCode, List<String> list) {
    // Some permissions have been denied
    // ...
}
}

ที่นี่คุณจะได้รับตัวอย่างการทำงานวิธีการทำงานของห้องสมุดนี้ https://github.com/milon87/EasyPermission


2

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

ลองทำดูสิเพราะมันทำให้ชีวิตง่ายขึ้น: สิทธิ์ Android


2

รหัสด้านล่างนี้ทำงานได้อย่างสมบูรณ์ฉันอธิบายด้วยความช่วยเหลือของตัวอย่าง

ในกรณีของฉันฉันวางการตรวจสอบสิทธิ์แยกต่างหากในคลาส util และผ่านการอนุญาตที่เฉพาะเจาะจงฉันต้องตรวจสอบจากคลาสที่เหมาะสมซึ่งเปิดใช้งานเพื่อนำไฟล์ util check check ไปใช้ในแอปพลิเคชันทั้งหมด

ส่วนรหัสด้านล่างแสดงการเรียกใช้ฟังก์ชันในกรณีนี้กำลังขอandroid.Manifest.permission.READ_EXTERNAL_STORAGEอนุญาต

//the below call is from a fragment
     @OnClick(R.id.button)//butterknife implementation
        public void attachPressed() {
            if (PermissionUtils.hasThisPermission(getContext(), android.Manifest.permission.READ_EXTERNAL_STORAGE)) {
                onAttachPressed();
            } else {
                PermissionUtils.isPermissionRequestNeeded(getActivity(), this, android.Manifest.permission.READ_EXTERNAL_STORAGE, PermissionUtils.REQUEST_GROUP_STORAGE);
            }
        }   

ในกรณีข้างต้นได้รับอนุญาตจะถูกตรวจสอบหากได้รับอนุญาต onAttachPressed();ฟังก์ชั่นที่เรียกว่ามิฉะนั้นเราจะตรวจสอบการขออนุญาต

ด้านล่างเป็นรหัสที่มีอยู่ในคลาส util ในกรณีของฉัน PermissionUtils

public final class PermissionUtils {

    public static final int REQUEST_GROUP_STORAGE = 1508;

    private PermissionUtils() {
    }

    public static boolean hasThisPermission(Context context, String permission) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            return ActivityCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED;
        } else {
            return true;
        }
    }

    public static boolean isPermissionRequestNeeded(Activity activity, Fragment fragment, String permission, int requestCode) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !hasThisPermission(activity, permission)) {
            final String[] permissions = new String[]{permission};
            if (fragment == null) {
                activity.requestPermissions(permissions, requestCode);
            } else {
                fragment.requestPermissions(permissions, requestCode);
            }
            return true;
        }
        return false;
    }
}

และหลังจากการร้องขอหากคุณอาจต้องการเรียกใช้ฟังก์ชันจาก onRequestPermissionsResultหรืออื่นคุณจะต้องกดปุ่มอีกครั้งสำหรับการเรียกใช้ฟังก์ชัน

ดังนั้นเพียงแค่เรียกมันจาก onRequestPermissionsResult

//the below call  is from a fragment
     @Override
        public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
            if (requestCode == PermissionUtils.REQUEST_GROUP_STORAGE && grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                onAttachPressed();
            } else {
                Log.e("value", "Permission Denied, You cannot use local drive .");
            }
        }

2

ฉันใช้ไลบรารีไลบรารีRxPermissionเพื่อขออนุญาต เพราะมันเป็นรหัสยาวที่เราต้องเขียนเพื่อขออนุญาต

RxPermissions rxPermissions = new RxPermissions(this); // where this is an Activity instance // Must be done during an initialization phase like onCreate
rxPermissions
    .request(Manifest.permission.CAMERA)
    .subscribe(granted -> {
        if (granted) { // Always true pre-M
           // I can control the camera now
        } else {
           // Oups permission denied
        }
    });

เพิ่มการพึ่งพาเหล่านี้ในของคุณ build.gradle

allprojects {
    repositories {
        ...
        maven { url 'https://jitpack.io' }
    }
}

dependencies {
    implementation 'com.github.tbruyelle:rxpermissions:0.10.1'
    implementation 'com.jakewharton.rxbinding2:rxbinding:2.1.1'
}

1

ลองสิ่งนี้

นี่เป็นวิธีที่ง่ายที่สุดในการขออนุญาตในรุ่น Marshmallow

 if (ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED&&ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED)
    {
        //TO do here if permission is granted by user
    }
    else
    {
        //ask for permission if user didnot given
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
        {
            requestPermissions(new String[]{Manifest.permission.CAMERA,Manifest.permission.ACCESS_FINE_LOCATION}, 0);
        }
    }

หมายเหตุ: -อย่าลืมเพิ่มสิทธิ์เดียวกันนี้ในไฟล์ Manifest

 <uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

รหัสวิธีที่สองสำหรับการตรวจสอบการอนุญาตจะได้รับหรือไม่?

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

และแทนที่วิธีการ

@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
    switch (requestCode) {
        case 1: {
            if (grantResults.length > 0 && grantResults[1] == PackageManager.PERMISSION_GRANTED) {
         //                    grantResult[0] means it will check for the first postion permission which is READ_EXTERNAL_STORAGE
        //                    grantResult[1] means it will check for the Second postion permission which is CAMERA
                Toast.makeText(this, "Permission Granted", Toast.LENGTH_SHORT).show();
            }
            else
                Toast.makeText(this, "Permission not Granted", Toast.LENGTH_SHORT).show();
            return;
        }
    }
}

คุณกำลังบอกว่าถ้าฉันกำหนดเป้าหมาย Marshmallow หรือสูงกว่านั้นฉันไม่จำเป็นต้องประกาศอนุญาตในรายการ? ฉันรู้ว่าเราต้องใส่มันโดยไม่คำนึงถึงรุ่น Android ที่เรากำหนดเป้าหมาย โปรดแก้ไขให้ฉันด้วยถ้าฉันผิด @Sunil
Nilabja

@Nilabja ได้รับอนุญาตอย่างชัดแจ้งในการประกาศเป็นภาคบังคับสำหรับทุกสภาพอากาศรุ่นหุ่นยนต์มันเป็นขนมหวานหรือไม่
นิล

1

วิธีง่ายๆในการขออนุญาตโดยหลีกเลี่ยงการเขียนโค้ดจำนวนมาก

https://github.com/sachinvarma/EasyPermission

วิธีเพิ่ม:

repositories {
        maven { url "https://jitpack.io" }
    }

implementation 'com.github.sachinvarma:EasyPermission:1.0.1'

วิธีขออนุญาต:

 List<String> permission = new ArrayList<>();
 permission.add(EasyPermissionList.READ_EXTERNAL_STORAGE);
 permission.add(EasyPermissionList.ACCESS_FINE_LOCATION);

 new EasyPermissionInit(MainActivity.this, permission);

หวังว่ามันจะเป็นประโยชน์สำหรับใครบางคน


1

ฉันได้รับคำตอบทั้งหมด แต่ไม่พอใจคำตอบที่ต้องการดังนั้นนี่คือตัวอย่างที่ฉันเขียนและใช้งานได้อย่างสมบูรณ์แม้ผู้ใช้คลิกที่ช่องทำเครื่องหมายDon't ask อีกครั้ง

  1. สร้างวิธีการที่จะถูกเรียกเมื่อคุณต้องการขอสิทธิ์รันไทม์เช่นreadContacts()หรือคุณสามารถมีopenCamera()ดังต่อไปนี้:

    private void readContacts() {
        if (!askContactsPermission()) {
            return;
        } else {
            queryContacts();
        } }

ตอนนี้เราจำเป็นต้องทำaskContactsPermission()คุณยังสามารถตั้งชื่อมันเป็นaskCameraPermission()หรือสิ่งที่ได้รับอนุญาตที่คุณจะถาม

    private boolean askContactsPermission() {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
        return true;
    }
    if (checkSelfPermission(READ_CONTACTS) == PackageManager.PERMISSION_GRANTED) {
        return true;
    }
    if (shouldShowRequestPermissionRationale(READ_CONTACTS)) {
        Snackbar.make(parentLayout, R.string.permission_rationale, Snackbar.LENGTH_INDEFINITE)
                .setAction(android.R.string.ok, new View.OnClickListener() {
                    @Override
                    @TargetApi(Build.VERSION_CODES.M)
                    public void onClick(View v) {
                        requestPermissions(new String[]{READ_CONTACTS}, REQUEST_READ_CONTACTS);
                    }
                }).show();
    } else if (contactPermissionNotGiven) {
        openPermissionSettingDialog();
    } else {
        requestPermissions(new String[]{READ_CONTACTS}, REQUEST_READ_CONTACTS);
        contactPermissionNotGiven = true;

    }
    return false;
}

ก่อนที่จะเขียนฟังก์ชันนี้ให้แน่ใจว่าคุณได้กำหนดตัวแปรอินสแตนซ์ด้านล่างตามที่แสดง:

    private View parentLayout;
    private boolean contactPermissionNotGiven;;


/**
 * Id to identity READ_CONTACTS permission request.
 */
private static final int REQUEST_READ_CONTACTS = 0;

ตอนนี้ขั้นตอนสุดท้ายเพื่อแทนที่onRequestPermissionsResultวิธีดังที่แสดงด้านล่าง:

/**
 * Callback received when a permissions request has been completed.
 */
@RequiresApi(api = Build.VERSION_CODES.M)
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
                                       @NonNull int[] grantResults) {
    if (requestCode == REQUEST_READ_CONTACTS) {
        if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            queryContacts();
        }
    }
}

ที่นี่เราจะทำกับสิทธิ์ RunTime, addon เป็นopenPermissionSettingDialog()เพียงที่เปิดหน้าจอการตั้งค่าหากผู้ใช้ปิดการอนุญาตอย่างถาวรโดยการคลิกไม่ต้องถามอีกครั้งช่องทำเครื่องหมาย ด้านล่างเป็นวิธีการ:

    private void openPermissionSettingDialog() {
    String message = getString(R.string.message_permission_disabled);
    AlertDialog alertDialog =
            new AlertDialog.Builder(MainActivity.this, AlertDialog.THEME_DEVICE_DEFAULT_LIGHT)
                    .setMessage(message)
                    .setPositiveButton(getString(android.R.string.ok),
                            new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) {
                                    Intent intent = new Intent();
                                    intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                                    Uri uri = Uri.fromParts("package", getPackageName(), null);
                                    intent.setData(uri);
                                    startActivity(intent);
                                    dialog.cancel();
                                }
                            }).show();
    alertDialog.setCanceledOnTouchOutside(true);
}

สิ่งที่เราพลาด 1. การกำหนดสตริงที่ใช้ในstrings.xml

<string name="permission_rationale">"Contacts permissions are needed to display Contacts."</string>
    <string name="message_permission_disabled">You have disabled the permissions permanently,
        To enable the permissions please go to Settings -> Permissions and enable the required Permissions,
        pressing OK you will be navigated to Settings screen</string>

  1. เริ่มต้นparentLayoutตัวแปรภายในonCreateวิธีการ

    parentLayout = findViewById (R.id.content);

  2. กำหนดสิทธิ์ที่จำเป็นใน AndroidManifest.xml

<uses-permission android:name="android.permission.READ_CONTACTS" />

  1. queryContactsวิธีการตามความต้องการหรือได้รับอนุญาตรันไทม์ที่คุณสามารถเรียกวิธีของคุณก่อนที่คุณpermissionเป็นสิ่งที่จำเป็น ในกรณีของฉันฉันใช้ตัวโหลดเพื่อดึงข้อมูลผู้ติดต่อดังแสดงด้านล่าง:

    private void queryContacts() {
    getLoaderManager().initLoader(0, null, this);}

วิธีนี้ใช้งานได้ดีมาก :)


1

หากคุณใช้AndroidX Activity 1.2.0หรือAndroidX Fragment 1.3.0 :

มี API ผลลัพธ์กิจกรรมใหม่ที่คุณสามารถใช้เพื่อขออนุญาต:

val launcher = registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted ->
    if (isGranted) {
        // Permission granted. Do the tasks.
    }
}
launcher.launch(Manifest.permission.ACCESS_FINE_LOCATION)

0
  if (CommonMethod.isNetworkAvailable(MainActivity.this)) {
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                        int permissionCheck = ContextCompat.checkSelfPermission(MainActivity.this,
                                android.Manifest.permission.CAMERA);
                        if (permissionCheck == PackageManager.PERMISSION_GRANTED) {
                            //showing dialog to select image
                            callFacebook();
                            Log.e("permission", "granted MarshMallow");
                        } else {
                            ActivityCompat.requestPermissions(MainActivity.this,
                                    new String[]{android.Manifest.permission.READ_EXTERNAL_STORAGE,
                                            android.Manifest.permission.WRITE_EXTERNAL_STORAGE, android.Manifest.permission.CAMERA}, 1);
                        }
                    } else {
                        Log.e("permission", "Not Required Less than MarshMallow Version");
                        callFacebook();
                    }
                } else {
                    CommonMethod.showAlert("Internet Connectivity Failure", MainActivity.this);
                }

0

คุณสามารถใช้ห้องสมุดของฉัน - NoPermission (เป็นเพียงชั้นเดียว)

compile 'ru.alexbykov:nopermission:1.1.1'

ตัวอย่าง

PermissionHelper permissionHelper = new PermissionHelper(this); //don't use getActivity in fragment!

permissionHelper.check(Manifest.permission.READ_CONTACTS)
                .onSuccess(this::onSuccess)
                .onDenied(this::onDenied)
                .onNeverAskAgain(this::onNeverAskAgain)
                .run();

onRequestPermissionResult:

 @Override
  public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults)
        permissionHelper.onRequestPermissionsResult(requestCode, permissions, grantResults);
   }

ฉันคิดว่า api สะดวกกว่าEasyPermissionsGoogle


0

การอนุญาตรันไทม์ทุกที่ในแอปพลิเคชันนี่คือตัวอย่าง

use dependency
maven { url 'https://jitpack.io' }
dependencies {
implementation 'com.github.irshadsparky:PermissionLib:master-SNAPSHOT'
}

และรหัสโทรเช่นนี้:

PermissionHelper.requestCamera(new PermissionHelper.OnPermissionGrantedListener() {
@Override
public void onPermissionGranted() {

}
});

คุณสามารถหาGithubเพิ่มเติมได้


0

สิทธิ์รันไทม์สร้างรหัสสำเร็จรูปจำนวนมากในกิจกรรมที่มีการเชื่อมโยงอย่างมาก เพื่อลดรหัสและทำให้เป็นเรื่องง่ายคุณสามารถใช้ไลบรารีDexter


0

สิทธิ์ช่วงเวลาใน ANDROID

public void onClick(View view) {
    if (view.getId() == shareButton.getId()) {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
            this.shareLog();
        } else {
            ActivityCompat.requestPermissions(this, new String[] { Manifest.permission.WRITE_EXTERNAL_STORAGE }, LogConstants.PERMISSION_REQ_WRITE_EXTERNAL_STORAGE);
        }
    }
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    if (requestCode == LogConstants.PERMISSION_REQ_WRITE_EXTERNAL_STORAGE) {
        if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            this.shareLog();
        }
    }
}

วิธี OnClick คือการตรวจสอบสิทธิ์การใช้งานจริง

และถ้าการอนุญาตถูก จำกัด ก็จะขออนุญาต

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