[英]Download and install an application (apk) from internal memory - no SD card
向我所有的程序员伙伴们问好,新年快乐。
我的代码从远程服务器下载了一个 apk 文件。 我需要通过代码启动安装过程,而无需用户显式安装。 问题是我不能使用 SD 卡下载 apk 文件。
我可以导航到 data/data/files 文件夹并可以看到我下载的文件。 唯一的问题是我无法安装它。 这就是我得到的
'/data/data/org.obs.testinstall.main/files/app.apk': Permission denied
我了解 Android 不授予访问数据目录的权限。 我的问题是如何在不使用 SD 卡的情况下下载和安装应用程序(apk)。 此应用程序不打算在市场上发布。 我尝试使用内部存储
FileOutputStream fos = openFileOutput("app.apk", Context.MODE_PRIVATE);
和缓存目录
File file = getCacheDir();
File outputFile = new File(file, "app.apk");
两者都给出相同的结果..“权限被拒绝”
当我更改代码以合并 SD 卡时,应用程序可以完美运行,但不能选择使用 SD 卡。
肯定有办法做到这一点。 很难相信 Android 操作系统中存在这样的障碍。
有人做过吗? 任何解决方法? 任何指针都会有所帮助。
如果使用PRIVATE模式写入,它是由android应用程序引起的,无法从另一个应用程序文件中读取。
你可以这样做:
String fileName = "tmp.apk";
FileOutputStream fos = openFileOutput(fileName,
MODE_WORLD_READABLE | MODE_WORLD_WRITEABLE);
// write the .apk content here ... flush() and close()
// Now start the standard instalation window
File fileLocation = new File(context.getFilesDir(), fileName);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(fileLocation),
"application/vnd.android.package-archive");
context.startActivity(intent);
不过要小心,因为该文件现在是全世界可见的,并且可以被同一设备中的任何应用程序看到,如果他们知道文件位置的话。
无需root。 你可以使用 linux 命令 chmod 来完成它。
public static String exec(String[] args) {
String result = "";
ProcessBuilder processBuilder = new ProcessBuilder(args);
Process process = null;
InputStream errIs = null;
InputStream inIs = null;
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int read = -1;
process = processBuilder.start();
errIs = process.getErrorStream();
while ((read = errIs.read()) != -1) {
baos.write(read);
}
baos.write('\n');
inIs = process.getInputStream();
while ((read = inIs.read()) != -1) {
baos.write(read);
}
byte[] data = baos.toByteArray();
result = new String(data);
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (errIs != null) {
errIs.close();
}
if (inIs != null) {
inIs.close();
}
} catch (IOException e) {
e.printStackTrace();
}
if (process != null) {
process.destroy();
}
}
return result;
}
在您的程序中,可以像这样调用它:
String[] args1 = { "chmod", "705", "/data/data/org.obs.testinstall.main/files/" };
exec(args1);
String[] args2 = { "chmod", "604", "/data/data/org.obs.testinstall.main/files/app.apk" };
exec(args2);
然后您可以根据需要安装 app.apk。
你也可以使用
downloadedFile.setReadable(true, false);
和
fileOutputStream = openFileOutput(fileName, Context.MODE_PRIVATE);
有两个 setReadable 方法。 第一个有一个参数,第二个有两个参数。
setReadable(boolean readable)
setReadable(boolean readable, boolean ownerOnly)
对我来说,我在startActivity
之后删除了 apk 文件,这是异步的。
太糟糕了,没有更好的解析错误描述(文件未找到,访问被拒绝,包中的文件损坏,......)
当您发送安装 apk 的意图时,您可以使用此功能更改 apk 目录的模式。
private static boolean changeMode(String filePath, String prefixPath) {
if (TextUtils.isEmpty(prefixPath) || !filePath.startsWith(prefixPath)) {
return true;
}
try {
String[] args1 = { "chmod", "705", prefixPath};
Runtime.getRuntime().exec(args1);
} catch (IOException e) {
e.printStackTrace();
return false;
}
String subPath = filePath.split(prefixPath)[1];
String[] subArr = subPath.split(File.separator);
for (String path : subArr) {
if (!TextUtils.isEmpty(path)) {
prefixPath = prefixPath + File.separator + path;
try {
if (!prefixPath.endsWith(".apk")) {
String[] progArray1 = {"chmod", "705", prefixPath};
Runtime.getRuntime().exec(progArray1);
} else {
String[] progArray2 = {"chmod", "604", prefixPath};
Runtime.getRuntime().exec(progArray2);
}
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
}
return true;
}
在您发送意图之前,请检查 chmod 是否已经成功。
boolean chmodRes = changeMode(filePath, context.getCacheDir().getAbsolutePath())
&& changeMode(filePath, context.getFilesDir().getAbsolutePath());
if (!chmodRes) {
return false;
}
尝试生根您的设备,然后从设备运行程序,而不是使用模拟器。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.