解决AndroidStudio File类的Listfile返回值为null问题

来源:互联网 发布:javascript实战手册 编辑:程序博客网 时间:2024/06/13 19:12

最近学习AndroidStudio,用到File类的listFiles方法,其返回值总是为null,费了很大力气才解决。因此需要总结一下。

访问文件代码:

private File mImgDir;
private final String mTestPath = "/pictest/pic/";//该目录在模拟器上实际存在,里面有几张测试图片。

List<String> getFileNameList(){    File sdCard = Environment.getExternalStorageDirectory();//获取的值为: /storage/emulated/0    String folder = sdCard.getAbsolutePath() + mTestPath;  //folder值为:/storage/emulated/0/pictest/pic
    mImgDir = new File(folder);//初始化File对象
     File [] files = mImgDir.listFiles();//噩梦在这一行开始!

    if (files!= null)    {        Toast.makeText(getApplicationContext(),"有内容!",Toast.LENGTH_SHORT).show();        Log.d("哈哈哈","能访问!");    }    else    {        Toast.makeText(getApplicationContext(),"null!",Toast.LENGTH_SHORT).show();        Log.d("哎呀","仍然搞不定!");    }

}

噩梦在“File[] files =mImgDir.listFiles()”这一行开始!files的值是null!下面是探索过程:


1.在AndroidMenifest.xml中增加permission:

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"></uses-permission><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission
再次运行代码,files的值仍然是null !


2.加入运行时检查

拜读了自仁兄nianhua120的大作:http://blog.csdn.net/nianhua120/article/details/51525949 感觉有所悟,copy了两个关键函数

getPermission函数和onRequestPermissionsResult函数。代码变为:


private File mImgDir;
private final String mTestPath = "/pictest/pic/";//该目录在模拟器上实际存在,里面有几张测试图片。

List<String> getFileNameList(){     File sdCard = Environment.getExternalStorageDirectory();//获取的值为: /storage/emulated/0     String folder = sdCard.getAbsolutePath() + mTestPath;  //folder值为:/storage/emulated/0/pictest/pic
     getPermission();//加入运行时检查
}
void getPermission(){    int permissionCheck1 = ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.READ_EXTERNAL_STORAGE);    int permissionCheck2 = ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE);    if (permissionCheck1 != PackageManager.PERMISSION_GRANTED || permissionCheck2 != PackageManager.PERMISSION_GRANTED) {        ActivityCompat.requestPermissions(this,                new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE},                124);    }}
@Overridepublic void onRequestPermissionsResult(int requestCode,                                       String[] permissions,                                       int[] grantResults) {    if (requestCode == 124) {        if ((grantResults.length > 0) && (grantResults[0] == PackageManager.PERMISSION_GRANTED))        {             Log.d("heihei","获取到权限了!");             
             mImgDir = new File(folder);//初始化File对象
             File [] files = mImgDir.listFiles();//噩梦结束了吗?
} else { Log.d("heihei","搞不定啊!"); } }}

经过调试发现,执行到onRequestPermissionsResult,grantResults的返回值是{-1,-1}!

查看PackageManager.java, 发现:
public static final int PERMISSION_GRANTED = 0;
public static final int PERMISSION_DENIED = -1;
噩梦仍未结束!这下很崩溃啊!


3.看了大量权限相关的文章,仍然无果。最后找到一篇外国人的帖子:

http://stackoverflow.com/questions/37162223/permission-denial-android-permission-read-external-storage

里面有一句关键的话:As a temporary workaround, drop your targetSdkVersion below 23.

我照着这句话做了。打开build.gradle(Module:app)文件,修改 targetSdkVersion25为 targetSdkVersion22


private File mImgDir;
private final String mTestPath = "/pictest/pic/";//该目录在模拟器上实际存在,里面有几张测试图片。

List<String> getFileNameList(){    File sdCard = Environment.getExternalStorageDirectory();//获取的值为: /storage/emulated/0    String folder = sdCard.getAbsolutePath() + mTestPath;  //folder值为:/storage/emulated/0/pictest/pic
    //getPermission();//加入运行时检查
    mImgDir = new File(folder);//初始化File对象
    File [] files = mImgDir.listFiles();//噩梦在这一行开始!

    if (files!= null)    {        Toast.makeText(getApplicationContext(),"有内容!",Toast.LENGTH_SHORT).show();        Log.d("哈哈哈","能访问!");    }    else    {        Toast.makeText(getApplicationContext(),"null!",Toast.LENGTH_SHORT).show();        Log.d("哎呀","仍然搞不定!");    }

}

再次运行代码,屏幕弹出"哈哈哈",噩梦终于结束!


4.神奇的后续

1)神奇的是,把getPermission()注释掉,仍然可以工作!

2)更神奇的是,打开build.gradle(Module:app)文件,修改 targetSdkVersion 22为 targetSdkVersion 25,即把这个改动回退,仍然可以工作!

也就是说,最终能工作的代码其实就是第一步加入permission后的。第三步相当于提供了一把钥匙,开了门后,就不需要钥匙了!

这其中的谜,有待未来探索。。。



1 0