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

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

访问文件代码:

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

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

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



你可能感兴趣的:(AndroidStudio,debug,android,studio,Java,listfile)