这个INSTALL_FAILED_INSUFFICIENT_STORAGE错误是每个Android开发人员生活中的祸根.无论应用程序大小或可用存储空间如何,都会发生这种情况.重新启动目标设备可以简单地解决问题,但很快就会回来.有数百个(如果不是数千个)消息板帖子来自人们询问问题发生的原因,但谷歌的人们对这个问题感到沮丧.
有一个简单的解决方法.如果您的测试设备运行的是Android 2.2或更高版本,则android:installLocation使用该值将该属性添加到应用程序的清单文件中"preferExternal".这将强制将应用程序安装在设备的外部存储设备上,例如手机的SD卡.
例如:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.andrewsmith.android.darkness"
android:installLocation="preferExternal"
Run Code Online (Sandbox Code Playgroud)
这更像是一个创可贴,而不是一个修复,如果您希望您的已完成的应用程序安装在设备的内部存储器上,它可能并不理想.但它至少会让开发过程变得更加令人沮丧.
我正在创建一个文件作为电子邮件的附件发送.现在我想在发送电子邮件后删除图像.有没有办法删除文件?
我试过myFile.delete();但它没有删除该文件.
我正在使用Android的这个代码,因此编程语言是使用通常的Android方式访问SD卡的Java.当我在发送电子邮件后返回到屏幕onActivityResult时,我正在删除该方法中的文件Intent.
在Android 4.4(KitKat)上,谷歌已经限制了对SD卡的访问.
从Android Lollipop(5.0)开始,开发人员可以使用新的API,要求用户确认允许访问特定文件夹,如此Google-Groups帖子所述.
该帖子指导您访问两个网站:
这看起来像是一个内部示例(可能稍后会在API演示中显示),但很难理解发生了什么.
这是新API的官方文档,但它没有详细说明如何使用它.
这是它告诉你的:
如果您确实需要完全访问整个文档子树,请首先启动ACTION_OPEN_DOCUMENT_TREE以允许用户选择目录.然后将生成的getData()传递给fromTreeUri(Context,Uri)以开始使用用户选择的树.
在导航DocumentFile实例树时,您始终可以使用getUri()来获取表示该对象的基础文档的Uri,以便与openInputStream(Uri)等一起使用.
要在运行KITKAT或更早版本的设备上简化代码,可以使用fromFile(File)来模拟DocumentsProvider的行为.
我对新API有几个问题:
如何从sdcard将图像文件读入位图?
_path = Environment.getExternalStorageDirectory().getAbsolutePath();
System.out.println("pathhhhhhhhhhhhhhhhhhhh1111111112222222 " + _path);
_path= _path + "/" + "flower2.jpg";
System.out.println("pathhhhhhhhhhhhhhhhhhhh111111111 " + _path);
Bitmap bitmap = BitmapFactory.decodeFile(_path, options );
Run Code Online (Sandbox Code Playgroud)
我得到位图的NullPointerException.这意味着位图为空.但我有一个图像".jpg"文件存储在SD卡中作为"flower2.jpg".有什么问题?
我的SD卡中有一个文件夹:/mnt/sdcard/Folder1/Folder2/Folder3/*.jpg
Folder1和Folder2的名称保持不变,在Folder2里面我有Folder3,4,5等等.我想把所有jpeg文件而不是所有文件(还有更多)用adb到我当前的计算机目录上.
每个文件夹都有不同数量的jpeg文件和其他文件,我尝试使用这个:
adb pull mnt/sdcard/Folder1/Folder2/Folder/*.jpg .
Run Code Online (Sandbox Code Playgroud)
但它没有用..所以我怎么用一个命令adb拉出SD卡的任何文件夹中的所有文件(单个命令因为每个文件夹有不同数量的文件)
三星Galaxy S3有一个extrenal SD卡插槽,安装到/mnt/extSdCard.
我的问题是:如何通过类似的方式获得这条路径Environment.getExternalStorageDirectory()?这将返回mnt/sdcard,我找不到外部SD卡的API.(或某些平板电脑上的可移动USB存储器)
谢谢!
我想以编程方式获取设备内部/外部存储空闲内存的大小.我正在使用这段代码:
StatFs stat = new StatFs(Environment.getExternalStorageDirectory().getPath());
long bytesAvailable = (long)stat.getBlockSize() *(long)stat.getBlockCount();
long megAvailable = bytesAvailable / 1048576;
Log.e("","Available MB : "+megAvailable);
File path = Environment.getDataDirectory();
StatFs stat2 = new StatFs(path.getPath());
long blockSize = stat2.getBlockSize();
long availableBlocks = stat2.getAvailableBlocks();
String format = Formatter.formatFileSize(this, availableBlocks * blockSize);
Log.e("","Format : "+format);
Run Code Online (Sandbox Code Playgroud)
而我得到的结果是:
11-15 10:27:18.844: E/(25822): Available MB : 7572
11-15 10:27:18.844: E/(25822): Format : 869MB
Run Code Online (Sandbox Code Playgroud)
问题是我想获得1,96GB现在的SdCard的免费记忆.如何修复此代码,以便获得免费大小?
我使用以下代码从我的服务器下载文件,然后将其写入SD卡的根目录,一切正常:
package com.downloader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import android.os.Environment;
import android.util.Log;
public class Downloader {
public void DownloadFile(String fileURL, String fileName) {
try {
File root = Environment.getExternalStorageDirectory();
URL u = new URL(fileURL);
HttpURLConnection c = (HttpURLConnection) u.openConnection();
c.setRequestMethod("GET");
c.setDoOutput(true);
c.connect();
FileOutputStream f = new FileOutputStream(new File(root, fileName));
InputStream in = c.getInputStream();
byte[] buffer = new byte[1024];
int len1 = 0;
while ((len1 = in.read(buffer)) > 0) {
f.write(buffer, 0, len1);
}
f.close();
} …Run Code Online (Sandbox Code Playgroud) 在我的应用程序中,我需要在设备存储中存储大量图像.这些文件往往满足设备存储,我想让用户能够选择外部SD卡作为目标文件夹.
我到处读到Android不允许用户写入外部SD卡,SD卡是指外部和可安装的SD卡而不是外部存储器,但文件管理器应用程序设法在所有Android版本上写入外部SD.
在不同的API级别(Pre-KitKat,KitKat,Lollipop +)上授予对外部SD卡的读/写访问权限的更好方法是什么?
更新1
我从Doomknight的答案中尝试了方法1,但没有结果:正如您所看到的那样,我在尝试在SD上写入之前在运行时检查权限:
HashSet<String> extDirs = getStorageDirectories();
for(String dir: extDirs) {
Log.e("SD",dir);
File f = new File(new File(dir),"TEST.TXT");
try {
if(ActivityCompat.checkSelfPermission(this,Manifest.permission.WRITE_EXTERNAL_STORAGE)==PackageManager.PERMISSION_GRANTED) {
f.createNewFile();
}
} catch (IOException e) {
e.printStackTrace();
}
}
Run Code Online (Sandbox Code Playgroud)
但是我在两个不同的设备上尝试了访问错误:HTC10和Shield K1.
10-22 14:52:57.329 30280-30280/? E/SD: /mnt/media_rw/F38E-14F8
10-22 14:52:57.329 30280-30280/? W/System.err: java.io.IOException: open failed: EACCES (Permission denied)
10-22 14:52:57.329 30280-30280/? W/System.err: at java.io.File.createNewFile(File.java:939)
10-22 14:52:57.329 30280-30280/? W/System.err: at com.myapp.activities.TestActivity.onResume(TestActivity.java:167)
10-22 14:52:57.329 30280-30280/? W/System.err: at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1326)
10-22 14:52:57.330 30280-30280/? W/System.err: at android.app.Activity.performResume(Activity.java:6338)
10-22 14:52:57.330 …Run Code Online (Sandbox Code Playgroud) 我认为这很容易但事实证明不幸的是.
是)我有的:
我的外部存储器上有一个名为"myFolder"的文件夹(不是SD卡,因为它是Nexus 4,但这应该不是问题).该文件夹包含一些*.csv文件.
我想要的是:
我想写一个方法,它执行以下操作:显示各种应用程序(文件浏览器),我可以从中选择一个(见图片).单击它后,所选的文件浏览器应该启动并显示"myFolder"的内容.不多也不少.

我的问题:
我到底该怎么做?我想我接下来的代码非常接近,但无论我做什么 - 而且我确定必须有一些我还没有做到的事情 - 它始终只打开来自外部存储器的主文件夹.
public void openFolder()
{
File file = new File(Environment.getExternalStorageDirectory(),
"myFolder");
Log.d("path", file.toString());
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setDataAndType(Uri.fromFile(file), "*/*");
startActivity(intent);
}
Run Code Online (Sandbox Code Playgroud) android ×10
android-sdcard ×10
java ×2
directory ×1
diskspace ×1
documentfile ×1
download ×1
http ×1
installation ×1