2015-09-22 4 views
232

Я обновляю наше приложение, чтобы использовать новую систему M Permissions. Это все работает, кроме onRequestPermissionsResult(). Мне нужно проверить разрешение нажатием кнопки, и если оно выполнено успешно, отправьте текстовое сообщение. Когда я даю разрешение на это, диалог закрывается, но он не вызывает отправку текста, пока я не нажму кнопку еще раз.Android M Разрешения: onRequestPermissionsResult() не называется

Я отлаживал и устанавливал точки останова в методе onRequestPermissionsResult(), но он никогда не входит в него.

Этот метод вызывается первым:

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

Кто-столкнулось с подобным вопросом? Оцените справку. Благодаря

ответ

6

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

Он делал некоторые вещи низкого уровня, как бит переключения, чтобы получить эту работу, так что я не слишком уверен, фактического окончательного решения

+0

Это помогло мне решить мою проблему: мне пришлось перенаправить onRequestPermissionsResult из родительского фрагмента в дочерний (вложенный) фрагмент. Спасибо за совет! – Murphy

+0

Спасибо за информацию. –

84

Вы можете попробовать это:

requestPermissions(permissions, PERMISSIONS_CODE); 

Если вы вызываете этот код из фрагмента он имеет свой собственный метод requestPermissions. Я считаю, что проблема в том, что вы вызываете статический метод.

Pro Tip, если вы хотите, чтобы onRequestPermissionsResult() в фрагменте: FragmentCompat.requestPermissions(Fragment fragment, String[] permissions, int requestCode)

+0

Спасибо за помощь. Я заметил, что есть метод requestPermissions, если он есть в фрагменте. Я нахожусь в фрагменте, и я попробовал позвонить просто requestPermissions, к сожалению, он не работал. Я также попробовал то, что вы упомянули, и это тоже не сработало. – goodgamerguy

+0

Это работало для меня в Android M. Но просто интересно, не вызовет ли это какие-либо проблемы в устройствах Pre-M? –

+0

Это было решение! – Mulgard

12

У вас есть checkPermissions функции для предварительных устройств Зефира в FragmentCompat. я использую как это:

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

Это работает только в том случае, если разрешение запрашивается внутри android.app.fragment, и вам нужно импортировать библиотеку поддержки-v13! – MohammadReza

+0

Да, @EBLiS это правильно. –

+3

FragmentCompat.requestPermissions() не работает с android.support.v4.app.Fragment. Кто-нибудь знает, как справиться с этим. – Jutikorn

505

Я столкнулся с той же проблемой, и я только что нашел решение. При использовании библиотеки поддержки вы должны использовать правильные вызовы методов. Например:

  • Когда в AppCompatActivity, вы должны использовать ActivityCompat.requestPermissions;
  • Когда в android.support.v4.app.Fragment, вы должны использовать просто requestPermissions (это метод экземпляра android.support.v4.app.Fragment)

Если вы звоните ActivityCompat.requestPermissions в фрагменте, onRequestPermissionsResult callback вызывается для активности, а не для фрагмента.

Надеюсь, это поможет!

+12

Он также встречается с действиями noHistory: https://code.google.com/p/android-developer-preview/issues/detail?id=2915 –

+8

«Когда в файле android.support.v4.app.Fragment вы должны используйте просто requestPermissions "- спасибо! –

+0

Что делать, если у меня есть фрагмент поддержки в AppCompatActivity? – WindRider

31

Если у вас есть onRequestPermissionsResult в обоих активность и фрагмент, убедитесь, что для вызова super.onRequestPermissionsResult в Мероприятия. Он не требуется в фрагменте, но он находится в действии.

+0

Также обратите внимание, что если вы нацеливаете API (например, 19, например), вы по-прежнему будете находиться под старой системой моделей разрешений и, таким образом, не будете получать вызовы функций, связанных с запросами – Bonatti

+0

, см. Мой ответ, если вы расширили другой деятельность, которая не вызывает супер – TouchBoarder

+3

Наткнулся на этот. 'FragmentActivity.onRequestPermissionsResult (..)' - это то, куда пересылается вызов для 'onRequestPermissionsResult (..)' фрагмента. – JanPl

14

Если вы используете requestPermissions в фрагменте, он принимает 2 параметра вместо 3.

Вы должны использовать requestPermissions(permissions, PERMISSIONS_CODE);

+1

На самом деле это дает ответ на вопрос. Вызов requestPermissions (метод экземпляра фрагмента) вместо ActivityCompat.requestPermissions вызывает метод результата. В этом главная проблема. Спасибо Дон – Waclock

+0

отличная информация поблагодарить u – fullMoon

13

Если по какой-то причине вы расширили пользовательскую активность, расположенную в некоторой внешней библиотеке, которая не вызовите супер, вам нужно будет вручную вызвать Фрагмент super.onRequestPermissionsResult самостоятельно в вашей Activity 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); 
    } 
... 
6

Это будет работать ..

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

может у вас есть причина, почему она будет работать? –

+0

супер реализация вызывает реализацию фрагментов, а не hte framework –

11

Я обнаружил, что очень важно, когда вы звоните android.support.v4.app.Fragment.requestPermissions.

Если вы делаете это в onCreate(), onRequestPermissionsResult() никогда не вызывается.

Решение: Звоните по телефону onActivityCreated();

@Override 
public void onActivityCreated(Bundle savedInstanceState) { 

    super.onActivityCreated(savedInstanceState); 

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

} 
+1

У меня такая же проблема, но я не могу получить 'onActivityCreated()' в моем коде. SDK 23. – kAmol

+0

см. Http://developer.android.com/reference/android/app/Fragment.html#onActivityCreated%28android.os.Bundle%29, или см. Образец на http://www.mysamplecode.com/2012 /08/android-fragment-example.html – almisoft

+0

Я не во фрагменте, я пытаюсь сделать это on onCreate of activity – kAmol

9
/* use the object of your fragment to call the 
* onRequestPermissionsResult in fragment after 
* in activity and use different request Code for 
* both Activity and Fragment */ 

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

    else 
    ActivityCompat.requestPermissions(mActivity,permissions.toArray(new 
    String[permissions.size()]),requestPermission); 
45

Я тоже столкнулся с этой проблемой. Если вы хотите, чтобы действие, которое обрабатывает разрешения не в истории/ретентатах, вы захотите изменить свою запись AndroidManifest.xml.

Если вы установили деятельность, которую вы называете requestPermissions или AppCompatActivity.requestPermissions с

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

в вашем AndroidManifest.xml тогда onRequestPermissionsResult() не будет называться. Это верно, если ваша деятельность получена из Activity или AppCompatActivity.

Это можно устранить, удалив оба флажка из «AndroidManifest.xml» и закончив свою деятельность с помощью finishAndRemoveTask().

+0

Мне бы не пришлось удалять атрибут noHistory, но это было решение, которое сработало для меня. Благодаря! –

+0

спасибо миллион, никогда бы не догадался об этом – spy

+0

спасибо Саймон работает безупречно – Alok

29

Внутри фрагмента, вам нужно позвонить:

FragmentCompat.requestPermissions(permissionsList, RequestCode) 

Не:

ActivityCompat.requestPermissions(Activity, permissionsList, RequestCode); 
+2

Относится к android.support.v13.app.FragmentCompat –

2

Перед тем, как проверить, все в соответствии с выше ответов, убедитесь, что ваш код запроса не 0 !!!

проверить код onRequestPermissionsResult() в FragmentActivity.Java:

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

     String who = mPendingFragmentActivityResults.get(index); 
     mPendingFragmentActivityResults.remove(index); 
     if (who == null) { 
      Log.w(TAG, "Activity result delivered for unknown Fragment."); 
      return; 
     } 
     Fragment frag = mFragments.findFragmentByWho(who); 
     if (frag == null) { 
      Log.w(TAG, "Activity result no fragment exists for who: " + who); 
     } else { 
      frag.onRequestPermissionsResult(requestCode&0xffff, permissions, grantResults); 
     } 
    } 
} 
+0

Мой запрос Код 1337, но индекс оценивается в 0 ... – Andrew

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

Я надеюсь, что он работает нормально

Для деятельности:

ActivityCompat.requestPermissions(this,permissionsList,REQUEST_CODE); 

Для фрагмента:

requestPermissions(permissionsList,REQUEST_CODE); 
+0

Как насчет SDK 15 и ниже? –

+2

Вам не нужно разрешение на SDK 15, только для Marshmallow и выше для версии .. –

+0

спасибо, что вам удалось решить мою проблему во фрагменте. –

1

Вы можете использовать requestPermissions(PERMISSIONS, MULTIPLE_PERMISSIONS_CODE);. Не используйте FragmentCompat, если вы используете v4.

+0

Пожалуйста, объясните почему. – Placeable

4

Если вы вызываете этот код из фрагмента, у него есть собственный метод requestPermissions.

Так основная концепция, если вы находитесь в деятельности, а затем вызвать

ActivityCompat.requestPermissions(this, 
          permissionsList, 
          permissionscode); 

и если в фрагменте, просто позвоните

requestPermissions(permissionsList, 
          permissionscode); 
+1

Требуется уровень API 23 ... На ранних версиях используйте 'FragmentCompat.requestPermissions()'. –

1

ОБНОВЛЕНИЕ: видели чужой ответ о вызове super.onRequestPermissionResult() в Activit y, и это исправляет проблему кода запроса, о которой я упоминал, и вызывает onRequestPermissionResult фрагмента.

игнорировать этот материал:

Для меня это было вызовом onRequestPermissionResult деятельности, несмотря на меня называющий fragment.requestPermission (...), но он вернул результат с неправильным requestCode (111 превратился в 65647 почему? Я никогда не узнаю).

К счастью, это единственное разрешение мы запрашиваем на этом экране, так что я просто игнорировать код запроса (не хватает времени, чтобы понять, почему сейчас это не правильно)

+0

Добавьте 65536 и 111, и вы получите его. Это из-за бит-масок. См. Некоторые темы. – CoolMind

0

У меня есть удивительное решение для достижения этой цели сделайте BaseActivity следующим образом.

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

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

Thanks

Смежные вопросы