android - 在 Android 免安装应用中下载文件
问题描述
我正在尝试通过 Instant 应用中的下载管理器下载文件:
Uri uri = Uri.parse("https://images.pexels.com/photos/67636/rose-blue-flower-rose-blooms-67636.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260");
DownloadManager downloadManager = (DownloadManager) context.getSystemService(DOWNLOAD_SERVICE);
downloadManager.enqueue(new DownloadManager.Request(uri)
.setTitle("Demo")
.setDescription("Something useful. No, really.")
.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS,
"test.mp4"));
但得到一个例外:
java.lang.IllegalStateException: Unable to create directory: /storage/emulated/0/Download
at android.app.DownloadManager$Request.setDestinationInExternalPublicDir(DownloadManager.java:539)
有没有其他方法可以在免安装应用中下载文件?
解决方案
问题似乎与 Android 6.0 中引入的 Android 运行时权限有关
当您的应用程序以 API 级别 23 为目标时,默认情况下所有权限都是错误的,您必须先请求权限对话框并批准权限,然后才能将其用于您的应用程序。
请求许可
public class RequestPermissionHandler {
private Activity mActivity;
private RequestPermissionListener mRequestPermissionListener;
private int mRequestCode;
public void requestPermission(Activity activity, @NonNull String[] permissions, int requestCode,
RequestPermissionListener listener) {
mActivity = activity;
mRequestCode = requestCode;
mRequestPermissionListener = listener;
if (!needRequestRuntimePermissions()) {
mRequestPermissionListener.onSuccess();
return;
}
requestUnGrantedPermissions(permissions, requestCode);
}
private boolean needRequestRuntimePermissions() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M;
}
private void requestUnGrantedPermissions(String[] permissions, int requestCode) {
String[] unGrantedPermissions = findUnGrantedPermissions(permissions);
if (unGrantedPermissions.length == 0) {
mRequestPermissionListener.onSuccess();
return;
}
ActivityCompat.requestPermissions(mActivity, unGrantedPermissions, requestCode);
}
private boolean isPermissionGranted(String permission) {
return ActivityCompat.checkSelfPermission(mActivity, permission)
== PackageManager.PERMISSION_GRANTED;
}
private String[] findUnGrantedPermissions(String[] permissions) {
List<String> unGrantedPermissionList = new ArrayList<>();
for (String permission : permissions) {
if (!isPermissionGranted(permission)) {
unGrantedPermissionList.add(permission);
}
}
return unGrantedPermissionList.toArray(new String[0]);
}
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
if (requestCode == mRequestCode) {
if (grantResults.length > 0) {
for (int grantResult : grantResults) {
if (grantResult != PackageManager.PERMISSION_GRANTED) {
mRequestPermissionListener.onFailed();
return;
}
}
mRequestPermissionListener.onSuccess();
} else {
mRequestPermissionListener.onFailed();
}
}
}
public interface RequestPermissionListener {
void onSuccess();
void onFailed();
}
像这样在活动中使用:
public class MainActivity extends AppCompatActivity {
private RequestPermissionHandler mRequestPermissionHandler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRequestPermissionHandler = new RequestPermissionHandler();
findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
handleButtonClicked();
}
});
}
private void handleButtonClicked(){
mRequestPermissionHandler.requestPermission(this, new String[] {
Manifest.permission.RECEIVE_SMS, Manifest.permission.READ_EXTERNAL_STORAGE
}, 123, new RequestPermissionHandler.RequestPermissionListener() {
@Override
public void onSuccess() {
Toast.makeText(MainActivity.this, "request permission success", Toast.LENGTH_SHORT).show();
}
@Override
public void onFailed() {
Toast.makeText(MainActivity.this, "request permission failed", Toast.LENGTH_SHORT).show();
}
});
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
mRequestPermissionHandler.onRequestPermissionsResult(requestCode, permissions,
grantResults);
}
}
并且不要忘记将其添加到您的manifest
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
推荐阅读
- java - Java Spring在数据库触发后继续执行
- python - 是否有像 Louvain 这样具有低时间复杂度的社区检测算法,但会惩罚太大的社区
- vba - 在 Outlook 邮件中发送 Excel 表格而不使用显示
- python - 使用 Scrapy Files Pipeline 在几年范围内下载 (PDF) 文档
- android - 由于“隐私政策链接无效或丢失”,Google 拒绝了应用
- python - 获取 Riot 的永久 API 密钥
- node.js - NGINX 反向代理将“未定义”添加到请求路径(docker、node、create-react-app)
- discord.js - 查找角色中有多少成员
- flutter - 在代码中没有 hero 或 FloatingActionButton 小部件的子树错误中有多个英雄共享相同的标签
- javascript - 如何在文本字段中检测到英文字符?