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

最近学习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);
    }
}

@Override
public 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后的。第三步相当于提供了一把钥匙,开了门后,就不需要钥匙了!

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



评论 20
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值