java - 复制在模拟器上工作但在安卓设备上不工作的音频文件
问题描述
我下面的代码适用于模拟器(android 11 和 api 30)。
private void copy(File in, File out) throws IOException {
FileInputStream is = null;
FileOutputStream os = null;
try {
is = new FileInputStream(in);
os = new FileOutputStream(out);
byte[] buffer = new byte[1024];
int length;
while ((length = is.read(buffer)) > 0) {
os.write(buffer, 0, length);
Log.d("AAA", String.valueOf(out.length()));
}
} finally {
assert is != null;
is.close();
assert os != null;
os.close();
}
}
我把这个方法放在哪里
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 0 && resultCode == RESULT_OK) {
String path = RealPathUtil.getRealPath(SetVoiceIntroActivity.this, data.getData());
File in = new File(path);
File out = new File(getFilesDir(), "record.mp3");
try {
copy(in, out);
Log.d(TAG, out.getAbsolutePath());
} catch (IOException e) {
e.printStackTrace();
}
binding.voicePlayerView.setVisibility(View.VISIBLE);
binding.buttonDeleteVoice.setVisibility(View.VISIBLE);
binding.voicePlayerView.setAudio(out.getAbsolutePath());
}
}
但是当我尝试使用我的手机时,它出现了问题。我该如何解决?
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.yolo.hopel, PID: 19152
java.lang.AssertionError
at com.yolo.hopel.Activities.SetProfile.SetVoiceIntroActivity.copy(SetVoiceIntroActivity.java:251)
at com.yolo.hopel.Activities.SetProfile.SetVoiceIntroActivity.onActivityResult(SetVoiceIntroActivity.java:64)
at android.app.Activity.dispatchActivityResult(Activity.java:8292)
at android.app.ActivityThread.deliverResults(ActivityThread.java:5136)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:5184)
at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:51)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2175)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:237)
at android.app.ActivityThread.main(ActivityThread.java:7860)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1075)
我抓住了它,我得到了消息
2021-08-03 19:29:10.310 25013-25013/com.yolo.hopel D/error: /storage/emulated/0/NCT/NgayKhacLa-DenDJGiangPhamTripleD-5393909.mp3: open failed: EACCES (Permission denied)
但我之前检查过许可
binding.buttonSetVoiceGallery.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
checkPermission();
}
});
private void checkPermission() {
PermissionListener permissionlistener = new PermissionListener() {
@Override
public void onPermissionGranted() {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_GET_CONTENT);
intent.setType("audio/*");
startActivityForResult(intent, 0);
}
@Override
public void onPermissionDenied(List<String> deniedPermissions) {
Toast.makeText(SetVoiceIntroActivity.this, "Permission Denied\n" + deniedPermissions.toString(), Toast.LENGTH_SHORT).show();
}
};
TedPermission.with(this)
.setPermissionListener(permissionlistener)
.setDeniedMessage("If you reject permission,you can not use this service\n\nPlease turn on permissions at [Setting] > [Permission]")
.setPermissions(Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE)
.check();
}
对不起,我的帖子是大多数代码,我必须添加一些文字...请帮助我,谢谢大家,祝你有美好的一天!
解决方案
AssertionError
当程序员认为发生了他/她没想到会发生的事情时,抛出An 。所以大多数情况下这对我来说似乎是一个ScopedStorage
问题,因为你明确提到了Android 11
. 您可以尝试阅读 Android 中的范围存储。此外RealPathUtil
,您用于 github 的内容不适用于范围存储案例
对于使用 Scoped Storage 的文件的一些常用操作,您可以参考此答案
您可能需要了解的有关 Scoped Storage 的其他几点
- 该
WRITE_EXTERNAL_STORAGE
权限已弃用,MANAGE_EXTERNAL_STORAGE
并由 Google 手动批准后在 Play 商店中允许的权限替换。您现在可以在 Q 之后访问 Android 中所有公开可用的文件,而无需WRITE_EXTERNAL_PERMISSION
.MANAGE_EXTERNAL_STORAGE
因此,除非您正在构建文件资源管理器或类似的东西,否则您不得请求许可 MediaStore
如果您需要显式访问外部存储,则可以使用该类写入这些公共目录,如果不需要,则可以使用context.getFilesDir()
它为您提供对目录下外部存储的应用程序私有访问权限/data/data/yourpackagename
。您必须明确管理此空间- 如果您需要临时文件存储,您应该更喜欢使用
context.getCacheDir()
,这里的空间将由 Android 自己管理 - 在任何情况下,您都无法访问应用程序的特定目录,即使您拥有
MANAGE_EXTERNAL_STORAGE
推荐阅读
- rust - 函数参数中不满足特征界限
- python-3.x - pymongo json 返回 bson 字符串
- pipe - Python:如何调试打印到标准输出的数据未打印
- c# - 列表
添加方法不起作用C# - java - JAVA泛型构造函数问题
- openshift - Openshift 3.11 atomic-openshift-node - 服务重启影响
- java - 如何洗牌一个集合?
- javascript - 卡住试图编写分离轴定理代码
- javascript - 带有 Javascript 的 Paypal 智能按钮并获取到 PHP 页面
- java - Java - 将文件从本地目录传输到 S3 的有效方法