您的位置:首页 > 移动开发 > Android开发

关于android 如何安装 assets文件下的apk

2015-06-20 10:26 627 查看
本来来源于为了得分回答别人的问题,不详细思考,不验证,就把百度的答案贴上去,所以在此,先道歉http://bbs.csdn.net/topics/390432635。

留有问题,当没有SD卡又不知道内部存储路径时,这时候我本打算将APK 存到

/data/data/<packagename>/files/xxx.apk 该位置,然后安装,然后删除。但是出现问题,出现解析错误,我试过chmod 777 来给予权限了依然有问题。等待解答。

那下载安装,下载路径有是怎么一种情况,又是如何安装的呢?有待于学习。

运行该示例代码的可能出现问题,就在文件名和路径名那里。如果有问题,请更改这两处。

本文中的所有代码都经过本人验证。

从整体上看,一般的对于assets 里面的apk进行安装的操作是先将 apk 复制到sd上 或者其他的可读取存储位置。比如我拿到的机子 有两个路径

/mnt/emmc/ 手机的内部存储位置(其他的手机不一定有)

/mnt/sdcard/ 手机的sd存储位置

复制到这两个路径都OK。

首先要获取assets目录下文件的数据流,用于写到存储位置上。

//这里的fileName 这个是assets文件下的全文件名 包括后缀名。

path 是存储的路径位置,绝对路径。

InputStream is = context.getAssets().open(fileName);

File file = new File(path);

file.createNewFile();

FileOutputStream fos = new FileOutputStream(file);

byte[] temp = new byte[1024];

int i = 0;

while ((i = is.read(temp)) > 0) {

fos.write(temp, 0, i);

}

fos.close();

is.close();

通过Context 获取到AssetManager

abstract AssetManagergetAssets()

Return an AssetManager instance for your application's package.
在Google sdk 上如此解释 返回一个 AssetManager

final InputStreamopen(String fileName)

Open an asset using ACCESS_STREAMING mode.
final InputStreamopen(String fileName,
int accessMode)

Open an asset using an explicit access mode, returning an InputStream to read its contents.
AssetManager 有着两种方式获取到InputStream 第二种带入accessMode 是对 访问权限控制的
此时获取到了输入流 然后输出就OK,注意close 没其他的问题。 一会回头详细分析这个AssetManager。

这里所谓的安装就是打开apk 百度有很多答案,我给出一个我测试通过的代码

Intent intent = new Intent(Intent.ACTION_VIEW);

intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

intent.setDataAndType(Uri.parse("file://" + Environment.getExternalStorageDirectory().getAbsolutePath()+"/test.apk"),

"application/vnd.android.package-archive");

mContext.startActivity(intent);

我在下面提供整体的代码

[java]
view plaincopy

package com.example.testinstallapk;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.view.Menu;
import android.widget.Toast;

public class MainActivity extends Activity {
Context mContext;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mContext = this;
//Toast.makeText(this, ""+Environment.getExternalStorageDirectory().getAbsolutePath(), 0).show();
if(copyApkFromAssets(this, "test.apk", Environment.getExternalStorageDirectory().getAbsolutePath()+"/test.apk")){
Builder m = new AlertDialog.Builder(mContext)
.setIcon(R.drawable.ic_launcher).setMessage("是否安装?")
.setIcon(R.drawable.ic_launcher)
.setPositiveButton("yes", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setDataAndType(Uri.parse("file://" + Environment.getExternalStorageDirectory().getAbsolutePath()+"/test.apk"),
"application/vnd.android.package-archive");
mContext.startActivity(intent);
}
});
m.show();
}

}
public boolean copyApkFromAssets(Context context, String fileName, String path) {
boolean copyIsFinish = false;
try {
InputStream is = context.getAssets().open(fileName);
File file = new File(path);
file.createNewFile();
FileOutputStream fos = new FileOutputStream(file);
byte[] temp = new byte[1024];
int i = 0;
while ((i = is.read(temp)) > 0) {
fos.write(temp, 0, i);
}
fos.close();
is.close();
copyIsFinish = true;
} catch (IOException e) {
e.printStackTrace();
}
return copyIsFinish;
}
}

注意在manifest中添加你的sd权限<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

现在分析一下这个 AssetManager 类。

为了分析这个类,先介绍一下assets这个文件夹

Android 系统为每个新设计的程序提供了/assets目录,这个目录保存的文件可以打包在程序里。/res 和/assets的不同点是,android不为/assets下的文件生成ID。如果使用/assets下的文件,需要指定文件的路径和文件名(是全名)
下面写一个方法遍历assets下面的全部文件

AssetManager mAssetManager= getAssets();

String[] files = null;

try {

files = mAssetManager.list("");//为什么是空呢

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

for(String temp:files) Log.v("shenwenjian",""+temp);

final String[]list(String path)

Return a String array of all the assets at the given path.
返回一个包含在assets中给定路径的所有文件 数组,
我为了获取所有故这里填"" 这时候得到几个字符串分别是images, sounds,webkit 当然你也可以放其他的文件 也会被打印出来.

怎么读取文件,获取到文件内容呢?先获取上面说的获取数据流。

final InputStreamopen(String fileName)

Open an asset using ACCESS_STREAMING mode.
final InputStreamopen(String fileName,
int accessMode)
通过这两个方法就可获取到输入流,然后通过 ByteArrayOutputStream 将inputstream 转换成string 即可以看到文件内容
关于那个打开APK的还需要分析。
主要就是解析那个intent 和策略等
这里给定一个apk安装,卸载和更新的连接。 http://blog.csdn.net/netpirate/article/details/5801379 http://www.devdiv.com/Android-%E5%A6%82%E4%BD%95%E6%89%93%E5%BC%80assets%E6%96%87%E4%BB%B6%E5%A4%B9%E4%B8%AD%E7%9A%84apk_-thread-38839-1-1.html
谢谢该链接的内容!

转:http://blog.csdn.net/shen332401890/article/details/8826827
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: