我想为我的应用程序创建一个文件夹。为此,需要在运行时检查权限。因此,当用户接受请求时,我正在创建文件夹并使用目录中的文件数量初始化listFile数组。
我也有一个asyncTask来获取事件。所以我在asyncTask的onPostExecute方法中创建主列表。
在这个主列表中,我想显示listFile数组的长度。但是它会因为空指针异常而崩溃。
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();
}
}
日志: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)
如何以及何时初始化listFile数组以及何时调用prepareData方法?
请帮助。被困住了,对这个很陌生。谢谢你。
您正在使用方法File.listFiles()
从目录中获取文件列表。
listFile可以为空
但是,根据Docs,这个方法可以返回null
public File[] listFiles()
…如果此抽象路径名不表示目录,或者发生I/O错误,则返回null。
dir.listFile()
可以在以下条件下返回null
:
- 如果
dir
不反映一个目录(dir
可以指向一个文件,例如..这不是你的情况) - 任何I/O错误(如读取目录内容时的权限或任何其他失败)
正如你所看到的,你不能确保listFile
总是不同于null '…它有时可能为空。因此,在读取它的属性/值之前,你应该首先检查listFile是否为空。
@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]);
}
...
}
和
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);
...
}
你只是忘记实现eventArrayList
作为一个类变量,你也试图调用它作为一个你得到一个null
异常当你试图调用eventArrayList.size()
您试图在没有指定文件大小或初始化listFile对象的情况下获得长度。您需要指定listFile的长度。像
File[] listFile = new File[10];
或者你可以在你的listFile对象中传递任何你需要的数组。然后获取长度