Запрос разрешений во время выполнения, Android M+

Во-первых, я знаю, что это повторяющийся вопрос, но я просмотрел ответы на другие подобные вопросы и не смог добиться успеха ни с одним из этих решений.

Я разработал приложение, которое отлично работает на моем тестовом устройстве, которым является Samsung S4 под управлением Android L (5.0.1), однако я хотел бы, чтобы это приложение также работало на более новых версиях Android.

Я понимаю, что запрашиваемые разрешения изменились для Android M+, поэтому их нужно запрашивать во время выполнения, но когда я пытаюсь реализовать это, диалоговое окно никогда не появляется, и, следовательно, требуемые разрешения никогда не запрашиваются.

Я запрашиваю разрешение ACCESS_FINE_LOCATION.

Вот соответствующий код из моего файла манифеста:

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

Где я прошу разрешения, если оно еще не предоставлено:

if (ActivityCompat.checkSelfPermission(MapsActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {

    startGeofenceMonitoring();

} else {
    askForPermission(android.Manifest.permission.ACCESS_FINE_LOCATION,LOCATION);
}

Функция askForPermission (слегка измененная из примера Google):

private void askForPermission(String permission, Integer requestCode) {
    if (ContextCompat.checkSelfPermission(MapsActivity.this, permission) != PackageManager.PERMISSION_GRANTED) {

        // Should we show an explanation?
        if (ActivityCompat.shouldShowRequestPermissionRationale(MapsActivity.this, permission)) {

            //This is called if user has denied the permission before
            //In this case I am just asking the permission again
            ActivityCompat.requestPermissions(MapsActivity.this, new String[]{permission}, requestCode);

        } else {

            Log.d(TAG, "askForPermission: " + permission);

            ActivityCompat.requestPermissions(MapsActivity.this, new String[]{permission}, requestCode);
        }
    } else {
        Toast.makeText(this, "" + permission + " is already granted.", Toast.LENGTH_SHORT).show();
    }
}

И функция onRequestPermissionsResult:

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

    Log.d(TAG, "onRequestPermissionsResult: " + requestCode);

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

                    Log.d(TAG, "onRequestPermissionsResult: request");

                    Toast.makeText(this, "Permission granted", Toast.LENGTH_SHORT).show();

                    startGeofenceMonitoring();
                }
                break;
        }
}

Как я уже сказал, диалоговое окно, которое запрашивает разрешения, никогда не появляется, но моя консоль сообщает мне, что вызывается ActivityCompat.requestPermissions(MapsActivity.this, new String[]{permission}, requestCode);, и после долгих исследований я до сих пор не совсем понимаю, почему оно не работает. Единственное, что я думаю, это может быть связано с тем, что это действие является действием фрагмента, отображающим карту Google Maps. Я пытался запросить разрешения в другом действии, но происходит то же самое.

Спасибо.

ИЗМЕНИТЬ

Итак, я только что протестировал код, который я разместил здесь, в совершенно новом проекте, и он отлично работал и показывал диалоговое окно. Теперь я действительно смущен тем, что мешает этому диалоговому окну отображаться в моем текущем проекте.


person Haris    schedule 05.03.2017    source источник
comment
Попробуйте полностью удалить приложение, а затем переустановить его. Возможно, при тестировании вы дважды отказали в разрешении, когда его спросили, после чего Android перестанет показывать диалог.   -  person CommonsWare    schedule 05.03.2017
comment
Только что попробовал это, и, к сожалению, это не решило проблему.   -  person Haris    schedule 05.03.2017


Ответы (3)


Мне удалось это исправить!

В моем приложении я использовал другое действие для управления вкладками и того, какое действие отображается пользователю. Это самое первое действие, которое будет отображаться, и я думаю, что это единственное действие, отображаемое во всей программе, но просто показывает содержимое других действий. Поэтому, когда я запросил разрешения для MapsActivity, он не отображался, потому что MapsActivity на самом деле не присутствовал.

Мое объяснение может быть неверным, поэтому вот код моей TabBarActivity:

    TabHost tabHost = getTabHost();
    TabHost.TabSpec spec;
    Intent intent;

    intent = new Intent().setClass(this, SecondActivity.class);
    spec = tabHost.newTabSpec("Second").setIndicator("Profile")
            .setContent(intent);
    tabHost.addTab(spec);

    intent = new Intent().setClass(this, MapsActivity.class);
    spec = tabHost.newTabSpec("First").setIndicator("Location")
            .setContent(intent);
    tabHost.addTab(spec);

    intent = new Intent().setClass(this, ThirdActivity.class);
    spec = tabHost.newTabSpec("Third").setIndicator("Settings")
            .setContent(intent);
    tabHost.addTab(spec);
person Haris    schedule 05.03.2017

Код ниже работал для меня.

public static final int MY_PERMISSION_REQUEST_READ_EXTERNAL_STORAGE=1;

 public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
    View view=inflater.inflate(R.layout.activity_tracks,container,false);

    getPermission();
        ...
          }

 public void getPermission(){
        if(ContextCompat.checkSelfPermission(getActivity(),Manifest.permission.READ_EXTERNAL_STORAGE)!=PackageManager.PERMISSION_GRANTED){
            if(ActivityCompat.shouldShowRequestPermissionRationale(getActivity(),Manifest.permission.READ_EXTERNAL_STORAGE)){

            }else{
                ActivityCompat.requestPermissions(getActivity(),new String[] {Manifest.permission.READ_EXTERNAL_STORAGE},MY_PERMISSION_REQUEST_READ_EXTERNAL_STORAGE);
            }
        }else{
            getSongDetails();
        }
    }


 @Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    switch (requestCode){
        case -1:
            //hello
            break;
        case MY_PERMISSION_REQUEST_READ_EXTERNAL_STORAGE:
            if(grantResults.length>0 && grantResults[0]==PackageManager.PERMISSION_GRANTED){
                getPermission();
            }else{
                Toast.makeText(getActivity(),"You've denied permission",Toast.LENGTH_LONG).show();
            }
            return;
        default:
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }

}
person Gopalakrishna Umapathi    schedule 11.04.2017

person    schedule
comment
Это все еще дает мне ту же самую проблему. Нет диалогового окна. - person Haris; 05.03.2017
comment
Убедитесь, что ваше устройство поддерживает разрешения во время выполнения. (Попробуйте с другим новым устройством) - person Sameera Jayarathna; 06.03.2017
comment
Спасибо, но я смог это исправить. Я разместил свое решение здесь. - person Haris; 06.03.2017