skbrhmn skbrhmn - 1 month ago 16
Android Question

Android RunTime Permissions

I am trying to add runtime permissions to make an app compatible for API 23+. I went through the documentation but when I just include the following line

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

my app crashes and I get the following error:

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) 


 

My code is as follows:

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


How should I check for permission within the fragment? What is causing this error? How do I solve this problem? Thanks!

Answer

getActivity() returns null when a Fragment is first created (i.e., before onAttach() is called).

You should check for permissions directly before you need them, rather than keeping them in a final class variable.

Comments