অ্যান্ড্রয়েড এম অনুমতি: শো রেকুয়েস্টপেরিশনরেশনাল () ফাংশনের ব্যবহার সম্পর্কে বিভ্রান্ত


148

আমি অ্যান্ড্রয়েড এম এর নতুন অনুমতি মডেল সম্পর্কে অফিসিয়াল ডকটির মধ্য দিয়ে যাচ্ছিলাম এটি shouldShowRequestPermissionRationale()ফাংশন সম্পর্কে কথা বলে যা অ্যাপলটি trueআগে এই অনুমতিটির জন্য অনুরোধ করেছিল এবং ব্যবহারকারী যদি অনুরোধ অস্বীকার করে তবে তা ফিরে আসে । যদি ব্যবহারকারী অতীতে অনুমতি অনুরোধটি প্রত্যাখ্যান করে এবং পুনরায় জিজ্ঞাসা করবেন না বিকল্পটি চয়ন করে, এই পদ্ধতিটি ফিরে আসে false

তবে কীভাবে আমরা নিম্নলিখিত দুটি ক্ষেত্রে পার্থক্য করতে পারি?

কেস 1 : অ্যাপ্লিকেশনটির অনুমতি নেই এবং ব্যবহারকারীর কাছে এর আগে অনুমতি চাওয়া হয়নি। এই ক্ষেত্রে, শো রেকোয়েস্টপিরমিশনেশনেশন () মিথ্যা ফিরে আসবে কারণ আমরা ব্যবহারকারীকে এই প্রথম জিজ্ঞাসা করছি।

কেস 2 : ব্যবহারকারীর অনুমতি অস্বীকার করেছে এবং "আবার জিজ্ঞাসা করবেন না" বাছাই করেছে, এক্ষেত্রেও শো-রিকোয়েস্টপিরেশনরেশনাল () মিথ্যা প্রত্যাবর্তন করবে।

আমি কেস ২ তে অ্যাপটির সেটিংস পৃষ্ঠায় ব্যবহারকারীকে প্রেরণ করতে চাই? এই দুটি ক্ষেত্রে আমি কীভাবে পার্থক্য করব?


1
গৃহীত উত্তর ভাল। ঠিক তেমন বিকল্প হিসাবে আপনি অ্যাপটি এর আগে অনুমতিটির জন্য অনুরোধ করেছে কিনা তা জানতে একটি ভাগ করা প্রিফও ব্যবহার করতে পারেন। এটি অন্য কারও পরিস্থিতির জন্য আরও প্রযোজ্য ক্ষেত্রে সেখানে ফেলে দেওয়া।
রকিন

4
এছাড়াও একটি কেস 3 রয়েছে: ব্যবহারকারীর কাছে অনুমতি চাওয়া হয়েছে এবং অনুমতি দেওয়া হয়েছে / অস্বীকার করা হয়েছে, তবে "প্রতিটি সময় জিজ্ঞাসা করুন" এ ফিরে যাওয়ার জন্য অনুমতি সেটিংস ব্যবহার করেছেন। পরীক্ষাগুলি shouldShowRequestPermissionRationale()এই ক্ষেত্রে মিথ্যা প্রত্যাবর্তন করে, যা "আমি আগে জিজ্ঞাসা করেছি" পতাকাটিতে নির্ভর করে যে কোনও কোডকে আঘাত করবে hurt
লোগান পিকআপ

এখানে একটি গুগল নমুনা রয়েছে permissionsযা অ্যান্ড্রয়েডের সেরা অনুশীলনগুলি দেখায় । github.com/android/permission-sams
itabdullah

@itabdullah গুগলের নমুনা কোডটি নিষ্ক্রিয় কারণ তারা "ব্যবহারকারী শেষবারের মতো অনুমতিটি প্রত্যাখ্যান করেছিলেন" এর খুব সম্ভবত ব্যবহারের ঘড়ি বিবেচনা করেনি। : - / সাধারণ
কোথাও কেউ

উত্তর:


172

এম প্রিভিউ 1 এর পরে, যদি প্রথমবারের মতো ডায়ালগটি প্রদর্শিত হয় , আবার কখনও জিজ্ঞাসা করবেন না চেকবক্স।

যদি ব্যবহারকারী অনুমতি অনুরোধ অস্বীকার করে, অনুমতি ডায়ালগটিতে আবার কখনও জিজ্ঞাসা করবেন না চেকবক্সটি দ্বিতীয়বার অনুমতি চাওয়ার অনুরোধ জানানো হবে।

সুতরাং যুক্তিটি এমন হওয়া উচিত:

  1. অনুমতির অনুরোধ:

    if (ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(context, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_CODE);
    } else {
        //Do the stuff that requires permission...
    }
    
  2. অনুমতি অস্বীকার করা হয়েছে বা এতে মঞ্জুর করা হয়েছে কিনা তা পরীক্ষা করুন onRequestPermissionsResult

    যদি অনুমতিটি আগে অস্বীকার করা হত, এবার অনুমতি ডায়ালগটিতে আবার কখনও জিজ্ঞাসা করবেন না চেকবক্স হবে।

    shouldShowRequestPermissionRationaleব্যবহারকারী চেক করেছে কিনা তা দেখতে কল করুন আবার কখনও জিজ্ঞাসা করবেন নাshouldShowRequestPermissionRationaleপদ্ধতিটি কেবল তখনই মিথ্যা প্রত্যাবর্তন করে যদি ব্যবহারকারী নির্বাচিত হন আবার কখনও জিজ্ঞাসা করবেন না বা ডিভাইস নীতি অ্যাপ্লিকেশনটিকে সেই অনুমতি থেকে নিষিদ্ধ করেছে:

    if (grantResults.length > 0){
        if(grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            //Do the stuff that requires permission...
        }else if (grantResults[0] == PackageManager.PERMISSION_DENIED){
            // Should we show an explanation?
            if (ActivityCompat.shouldShowRequestPermissionRationale(context, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
                //Show permission explanation dialog...
            }else{
                //Never ask again selected, or device policy prohibits the app from having that permission.
                //So, disable that feature, or fall back to another situation...
            }
        }
    }
    

সুতরাং, কোনও ব্যবহারকারী চেক করেছে কিনা তা আপনাকে আবার ট্র্যাক করতে হবে না আবার কখনও জিজ্ঞাসা করুন বা না করুন।


49
স্পষ্টকরণের একটি বিষয়, ব্যবহারকারীর কাছে অনুমতি চেয়ে জিজ্ঞাসা না করা হলে (যেমন প্রথমবার অ্যাপ্লিকেশনটি প্রথমবার চালিত হয়) উইন্ডোজ শো-রেকুয়েস্টপিরমিরিশনেশন () উইলও মিথ্যা প্রত্যাবর্তন করবে। যদি আপনি প্রদত্ত উদাহরণের যুক্তি অনুসরণ করেন তবে আপনি সেই ক্ষেত্রে দৌড়াবেন না। তবে 2 বছরের কম বয়সী শব্দটি কিছুটা বিভ্রান্তিকর।
বেন

15
আমি নিশ্চিত নই, এটি ত্রুটিযুক্ত বলে মনে হচ্ছে। এটি প্রথমবার ব্যবহারকারীর কাছে জিজ্ঞাসা করা হয় কিনা তা আমরা কীভাবে জানতে পারি? ব্যবহারকারীকে জিজ্ঞাসা করা হয়েছে কিনা তা আমাকে খুঁজে বের করতে হবে এবং যদি সে তা করে থাকে তবে আমাকে যুক্তিটি বিপরীত করতে হবে। আমার কাছে কোন লাভ করে না।
ড্যানিয়েল এফ

4
আমার মনে হয় এটা লক্ষ করেন, যেখানে আপনি ক্ষণস্থায়ী হয় মূল্য contextমধ্যে ActivityCompat.shouldShowRequestPermissionRationale(...)পরামিতি টাইপ আসলে Activity। আপনি সব প্রভাবিত করতে পারে না আমার ক্ষেত্রে এটি।
aProperFox

7
এই অ্যান্ড্রয়েড যুক্তি এত মূর্খ! shouldকলব্যাকে কল করতে এবং এনভিএম-এ এর পাল্টা মানটি সংরক্ষণ করার জন্য আমাকে জোর করে, পরের বার অ্যাপটি খোলার পরে আমাকে অনুরোধটি আবার প্রম্পট করতে হবে কিনা! ... বাহ (ফেসপাম) ... স্ট্যাটাস অ্যানুমুলেশন ফিরিয়ে দেওয়া শুধুমাত্র একটি কল করা কি খুব কঠিন ছিল ??
শকওভার

2
আমি গুগল দ্বারা এটি একটি বড় ব্যর্থ মনে হয়। অফিশিয়াল ডকুমেন্টেশনে বলা হয়েছে যে অনুমতিগুলি পরীক্ষা করার আগে (অবশ্যই ডেভেলপার.অ্যান্ড্রয়েড / ট্রেনিং / স্পেসিফিকেশন / পুনর্নির্মাণ# এক্সপ্লেইন দেখুন) শো-রেক্যুয়েস্টপিরমিরিশনেশন () কে ফোন করা উচিত , তবে স্ট্যাকওভারফ্লোতে সমস্ত উত্তর এটিকে "RequestPermissionResult () এ কল করে কিনা তা পৃথক করার জন্য ব্যবহারকারী "আর কখনও জিজ্ঞাসা করবেন না" ক্লিক করুন।
মিলো আর্নিলোভস্কে

22

আমারও একই সমস্যা ছিল এবং আমি এটি বের করে ফেললাম। জীবনকে আরও সহজ করে তোলার জন্য, রানটাইম অনুমতিগুলি হ্যান্ডেল করার জন্য আমি একটি ব্যবহারের ক্লাস লিখেছিলাম।

public class PermissionUtil {
    /*
    * Check if version is marshmallow and above.
    * Used in deciding to ask runtime permission
    * */
    public static boolean shouldAskPermission() {
        return (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M);
    }
private static boolean shouldAskPermission(Context context, String permission){
        if (shouldAskPermission()) {
            int permissionResult = ActivityCompat.checkSelfPermission(context, permission);
            if (permissionResult != PackageManager.PERMISSION_GRANTED) {
                return true;
            }
        }
        return false;
    }
public static void checkPermission(Context context, String permission, PermissionAskListener listener){
/*
        * If permission is not granted
        * */
        if (shouldAskPermission(context, permission)){
/*
            * If permission denied previously
            * */
            if (((Activity) context).shouldShowRequestPermissionRationale(permission)) {
                listener.onPermissionPreviouslyDenied();
            } else {
                /*
                * Permission denied or first time requested
                * */
if (PreferencesUtil.isFirstTimeAskingPermission(context, permission)) {
                    PreferencesUtil.firstTimeAskingPermission(context, permission, false);
                    listener.onPermissionAsk();
                } else {
                    /*
                    * Handle the feature without permission or ask user to manually allow permission
                    * */
                    listener.onPermissionDisabled();
                }
            }
        } else {
            listener.onPermissionGranted();
        }
    }
/*
    * Callback on various cases on checking permission
    *
    * 1.  Below M, runtime permission not needed. In that case onPermissionGranted() would be called.
    *     If permission is already granted, onPermissionGranted() would be called.
    *
    * 2.  Above M, if the permission is being asked first time onPermissionAsk() would be called.
    *
    * 3.  Above M, if the permission is previously asked but not granted, onPermissionPreviouslyDenied()
    *     would be called.
    *
    * 4.  Above M, if the permission is disabled by device policy or the user checked "Never ask again"
    *     check box on previous request permission, onPermissionDisabled() would be called.
    * */
    public interface PermissionAskListener {
/*
        * Callback to ask permission
        * */
        void onPermissionAsk();
/*
        * Callback on permission denied
        * */
        void onPermissionPreviouslyDenied();
/*
        * Callback on permission "Never show again" checked and denied
        * */
        void onPermissionDisabled();
/*
        * Callback on permission granted
        * */
        void onPermissionGranted();
    }
}

এবং পছন্দসই পদ্ধতিগুলি নিম্নরূপ।

public static void firstTimeAskingPermission(Context context, String permission, boolean isFirstTime){
SharedPreferences sharedPreference = context.getSharedPreferences(PREFS_FILE_NAME, MODE_PRIVATE;
 sharedPreference.edit().putBoolean(permission, isFirstTime).apply();
 }
public static boolean isFirstTimeAskingPermission(Context context, String permission){
return context.getSharedPreferences(PREFS_FILE_NAME, MODE_PRIVATE).getBoolean(permission, true);
}

এখন, আপনার প্রয়োজন কেবল সঠিক যুক্তি সহ পদ্ধতি চেকপিরমিশন ব্যবহার করা ।

এখানে একটি উদাহরণ,

PermissionUtil.checkPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE,
                    new PermissionUtil.PermissionAskListener() {
                        @Override
                        public void onPermissionAsk() {
                            ActivityCompat.requestPermissions(
                                    thisActivity,
              new String[]{Manifest.permission.READ_CONTACTS},
                            REQUEST_EXTERNAL_STORAGE
                            );
                        }
@Override
                        public void onPermissionPreviouslyDenied() {
                       //show a dialog explaining permission and then request permission
                        }
@Override
                        public void onPermissionDisabled() {
Toast.makeText(context, "Permission Disabled.", Toast.LENGTH_SHORT).show();
                        }
@Override
                        public void onPermissionGranted() {
                            readContacts();
                        }
                    });

কেস 1: অ্যাপ্লিকেশনটির অনুমতি নেই এবং ব্যবহারকারীর কাছে এর আগে অনুমতি চাওয়া হয়নি। এই ক্ষেত্রে, শো রেকোয়েস্টপিরমিশনেশনেশন () মিথ্যা ফিরে আসবে কারণ আমরা ব্যবহারকারীকে এই প্রথম জিজ্ঞাসা করছি।

কেস 2: ব্যবহারকারীর অনুমতি অস্বীকার করেছে এবং "আবার জিজ্ঞাসা করবেন না" বাছাই করেছে, এই ক্ষেত্রেও শো-রিকোয়েস্টপিরেশনরেশনাল () মিথ্যা প্রত্যাবর্তন করবে।

আমি কেস ২ তে অ্যাপটির সেটিংস পৃষ্ঠায় ব্যবহারকারীকে প্রেরণ করতে চাই? এই দুটি ক্ষেত্রে আমি কীভাবে পার্থক্য করব?

আপনি কেস 1 এর জন্য onPermissionAsk এ কলব্যাক পাবেন , এবং কেস 2 এর জন্য onPermissionDis अक्षम

শুভ কোডিং :)


দুর্দান্ত ব্যাখ্যা ভাই। আপনার ঠিক একই পদ্ধতি অনুসরণ করেছে। :)
সুমিত ঝা

এই কার্যকলাপের জন্য আমি কী পূরণ করব? public void onPermissionAsk() { ActivityCompat.requestPermissions( thisActivity, ...
মার্ডিমার

@ মার্ডাইমার thisActivityছাড়া আর কিছুই নয় YourActivity.this
মুথুরাজ

1
কীভাবে একাধিক অনুমতি পরিচালনা করতে হবে এবং এই কোডটি খণ্ডের মধ্যে কীভাবে সংহত করা যায়।
তাইমুর

আপনি কোন ধরনের contextব্যবহার করছেন? shouldShowRequestPermissionRationale(permission)মধ্যে নেই android.content.Context। এটি ক্রিয়াকলাপে রয়েছে
হিলিকাস

8

হালনাগাদ

আমি বিশ্বাস করি যে নীচের ক্যানির উত্তরটি সঠিক উত্তর যা অনুসরণ করা উচিত। নিশ্চিতরূপে জানার একমাত্র উপায় হ'ল শো-পারমিশনআরেশনাল ব্যবহার করে অন-রিকোয়েস্টপিরমিশন রিসাল্ট কলব্যাকটিতে এটি যাচাই করা।

==

আমার মূল উত্তর:

আমি যে একমাত্র পথটি খুঁজে পেয়েছি তা হ'ল এটিই প্রথমবার কিনা (যেমন ভাগ করে নেওয়া পছন্দগুলি ব্যবহার করে) আপনার নিজের নজর রাখা। এটি যদি প্রথমবার না হয় তবে shouldShowRequestPermissionRationale()আলাদা করার জন্য ব্যবহার করুন।

আরও দেখুন: অ্যান্ড্রয়েড এম - রানটাইম অনুমতি চেক করুন - ব্যবহারকারী "আবার কখনও জিজ্ঞাসা করবেন না" চেক করেছে কিনা তা কীভাবে নির্ধারণ করবেন?


1
হ্যাঁ এমনকি আমিও একমত যে ক্যানসির পদ্ধতিটি অনুসরণ করা উচিত। আমি এটি গ্রহণযোগ্য উত্তর হিসাবে চিহ্নিত করতে যাচ্ছি।
akshayt23

6

আমি এটি যেভাবে বুঝতে পারি, শো-রেকুয়েস্টপিরমিশনেশন () হুডের অধীনে বেশ কয়েকটি ব্যবহারের কেস চালায় এবং অনুরোধকৃত অনুমতিগুলির বিষয়ে কোনও ব্যাখ্যা প্রদর্শন করবে কিনা তা অ্যাপ্লিকেশনকে জানিয়ে দেয়।

রান টাইম অনুমতিগুলির পিছনে ধারণাটি হ'ল বেশিরভাগ সময়, ব্যবহারকারী অনুমতি অনুরোধের জন্য হ্যাঁ বলবেন। এইভাবে ব্যবহারকারীকে কেবল একটি ক্লিক করতে হবে। অবশ্যই অনুরোধটি সঠিক প্রসঙ্গে ব্যবহার করা উচিত - অর্থাত্ "ক্যামেরা" বোতামটি চাপলে ক্যামেরার অনুমতি চাওয়া হবে।

যদি ব্যবহারকারী অনুরোধটিকে অস্বীকার করে তবে কিছু সময় পরে আবার "ক্যামেরা" বোতাম টিপলে, শো-রেক্যুয়েস্টপিরমিশনেশন () সত্য হওয়া উচিত, সুতরাং অ্যাপ্লিকেশনটি কেন অনুরোধ করা হয়েছে এবং কেন অ্যাপ্লিকেশনটি করবে না তা কিছু অর্থপূর্ণ ব্যাখ্যা দেখাতে পারে এটি ছাড়া সঠিকভাবে কাজ। সাধারণত আপনি সেই ডায়ালগ উইন্ডোতে আবার অস্বীকার করতে / পরে সিদ্ধান্ত নেওয়ার জন্য একটি বোতাম এবং অনুমতিগুলি দেওয়ার জন্য একটি বোতাম দেখাতেন। যুক্তিযুক্ত কথোপকথনের গ্রান্ট অনুমতি বোতামের আবার অনুমতি অনুরোধ শুরু করা উচিত। এবার ব্যবহারকারীর একটি "আবার কখনও দেখাবে না" চেকবক্সও থাকবে। যদি সে এটিটি বেছে নেওয়ার সিদ্ধান্ত নেয় এবং অনুমতিটি আবার অস্বীকার করে তবে এটি অ্যান্ড্রয়েড সিস্টেমকে জানিয়ে দেবে যে ব্যবহারকারী এবং অ্যাপ একই পৃষ্ঠায় নেই। এই ক্রিয়াকলাপের দুটি পরিণতি হবে - শো -রেকুয়েস্টপিরমিশনেশনালেশন () সর্বদা মিথ্যা ফিরিয়ে দেবে,

তবে আরও একটি সম্ভাব্য দৃশ্যাবলীও রয়েছে যেখানে অনিক্যাস্টপিয়ারিশনস রিসাল্ট ব্যবহার করা যেতে পারে। উদাহরণস্বরূপ কিছু ডিভাইসের একটি ডিভাইস নীতি থাকতে পারে যা ক্যামেরাটি অক্ষম করে (সিআইএ, ডিআরপিএ ইত্যাদির জন্য কাজ করছে)। এই ডিভাইসগুলিতে, onRequestPermissionResult সর্বদা মিথ্যা প্রত্যাবর্তন করবে এবং অনুরোধের অনুমতি () পদ্ধতিটি নিঃশব্দে অনুরোধটিকে অস্বীকার করবে।

অ্যান্ড্রয়েড কাঠামোর একটি প্রোডাক্ট ম্যানেজার - বেন পয়েজ-এর সাথে পডকাস্ট শুনে আমি এটি সংগ্রহ করেছি।
http://androidbackstage.blogspot.jp/2015/08/episode-33-permission-mission.html


6

কেবল অন্য বিকল্পটি পোস্ট করুন, যদি কারও মনে হয়। আপনি ইজিপার্মিকেশনগুলি ব্যবহার করতে পারেন যা গুগল নিজেই সরবরাহ করেছিল, যেমন, "অ্যান্ড্রয়েড এম সিস্টেমের অনুমতিগুলি সরল করুন " to

তাহলে আপনাকে shouldShowRequestPermissionRationaleসরাসরি পরিচালনা করতে হবে না ।


কেন আমি এই প্রকল্পটি অগ্রণীভাবে দেখিনি :)
ভ্লাদ

ইজিপার্মিশনের সমস্যা প্রায় একই রকম থাকে same permissionPermanentlyDeniedঅভ্যন্তরীণভাবে কেবল কল shouldShowPermissionsRationaleএবং রিটার্ন জিজ্ঞাসা trueযখন ব্যবহারকারীর কাছে অনুমতি প্রদানের জন্য কখনও অনুরোধ করা হয়নি।
hgoebl

4

যদি কেউ কোটলিন সমাধানে আগ্রহী হন, আমি @ মুথুরাজকে কোটলিনে থাকার জবাবটি রিফেক্ট করেছিলাম। শ্রোতার পরিবর্তে এটি একটি সমাপ্তি ব্লককে কিছুটা আধুনিকীকরণ করুন।

PermissionUtil

object PermissionUtil {
    private val PREFS_FILE_NAME = "preference"

    fun firstTimeAskingPermission(context: Context, permission: String, isFirstTime: Boolean) {
        val sharedPreference = context.getSharedPreferences(PREFS_FILE_NAME, MODE_PRIVATE)
        sharedPreference.preferences.edit().putBoolean(permission,
                isFirstTime).apply()
    }

    fun isFirstTimeAskingPermission(context: Context, permission: String): Boolean {
        val sharedPreference = context.getSharedPreferences(PREFS_FILE_NAME, MODE_PRIVATE)
        return sharedPreference.preferences.getBoolean(permission,
                true)
    }
}

PermissionHandler

enum class CheckPermissionResult {
    PermissionAsk,
    PermissionPreviouslyDenied,
    PermissionDisabled,
    PermissionGranted
}

typealias PermissionCheckCompletion = (CheckPermissionResult) -> Unit


object PermissionHandler {

    private fun shouldAskPermission(context: Context, permission: String): Boolean {
        return ContextCompat.checkSelfPermission(context,
                permission) != PackageManager.PERMISSION_GRANTED
    }

    fun checkPermission(context: Context, permission: String, completion: PermissionCheckCompletion) {
        // If permission is not granted
        if (shouldAskPermission(context, permission)) {
            //If permission denied previously
            if ((context as Activity).shouldShowRequestPermissionRationale(permission)) {
                completion(CheckPermissionResult.PermissionPreviouslyDenied)
            } else {
                // Permission denied or first time requested
                if (PermissionUtil.isFirstTimeAskingPermission(context,
                                permission)) {
                    PermissionUtil.firstTimeAskingPermission(context,
                            permission,
                            false)
                    completion(CheckPermissionResult.PermissionAsk)
                } else {
                    // Handle the feature without permission or ask user to manually allow permission
                    completion(CheckPermissionResult.PermissionDisabled)
                }
            }
        } else {
            completion(CheckPermissionResult.PermissionGranted)
        }
    }
}

বাস্তবায়ন

PermissionHandler.checkPermission(activity,
                    Manifest.permission.CAMERA) { result ->
                when (result) {
                    CheckPermissionResult.PermissionGranted -> {
                        // openCamera()
                    }
                    CheckPermissionResult.PermissionDisabled -> {
                        // displayAlert(noPermissionAlert)
                    }
                    CheckPermissionResult.PermissionAsk -> {
                        // requestCameraPermissions()
                    }
                    CheckPermissionResult.PermissionPreviouslyDenied -> {
                        // displayAlert(permissionRequestAlert)
                    }
                }
            }

3

এই বাস্তবায়ন পরীক্ষা করে দেখুন। আমার জন্য বেশ ভাল কাজ করছে। মূলত আপনি চেকপিরমিশন () পদ্ধতিতে অনুমতিগুলির তালিকা পাস করার অনুমতিগুলি পরীক্ষা করে দেখুন। আপনি অনুমতি অনুরোধের ফলাফলটি onRequestPermissionResult () এ পরীক্ষা করে দেখুন। ব্যবহারকারী "আর কখনও জিজ্ঞাসা করবেন না" নির্বাচন না করে বাস্তবায়ন আপনাকে উভয় ক্ষেত্রেই সম্বোধন করতে দেয়। এই বাস্তবায়নে, সে ক্ষেত্রে "আবার কখনও জিজ্ঞাসা করবেন না" বাছাইয়ের ক্ষেত্রে ডায়ালগের কাছে তাকে অ্যাপ সেটিংস ক্রিয়াকলাপে নিয়ে যাওয়ার বিকল্প রয়েছে option

এই সমস্ত কোডটি আমার খণ্ডের মধ্যে রয়েছে। আমি ভেবেছিলাম পারমিশন ম্যানেজারের মতো এটি করার জন্য একটি বিশেষায়িত শ্রেণি তৈরি করা আরও ভাল তবে আমি এটি সম্পর্কে নিশ্চিত নই।

/**
     * responsible for checking if permissions are granted. In case permissions are not granted, the user will be requested and the method returns false. In case we have all permissions, the method return true.
     * The response of the request for the permissions is going to be handled in the onRequestPermissionsResult() method
     * @param permissions list of permissions to be checked if are granted onRequestPermissionsResult().
     * @param requestCode request code to identify this request in
     * @return true case we already have all permissions. false in case we had to prompt the user for it.
     */
    private boolean checkPermissions(List<String> permissions, int requestCode) {
        List<String> permissionsNotGranted = new ArrayList<>();
        for (String permission : permissions) {
            if (ContextCompat.checkSelfPermission(getActivity(), permission) != PackageManager.PERMISSION_GRANTED)
                permissionsNotGranted.add(permission);
        }

        //If there is any permission we don't have (it's going to be in permissionsNotGranted List) , we need to request.
        if (!permissionsNotGranted.isEmpty()) {
            requestPermissions(permissionsNotGranted.toArray(new String[permissionsNotGranted.size()]), requestCode);
            return false;
        }
        return true;
    }

    /**
     * called after permissions are requested to the user. This is called always, either
     * has granted or not the permissions.
     * @param requestCode  int code used to identify the request made. Was passed as parameter in the
     *                     requestPermissions() call.
     * @param permissions  Array containing the permissions asked to the user.
     * @param grantResults Array containing the results of the permissions requested to the user.
     */
    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        switch (requestCode) {
            case YOUR_REQUEST_CODE: {
                boolean anyPermissionDenied = false;
                boolean neverAskAgainSelected = false;
                // Check if any permission asked has been denied
                for (int i = 0; i < grantResults.length; i++) {
                    if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
                        anyPermissionDenied = true;
                        //check if user select "never ask again" when denying any permission
                        if (!shouldShowRequestPermissionRationale(permissions[i])) {
                            neverAskAgainSelected = true;
                        }
                    }
                }
                if (!anyPermissionDenied) {
                    // All Permissions asked were granted! Yey!
                    // DO YOUR STUFF
                } else {
                    // the user has just denied one or all of the permissions
                    // use this message to explain why he needs to grant these permissions in order to proceed
                    String message = "";
                    DialogInterface.OnClickListener listener = null;
                    if (neverAskAgainSelected) {
                        //This message is displayed after the user has checked never ask again checkbox.
                        message = getString(R.string.permission_denied_never_ask_again_dialog_message);
                        listener = new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                //this will be executed if User clicks OK button. This is gonna take the user to the App Settings
                                startAppSettingsConfigActivity();
                            }
                        };
                    } else {
                        //This message is displayed while the user hasn't checked never ask again checkbox.
                        message = getString(R.string.permission_denied_dialog_message);
                    }
                    new AlertDialog.Builder(getActivity(), R.style.AlertDialogTheme)
                            .setMessage(message)
                            .setPositiveButton(getString(R.string.label_Ok), listener)
                            .setNegativeButton(getString(R.string.label_cancel), null)
                            .create()
                            .show();
                }
            }
            break;
            default:
                super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }

    /**
     * start the App Settings Activity so that the user can change
     * settings related to the application such as permissions.
     */
    private void startAppSettingsConfigActivity() {
        final Intent i = new Intent();
        i.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
        i.addCategory(Intent.CATEGORY_DEFAULT);
        i.setData(Uri.parse("package:" + getActivity().getPackageName()));
        i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        i.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
        i.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
        getActivity().startActivity(i);
    }

2

কারও জন্য উপকারী হতে পারে: -

আমি যেটা লক্ষ্য করেছি তা হ'ল, আমরা যদি অন-রিকুয়েস্টপিয়ারেশনস রেজাল্ট () কলব্যাক পদ্ধতিতে শো-রেকুয়েস্টপিরমিরিশনেশন () পতাকাটি পরীক্ষা করি, এটি কেবলমাত্র দুটি স্থিতি দেখায়।

রাজ্য 1: -প্রসূত সত্য: - যে কোনও সময় ব্যবহারকারী অনুমতিগুলি অস্বীকার করে ক্লিক করুন (প্রথম বার সহ))

রাজ্য 2: -প্রার্থনা মিথ্যা: - ব্যবহারকারী যদি "আর কখনও জিজ্ঞাসা করেন না" নির্বাচন করে।

বিস্তারিত কাজের উদাহরণের জন্য লিঙ্ক


6
এটি প্রথমবারের জন্য মিথ্যা ফিরিয়ে দেয় । সত্য নয়
জেএম

হ্যাঁ, আমি এটিই উল্লেখ করেছি, আপনি যদি অনিয়ন্ত্রনপেরিশন রিসাল্ট () কলব্যাক পদ্ধতিতে পতাকাটি পরীক্ষা করেন তবে এটির দুটি রাজ্য থাকবে বিশেষত এই কলব্যাকে।
নিকস

2
দুর্ভাগ্যক্রমে, শো শো রেকুয়েস্টপিরমিশনেশন সর্বদা মিথ্যা ফিরিয়ে দেয় - ব্যবহারকারী যদি অনুমতি অস্বীকার করেন বা না করেন তা নির্বিশেষে।
ইগোরগানাপলস্কি

1

আমরা কি এইভাবে এটি করতে পারি?

@Retention(RetentionPolicy.SOURCE)
@IntDef({GRANTED, DENIED, NEVER})
public @interface PermissionStatus {
}

public static final int GRANTED = 0;
public static final int DENIED = 1;
public static final int NEVER = 2;

@PermissionStatus
public static int getPermissionStatus(Activity activity, String permission) {
    if (ActivityCompat.shouldShowRequestPermissionRationale(activity, permission)) {
        return DENIED;
    } else {
        if (ActivityCompat.checkSelfPermission(activity, permission) == PackageManager.PERMISSION_GRANTED) {
            return GRANTED;
        } else {
            return NEVER;
        }
    }
}

দুর্ভাগ্যক্রমে, এই কোডটি এমন পরিস্থিতির মধ্যে পার্থক্য করে না যেখানে অনুমতিটির আগে কখনও অনুরোধ করা হয়নি এবং যেখানে "আর কখনও অনুরোধ করবেন না" পরীক্ষা করা হয়েছিল।
বেন

অনুমতি দেওয়া হয়েছে কিনা তা পরীক্ষা করতে আপনার এই + অনুমতি সহায়ক শ্রেণীর সংমিশ্রণটি ব্যবহার করা উচিত।
ডাঃ এএনড্রো

0

shouldShowRequestPermissionRationale চেকবাক্স ছাড়াই ব্যবহারকারীরা অস্বীকার করার পরে বিশেষ অনুমতির জন্য সর্বদা সত্য ফিরিয়ে দেয়

আমরা মিথ্যা মান আগ্রহী

সুতরাং ভুয়া মান সহ 3 টি কেস হারিয়ে গেছে :

1. আগে এই জাতীয় কোনও পদক্ষেপ ছিল না এবং এখন ব্যবহারকারী সম্মত বা অস্বীকার করার সিদ্ধান্ত নেন।

কেবলমাত্র পছন্দ সংজ্ঞায়িত ASKED_PERMISSION_*যা এখন বিদ্যমান নেই এবং হবে সত্য মধ্যে onRequestPermissionsResultউপর এটি কোনো ক্ষেত্রে শুরু একমত বা অস্বীকার

সুতরাং এই পছন্দটি বিদ্যমান না থাকলে চেক করার কোনও কারণ নেইshouldShowRequestPermissionRationale

২. ব্যবহারকারী ক্লিক করে সম্মত হন।

সহজভাবে করুন:

checkCallingOrSelfPermission(permission) == PackageManager.PERMISSION_GRANTED

যা সত্য ফিরে আসবে এবং চেক করার কোনও কারণ নেইshouldShowRequestPermissionRationale

৩. ব্যবহারকারী চেকবক্সের সাথে অস্বীকার ক্লিক করেছেন (দ্বিতীয় বা আরও বেশি সময় জিজ্ঞাসা করা হয়েছে)

এটা TIME এ কাজ করার জন্য shouldShowRequestPermissionRationaleযা ফিরে আসবে মিথ্যা

(অগ্রাধিকার বিদ্যমান এবং আমাদের অনুমতি নেই)


0

এই কোডটি ব্যবহারকারীকে রানটাইম চলাকালীন অনুমতি চাইতে বলেছে, যদি ব্যবহারকারী অনুমতি দেয় তবে এটি ফলাফল পদ্ধতি কার্যকর করে, যদি ব্যবহারকারী অস্বীকার করে তবে এটি ব্যবহারকারীকে অস্বীকার করার সাথে বৈষম্য নিয়ে আবার জিজ্ঞাসা করে (এটি নির্দেশাবলীর সাথে আবার জিজ্ঞাসা করে), তবে ব্যবহারকারী যদি আর কখনও জিজ্ঞাসা না করেন তবে। এটি আর কখনও জিজ্ঞাসা না করে, নির্দেশাবলীর সাথে ওপেন সেটিংস বিকল্প প্রদর্শন করে les

public String storagePermissions = Manifest.permission.READ_EXTERNAL_STORAGE;   
private static final int REQUEST_ACCESS =101;  

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
      if(checkSelfPermission(storagePermissions)== PackageManager.PERMISSION_GRANTED){
          result();    // result  is your block of code 
      }else {
          requestPermissions(new String[]{storagePermissions},REQUEST_ACCESS);
      }

    }
    else{
        result();    //so if user is lower than api verison M, no permission is requested
    } 

}

 private void showMessageOKCancel(String message, DialogInterface.OnClickListener okListener) {
    new AlertDialog.Builder(MainActivity.this)
            .setMessage(message)
            .setTitle("Hi User..")
            .setPositiveButton("Ok", okListener)
            .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {        //idea calling showMessage funtion again
                    Snackbar mySnackbar = Snackbar.make( findViewById(R.id.coordinatorlayout),"You Press Cancel.. ", Snackbar.LENGTH_INDEFINITE);
                    mySnackbar.setAction("Exit", new cancelButton());
                    mySnackbar.show();

                }
            })
            .create()
            .show();
}


private void result(){
          //your code
}

    @RequiresApi(api = Build.VERSION_CODES.M)
public class NeverAskAgain implements View.OnClickListener{
    @Override
    public void onClick(View view)
    {
        goToSettings();
    }
}
@RequiresApi(api = Build.VERSION_CODES.M)
private void goToSettings() {
    Intent myAppSettings = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, Uri.parse("package:" + getPackageName()));
    finish();
    myAppSettings.addCategory(Intent.CATEGORY_DEFAULT);
    myAppSettings.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    startActivityForResult(myAppSettings, REQUEST_APP_SETTINGS);
}
public class cancelButton implements View.OnClickListener{
    @Override
    public void onClick(View view){
        Toast.makeText(MainActivity.this,"To use this app , you must grant storage permission",Toast.LENGTH_SHORT);
        finish();
    }
    }


 @Override
@RequiresApi(api = Build.VERSION_CODES.M)
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode,permissions,grantResults);

    switch(requestCode) {
        case REQUEST_ACCESS:
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    // permission is granted
                    result();
                    break;
                }
                else if (!shouldShowRequestPermissionRationale(permissions[0])){
                    showMessageOKCancel("You choose Never Ask Again,option",
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        Snackbar mySnackbar = Snackbar.make(findViewById(R.id.coordinatorlayout), "Permission=>Storage=>On", Snackbar.LENGTH_INDEFINITE);
                        mySnackbar.setAction("Settings", new NeverAskAgain());
                        mySnackbar.show();
                    }
                     });
                    break;
                }
                else {
                    showMessageOKCancel("You Denid permission Request..",
                    new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            requestPermissions(new String[]{storagePermissions}, REQUEST_ACCESS);
                        }
                    });
                    break;
                }
        }
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.