Android模拟器中URL视频下载播放权限异常求助
问题排查与解决方案
哥们,你的代码在真机跑起来没问题,但模拟器罢工,核心问题出在权限管控和路径/Uri的不规范写法上——毕竟模拟器一般用的是较新的Android版本,权限规则更严格。咱们一步步来解决:
1. 存储权限缺失(核心原因)
你看到的Permission denied是因为Android 6.0(API 23)及以上版本需要动态申请存储权限,光在Manifest里加静态权限没用。模拟器大概率是这个版本以上,所以直接下载会被系统拦截。
解决步骤:
- 首先在
AndroidManifest.xml里添加必要的静态权限,同时适配Android 10+的存储规则:
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <!-- Android 10+ 需要添加这个属性,兼容旧版存储方式 --> <application ... android:requestLegacyExternalStorage="true"> ... </application>
- 在点击下载按钮前,先检查并申请权限:
修改btnShowProgress的点击事件:
btnShowProgress.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // 检查读写存储权限是否已授权 if (ContextCompat.checkSelfPermission(AndroidDownloadFileByProgressBarActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { // 未授权,发起权限申请 ActivityCompat.requestPermissions(AndroidDownloadFileByProgressBarActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE}, 100); // 请求码随便设,只要唯一就行 } else { // 已授权,开始下载 new DownloadFileFromURL().execute(file_url); } } });
- 处理权限申请结果,添加以下方法到Activity中:
@Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == 100) { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // 用户同意权限,启动下载 new DownloadFileFromURL().execute(file_url); } else { Toast.makeText(this, "需要存储权限才能下载并播放视频", Toast.LENGTH_SHORT).show(); } } }
2. 硬编码路径不规范
直接写/sdcard/4.mp4是很不严谨的,不同设备的外部存储路径可能不一样,而且Android 10+对直接访问根目录有限制。应该用系统提供的API获取合法路径。
修改下载路径:
把DownloadFileFromURL里的FileOutputStream部分替换成:
// 获取公共视频目录,系统会自动适配路径 File downloadDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES); // 如果目录不存在,创建它 if (!downloadDir.exists()) { downloadDir.mkdirs(); } // 定义输出文件 File outputFile = new File(downloadDir, "4.mp4"); OutputStream output = new FileOutputStream(outputFile);
3. Uri解析错误
你用Uri.parse("/sdcard/4.mp4")的方式不对,系统无法识别这个路径为合法的文件Uri,应该用Uri.fromFile()来生成正确的文件Uri。
修改onPostExecute里的Uri生成:
@Override protected void onPostExecute(String file_url) { dismissDialog(progress_bar_type); videoView =(VideoView)findViewById(R.id.videoView); mediaController= new MediaController(AndroidDownloadFileByProgressBarActivity.this); mediaController.setAnchorView(videoView); // 用正确的方式生成文件Uri File videoFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES), "4.mp4"); Uri uri = Uri.fromFile(videoFile); videoView.setMediaController(mediaController); videoView.setVideoURI(uri); videoView.requestFocus(); videoView.start(); }
做完这些修改后,模拟器应该就能正常下载并播放视频了。本质上就是模拟器的权限规则更严格,同时咱们的路径和Uri写法要符合Android的规范~
内容的提问来源于stack exchange,提问作者user8618145
相关产品推荐
相关产品推荐

