真的操蛋的android 6.0+系统权限问题.....必须借这个机会,记录一下...
起初,晚上回去无聊只是单纯的说想做个播放器软件玩玩,导个第三方,遍历一下本地文件就OK了的事,打发一下时间...结果让我学到一大堆东西,首先是关于android的内存读取方式,就恶补了一遍,然后读取系统数据库又略补了一下,最后发现,居然TM的(原谅我爆粗口,因为我以来就在AndroidManifest.xml表做了读取权限添加了的)是android 6.0以上系统需要动态添加权限!!!!
首先,介绍一遍adnroid 读取本地文件的方法:
第一步肯定是先到清单文件添加:
两个权限
手机内部存储:
static File getDataDirectory() 获得data的目录(/data)。
static File getDownloadCacheDirectory() 获得下载缓存目录。(/cache)
static File getExternalStorageDirectory() 获得外部存储媒体目录。(/mnt/sdcard or /storage/sdcard0)
static File getRootDirectory() 获得系统主目录(/system)
另外,Environment.getDataDirectory().getParentFile(),可以回去内存的根目录:( / )
SD卡:
方法路径
Environment.getExternalStoragePublicDirectory(DIRECTORY_ALARMS)/storage/sdcard0/Alarms
Environment.getExternalStoragePublicDirectory(DIRECTORY_DCIM)/storage/sdcard0/DCIM
Environment.getExternalStoragePublicDirectory(DIRECTORY_DOWNLOADS)/storage/sdcard0/Download
Environment.getExternalStoragePublicDirectory(DIRECTORY_MOVIES)/storage/sdcard0/Movies
Environment.getExternalStoragePublicDirectory(DIRECTORY_MUSIC)/storage/sdcard0/Music
Environment.getExternalStoragePublicDirectory(DIRECTORY_NOTIFICATIONS)/storage/sdcard0/Notifications
Environment.getExternalStoragePublicDirectory(DIRECTORY_PICTURES)/storage/sdcard0/Pictures
Environment.getExternalStoragePublicDirectory(DIRECTORY_PODCASTS)/storage/sdcard0/Podcasts
Environment.getExternalStoragePublicDirectory(DIRECTORY_RINGTONES)/storage/sdcard0/Ringtones
一般也就这几种,如果要指定文件夹也可以这样:
File file = new File("/storage/sdcard1"); 直接定位到SD卡
File file = new File(Enviroment.getExternalStorageDirectory); 直接定位到内置内存
起初我也以为直接定位到内置内存(因为现在大多数手机都没有SD卡了的),递归文件夹获取视频文件就行了的,结果读取出来:它居然跟我报空!!! 我1000多张图片,10多部电影它居然告诉我内置存储位里面文件数为NULL !!!
算了,牢骚也发完了,直接上正确代码吧...
因为6.0以后要求,需要在java代码内自己加权限:
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode) {
case 0: {//手机内置外部存贮
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {//授权同意
File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath());
showFiles(file);
} else {//授权被拒绝
}
}
break;
case 1://sd卡
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {//授权同意
File file = new File("/storage/sdcard1");
showFiles(file);
} else {//授权被拒绝
}
break;
} }
就是这样啦,直接重写onRequestPermissionsResult 方法,在启动程序时运行调用判断,申请权限。同时在清单文件中,也一定要先添加这个权限。然后,然后就行了!!!!!!!
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(MainDemo10Activity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED ||
ContextCompat.checkSelfPermission(MainDemo10Activity.this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {//没有授权权限
ActivityCompat.requestPermissions(MainDemo10Activity.this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE},
1);
} else {//授权了权限
File file = new File("/storage/sdcard1");
showFiles(file);
}
} else {//6.0以下系统
File file = new File("/storage/sdcard1");
showFiles(file);
}
这个,就是启动的时候再去判断一下当前手机版本,是不是6.0以上的,然后进行下权限判断的...
最后附上查询本地视频的递归查询方法,好歹我的初衷是查询本地视频,想做个播放器的...结果弄了两个小时没弄好,郁闷的我打了局游戏睡觉了,而且居然还输了!...
private void showFiles(File file) {
if (file == null) return;
File[] files = file.listFiles();
if (files == null) return;
for (File file1 : files) {
if (file1.isDirectory()) {
showFiles(file1);
} else {
String name = file1.getPath();
int i = name.indexOf('.');
if (i != -1) {
name = name.substring(i);
if (name.equalsIgnoreCase(".mp4")
|| name.equalsIgnoreCase(".3gp")
|| name.equalsIgnoreCase(".wmv")
|| name.equalsIgnoreCase(".ts")
|| name.equalsIgnoreCase(".rmvb")
|| name.equalsIgnoreCase(".mov")
|| name.equalsIgnoreCase(".m4v")
|| name.equalsIgnoreCase(".avi")
|| name.equalsIgnoreCase(".m3u8")
|| name.equalsIgnoreCase(".3gpp")
|| name.equalsIgnoreCase(".3gpp2")
|| name.equalsIgnoreCase(".mkv")
|| name.equalsIgnoreCase(".flv")
|| name.equalsIgnoreCase(".divx")
|| name.equalsIgnoreCase(".f4v")
|| name.equalsIgnoreCase(".rm")
|| name.equalsIgnoreCase(".asf")
|| name.equalsIgnoreCase(".ram")
|| name.equalsIgnoreCase(".mpg")
|| name.equalsIgnoreCase(".v8")
|| name.equalsIgnoreCase(".swf")
|| name.equalsIgnoreCase(".m2v")
|| name.equalsIgnoreCase(".asx")
|| name.equalsIgnoreCase(".ra")
|| name.equalsIgnoreCase(".ndivx")
|| name.equalsIgnoreCase(".xvid")
) {
data.add(file1.getPath());
}
}
}
}
}
最后我只是添加了视频文件的路径检查了下是不是读取到文件了,就没有继续做播放器了,因为感觉已经恶补了一遍文件读取(都是因为不知道要添加权限,帮文件读取的资料看了一大堆),具体怎么做就不放代码了,路径都有了,难道还用不来嘛!