You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:11:41