I want to create a folder for my app. For this permissions needs to be checked at run time. So when the user accepts the request I am creating the folder and initializing the listFile array with the number of files in the directory.
Also I have one asyncTask to get an events. So I am creating the main list inside onPostExecute method of an asyncTask.
In this main list I want to show the length of an listFile array. But It's crashing with a null pointer exception.
MainActivity :
public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener,GetEventsAsyncTask.GetEvents {
private RecyclerView recyclerView;
private MainListAdapter mAdapter;
private List<MainList> mainLists = new ArrayList<>();
String folder_main = "MeaVita";
File dir = new File(Environment.getExternalStorageDirectory(),folder_main);
File[] listFile;
public int REQUEST_CODE_ASK_PERMISSIONS = 11;
public boolean permissionsAccepted;
private String userUsername;
public int PERMISSIONS_WRITE_EXTERNAL_STORAGE =10;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sharedpreferences = getSharedPreferences("username",Context.MODE_PRIVATE);
userUsername = sharedpreferences.getString("UserUsername","No name defined");
GetEventsAsyncTask getEventsAsyncTask = new GetEventsAsyncTask(this,MainActivity.this,eventArrayList);
getEventsAsyncTask.execute(userUsername);
parent = (AppBarLayout) findViewById(R.id.view3);
recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
eventArrayList = new ArrayList<>();
checkFilePermissions();
recyclerView.setAdapter(new MainListAdapter(mainLists, new MainListAdapter.OnItemClickListener() {
@Override public void onItemClick(MainList item) {
if(item.getTitle().equals("Plan Event")) {
startActivity(new Intent(MainActivity.this, PlanEventActivity.class));
}
if(item.getTitle().equals("Events")) {
startActivity(new Intent(MainActivity.this, EventsListActivity.class));
}
if(item.getTitle().equals("Photos")) {
// checkFilePermissions();
sharedpreferences = getSharedPreferences(MyPREFERENCES, Context.MODE_PRIVATE);
permissionsAccepted = sharedpreferences.getBoolean("permission",false);
if(dir.exists()) {
if (permissionsAccepted) {
if (listFile.length == 0) {
showAlert("No Images");
} else {
new MainActivity.SingleMediaScanner(MainActivity.this, listFile[0]);
}
}
}
else {
showAlert("No Folder");
}
}
if(item.getTitle().equals("Reminders")) {
startActivity(new Intent(MainActivity.this, RemindersActivity.class));
}
if(item.getTitle().equals("Chat")) {
}
if(item.getTitle().equals("Notes")) {
startActivity(new Intent(MainActivity.this, NotesActivity.class));
}
if(item.getTitle().equals("Notifications")) {
startActivity(new Intent(MainActivity.this, NotificationsActivity.class));
}
if(item.getTitle().equals("Profile")) {
startActivity(new Intent(MainActivity.this, ProfileActivity.class));
}
}
}));
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
}
public class SingleMediaScanner implements MediaScannerConnection.MediaScannerConnectionClient {
private MediaScannerConnection mMs;
private File mFile;
public SingleMediaScanner(Context context, File f) {
mFile = f;
mMs = new MediaScannerConnection(context, this);
mMs.connect();
}
public void onMediaScannerConnected() {
mMs.scanFile(mFile.getAbsolutePath(), null);
}
public void onScanCompleted(String path, Uri uri) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(uri);
startActivity(intent);
mMs.disconnect();
}
}
private void checkFilePermissions() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
int hasWriteExternalStoragePermission = checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (hasWriteExternalStoragePermission != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
REQUEST_CODE_ASK_PERMISSIONS);
}
}
}
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
if (REQUEST_CODE_ASK_PERMISSIONS == 11) {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
if (!dir.exists()) {
dir.mkdirs();
permissionsAccepted = true;
}
listFile = dir.listFiles();
SharedPreferences.Editor editor = sharedpreferences.edit();
editor.putBoolean("permission",permissionsAccepted);
editor.apply();
if (listFile.length == 0) {
Toast.makeText(MainActivity.this, "The folder is empty.", Toast.LENGTH_SHORT).show();
}
else {
new MainActivity.SingleMediaScanner(MainActivity.this, listFile[0]);
}
// permission was granted, yay! Do the
// contacts-related task you need to do.
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
Toast.makeText(MainActivity.this, "Request Denied", Toast.LENGTH_SHORT).show();
}
// other 'case' lines to check for other
// permissions this app might request
}
}
private void prepareData() {
MainList mainList = new MainList("Plan Event","", R.drawable.plan);
mainLists.add(mainList);
mainList = new MainList("Events",String.valueOf(eventArrayList.size()), R.drawable.events);
mainLists.add(mainList);
mainList = new MainList("Photos",String.valueOf(listFile.length), R.drawable.phone);
mainLists.add(mainList);
mainList = new MainList("Reminders","20", R.drawable.remind);
mainLists.add(mainList);
mainList = new MainList("Chat","2", R.drawable.chat);
mainLists.add(mainList);
mainList = new MainList("Notes","2", R.drawable.notes);
mainLists.add(mainList);
mainList = new MainList("Notifications","20", R.drawable.remind);
mainLists.add(mainList);
mainList = new MainList("Profile","50%", R.drawable.user);
mainLists.add(mainList);
}
public void showAlert(String alert) {
Snackbar snackbar = Snackbar.make(parent, alert, Snackbar.LENGTH_LONG);
snackbar.show();
}
@Override
public void doPostExecute(ArrayList<Event> response) {
eventArrayList = response;
listFile = dir.listFiles();
prepareData();
}
}
06-29 22:40:46.322 30194-30194/com.example.siddhi.meavita E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.siddhi.meavita, PID: 30194
java.lang.NullPointerException: Attempt to get length of null array
at com.example.siddhi.meavita.Activities.MainActivity.prepareData(MainActivity.java:341)
at com.example.siddhi.meavita.Activities.MainActivity.doPostExecute(MainActivity.java:370)
at com.example.siddhi.meavita.AsyncTaskClasses.GetEventsAsyncTask.onPostExecute(GetEventsAsyncTask.java:107)
at com.example.siddhi.meavita.AsyncTaskClasses.GetEventsAsyncTask.onPostExecute(GetEventsAsyncTask.java:28)
at android.os.AsyncTask.finish(AsyncTask.java:651)
at android.os.AsyncTask.-wrap1(AsyncTask.java)
You are using method File.listFiles()
to get the list of files from a directory.
listFile can be null
However, according to Docs, this method can return null
public File[] listFiles()
...
Returns null if this abstract pathname does not denote a directory, or if an I/O error occurs.
dir.listFile()
may return null
in following conditions:
dir
does not reflects a directory (dir
can be pointing to a file for example.. it is not your case)As you can see, you can not ensure that listFile
is always different from null`... It can be null ocasionally. So, you should first check if listFile is null before read its properties/values.
null protection
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
listFile = dir.listFiles();
...
if (listFile == null || listFile.length == 0) {
Toast.makeText(MainActivity.this, "The folder is empty.", Toast.LENGTH_SHORT).show();
} else {
new MainActivity.SingleMediaScanner(MainActivity.this, listFile[0]);
}
...
}
AND
private void prepareData() {
...
if(listFile != null && listFile.length >= 0)
mainList = new MainList("Photos",String.valueOf(listFile.length), R.drawable.phone);
else
mainList = new MainList("Photos", "0", R.drawable.phone);
mainLists.add(mainList);
...
}