Android:来自 ContentResolver 的 InputStream 已损坏
Android: InputStream from ContentResolver is corrupted
在业余时间,我开发了一个 Android 通过 Internet 发送文件的应用程序。我自己开发这个应用程序,所以我不太关心有关隐私等的Playstore Guildlines。
应用程序应该做什么:
- 用户点击按钮从存储select文件
- Android 将该文件提供给我的应用程序 -> 这就是问题所在
- 我的应用读取该文件并发送它
问题:
我的应用程序得到一个“URI”。我尝试使用 ContentResolver 从该 URI 读取文件。并将文件复制到我的应用程序的内部存储中。
但是当我用 ImageViewer 打开这个文件时,它告诉我,这个文件已损坏。十六进制编辑器还显示了与原始文件的差异。
权限:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
从 Android:
打开文件选择器的代码
ActivityResultLauncher<String> launcherGetContent = registerForActivityResult(
new ActivityResultContracts.GetContent(),
result ->
{
if (result != null)
{
addAttachment(result);
}
}
);
launcherGetContent.launch("*/*");
“addAttachment”方法:
try
{
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
InputStream inputStream = context.getContentResolver().openInputStream(uri);
int read = -1;
byte[] data = new byte[1024];
while ((read = inputStream.read(data, 0, data.length)) != -1)
{
byteArrayOutputStream.write(data, 0, read);
}
byteArrayOutputStream.flush();
byteArrayOutputStream.close();
BufferedWriter buf = new BufferedWriter(new FileWriter(context.getApplicationInfo().dataDir + "/cache/test4.jpg"));
buf.write(byteArrayOutputStream.toString("UTF-8"));
buf.flush();
buf.close();
}
catch (IOException e)
{
e.printStackTrace();
}
在十六进制编辑器中打开的原始图像:
复制的图像(test4.jpg):
有相似之处,但明显不同。我也不知道为什么。
可能是因为您 UTF8
将二进制文件编码为文本
buf.write(byteArrayOutputStream.toString("UTF-8"));
你的 addAttachment
方法看起来很奇怪
试试这个
File cacheFile = new File(getCacheDir(), "test4.jpg");
// Now read the file
try{
InputStream input = context.getContentResolver().openInputStream(uri);
int originalSize = input.available();
bis = new BufferedInputStream(input);
bos = new BufferedOutputStream(new FileOutputStream(cacheFile));
byte[] buf = new byte[originalSize];
//noinspection ResultOfMethodCallIgnored
bis.read(buf);
do {
bos.write(buf);
} while (bis.read(buf) != -1);
} catch (Exception e) {
// Notify User of fail
Log.e(Constants.TAG, "readFile:" + e);
} finally {
try {
if (bos != null) {
bos.flush();
bos.close();
}
} catch (Exception ignored) {
}
}
在业余时间,我开发了一个 Android 通过 Internet 发送文件的应用程序。我自己开发这个应用程序,所以我不太关心有关隐私等的Playstore Guildlines。
应用程序应该做什么:
- 用户点击按钮从存储select文件
- Android 将该文件提供给我的应用程序 -> 这就是问题所在
- 我的应用读取该文件并发送它
问题: 我的应用程序得到一个“URI”。我尝试使用 ContentResolver 从该 URI 读取文件。并将文件复制到我的应用程序的内部存储中。 但是当我用 ImageViewer 打开这个文件时,它告诉我,这个文件已损坏。十六进制编辑器还显示了与原始文件的差异。
权限:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
从 Android:
打开文件选择器的代码ActivityResultLauncher<String> launcherGetContent = registerForActivityResult(
new ActivityResultContracts.GetContent(),
result ->
{
if (result != null)
{
addAttachment(result);
}
}
);
launcherGetContent.launch("*/*");
“addAttachment”方法:
try
{
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
InputStream inputStream = context.getContentResolver().openInputStream(uri);
int read = -1;
byte[] data = new byte[1024];
while ((read = inputStream.read(data, 0, data.length)) != -1)
{
byteArrayOutputStream.write(data, 0, read);
}
byteArrayOutputStream.flush();
byteArrayOutputStream.close();
BufferedWriter buf = new BufferedWriter(new FileWriter(context.getApplicationInfo().dataDir + "/cache/test4.jpg"));
buf.write(byteArrayOutputStream.toString("UTF-8"));
buf.flush();
buf.close();
}
catch (IOException e)
{
e.printStackTrace();
}
在十六进制编辑器中打开的原始图像:
复制的图像(test4.jpg):
有相似之处,但明显不同。我也不知道为什么。
可能是因为您 UTF8
将二进制文件编码为文本
buf.write(byteArrayOutputStream.toString("UTF-8"));
你的 addAttachment
方法看起来很奇怪
试试这个
File cacheFile = new File(getCacheDir(), "test4.jpg");
// Now read the file
try{
InputStream input = context.getContentResolver().openInputStream(uri);
int originalSize = input.available();
bis = new BufferedInputStream(input);
bos = new BufferedOutputStream(new FileOutputStream(cacheFile));
byte[] buf = new byte[originalSize];
//noinspection ResultOfMethodCallIgnored
bis.read(buf);
do {
bos.write(buf);
} while (bis.read(buf) != -1);
} catch (Exception e) {
// Notify User of fail
Log.e(Constants.TAG, "readFile:" + e);
} finally {
try {
if (bos != null) {
bos.flush();
bos.close();
}
} catch (Exception ignored) {
}
}