0

Я пытаюсь добавить разрешения во время выполнения, чтобы приложение совместимо с API 23+. Я прошел через documentation, но когда я просто включить следующую строкуAndroid RunTime Permissions

private final int hasWriteFilePermission = ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE);,

мое приложение вылетает, и я получаю следующее сообщение об ошибке:

07-10 20:54:15.571 31479-31479/com.ibm.watson.developer_cloud.android.examples E/AndroidRuntime: FATAL EXCEPTION: main 
                          Process: com.ibm.watson.developer_cloud.android.examples, PID: 31479 
                          java.lang.RuntimeException: Unable to start activity ComponentInfo{com.ibm.watson.developer_cloud.android.examples/com.ibm.watson.developer_cloud.android.examples.MainActivity}: java.lang.NullPointerException: Attempt to invoke interface method 'int java.util.List.size()' on a null object reference 
                           at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3254) 
                           at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3350) 
                           at android.app.ActivityThread.access$1100(ActivityThread.java:222) 
                           at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1795) 
                           at android.os.Handler.dispatchMessage(Handler.java:102) 
                           at android.os.Looper.loop(Looper.java:158) 
                           at android.app.ActivityThread.main(ActivityThread.java:7229) 
                           at java.lang.reflect.Method.invoke(Native Method) 
                           at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230) 
                           at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120) 
                           Caused by: java.lang.NullPointerException: Attempt to invoke interface method 'int java.util.List.size()' on a null object reference 
                           at android.widget.ArrayAdapter.getCount(ArrayAdapter.java:337) 
                           at android.widget.AbsSpinner.setAdapter(AbsSpinner.java:115) 
                           at android.widget.Spinner.setAdapter(Spinner.java:554) 
                           at com.ibm.watson.developer_cloud.android.examples.MainActivity$FragmentTabSTT.addItemsOnSpinnerModels(MainActivity.java:566) 
                           at com.ibm.watson.developer_cloud.android.examples.MainActivity$FragmentTabSTT.onCreateView(MainActivity.java:190) 
                           at android.app.Fragment.performCreateView(Fragment.java:2281) 
                           at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:983) 
                           at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1163) 
                           at android.app.BackStackRecord.run(BackStackRecord.java:793) 
                           at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1552) 
                           at android.app.FragmentController.execPendingActions(FragmentController.java:325) 
                           at android.app.Activity.performStart(Activity.java:6914) 
                           at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3217) 
                           at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3350)  
                           at android.app.ActivityThread.access$1100(ActivityThread.java:222)  
                           at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1795)  
                           at android.os.Handler.dispatchMessage(Handler.java:102)  
                           at android.os.Looper.loop(Looper.java:158)  
                           at android.app.ActivityThread.main(ActivityThread.java:7229)  
                           at java.lang.reflect.Method.invoke(Native Method)  
                           at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)  
                           at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)  

Мой код выглядит следующим образом:

public static class FragmentTabSTT extends Fragment implements ISpeechToTextDelegate { 
    . 
    . 
    . 
@Override 
    public void onAttach(Context context) { 
     super.onAttach(context); 

     Activity a; 

     if (context instanceof Activity){ 
      a = (Activity) context; 
     } 

    } 



    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
            Bundle savedInstanceState) { 
    . 
    . 
    . 
    } 
    . 
    . 
    . 
     // One method that requires permission 
public ArrayList<String> GetFiles(String DirectoryPath) { 

     int hasReadFilesPermission = ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.READ_EXTERNAL_STORAGE); 

     if (hasReadFilesPermission != PackageManager.PERMISSION_GRANTED) { 
      if (!shouldShowRequestPermissionRationale(permission.READ_EXTERNAL_STORAGE)) { 
       showMessageOKCancel("You must give permission to read from storage.", 
         new DialogInterface.OnClickListener() { 
          @Override 
          public void onClick(DialogInterface dialog, int which) { 
           requestPermissions(new String[] {permission.READ_EXTERNAL_STORAGE}, 
             REQUEST_CODE_ASK_PERMISSIONS); 
          } 
         }); 
       return null; 
      } 

      requestPermissions(new String[] {permission.READ_EXTERNAL_STORAGE}, 
        REQUEST_CODE_ASK_PERMISSIONS); 
      return null; 
     } 
     ArrayList<String> MyFiles = new ArrayList<String>(); 
     File f = new File(DirectoryPath); 

     f.mkdirs(); 
     File[] files = f.listFiles(); 
     if (files.length == 0) 
      return null; 
     else { 
      for (int i=0; i<files.length; i++) 
       MyFiles.add(files[i].getName()); 
     } 

     return MyFiles; 
    } 
} 

Как shoul d Я проверяю разрешение внутри фрагмента? Что вызывает эту ошибку? Как решить эту проблему? Благодаря!

+0

Вы можете проверить класс, который я создал, и использовать его во Фрагментах https://github.com/mptrista/PermissionHelper Это очень просто. – toshkinl

ответ

3

getActivity() возвращает null, когда сначала создается Фрагмент (т. Е. До onAttach()).

Необходимо проверить права доступа непосредственно перед их использованием, а не хранить их в последней переменной класса.

+0

Благодарим за ответ, но не могли бы вы уточнить? Реализация метода, требующего разрешения, находится внутри фрагмента. Как проверить разрешения в этом случае? – skbrhmn

+0

Итак, положите вызов 'ContextCompat.checkSelfPermission' непосредственно перед этой строкой. – ianhanniballake

+0

Перед тем, как использовать строку 'contextCompat.checkSelfPermission'? Немного обновленный код. Это то, что вы имели в виду? – skbrhmn

1

Не называйте его в статической переменной:

@Override 
onViewCreated(Bundle savedInstanceState) { 
    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); 
    // do stuff 
} 

И вы должны будете наследовать от AppCompatFragment.