把apk文件放到assets文件夹下 自动运行

从整体上看,一般的对于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 AssetManager getAssets()
Return an AssetManager instance for your application's package.
在Google sdk 上如此解释 返回一个 AssetManager

final InputStream open(String fileName)
Open an asset using ACCESS_STREAMING mode.
final InputStream open(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 plain copy
  1. package com.example.testinstallapk;  
  2.   
  3. import java.io.File;  
  4. import java.io.FileOutputStream;  
  5. import java.io.IOException;  
  6. import java.io.InputStream;  
  7.   
  8. import android.net.Uri;  
  9. import android.os.Bundle;  
  10. import android.os.Environment;  
  11. import android.app.Activity;  
  12. import android.app.AlertDialog;  
  13. import android.app.AlertDialog.Builder;  
  14. import android.app.Dialog;  
  15. import android.content.Context;  
  16. import android.content.DialogInterface;  
  17. import android.content.DialogInterface.OnClickListener;  
  18. import android.content.Intent;  
  19. import android.view.Menu;  
  20. import android.widget.Toast;  
  21.   
  22. public class MainActivity extends Activity {  
  23.     Context mContext;  
  24.     @Override  
  25.     protected void onCreate(Bundle savedInstanceState) {  
  26.         super.onCreate(savedInstanceState);  
  27.         setContentView(R.layout.activity_main);  
  28.         mContext = this;  
  29.         //Toast.makeText(this, ""+Environment.getExternalStorageDirectory().getAbsolutePath(), 0).show();  
  30.         if(copyApkFromAssets(this"test.apk", Environment.getExternalStorageDirectory().getAbsolutePath()+"/test.apk")){  
  31.             Builder m = new AlertDialog.Builder(mContext)  
  32.                                 .setIcon(R.drawable.ic_launcher).setMessage("是否安装?")  
  33.                                 .setIcon(R.drawable.ic_launcher)  
  34.                                 .setPositiveButton("yes"new OnClickListener() {  
  35.                                     @Override  
  36.                                     public void onClick(DialogInterface dialog, int which) {  
  37.                                         Intent intent = new Intent(Intent.ACTION_VIEW);  
  38.                                         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);  
  39.                                         intent.setDataAndType(Uri.parse("file://" + Environment.getExternalStorageDirectory().getAbsolutePath()+"/test.apk"),  
  40.                                                        "application/vnd.android.package-archive");  
  41.                                         mContext.startActivity(intent);  
  42.                                         }  
  43.                                     });  
  44.             m.show();  
  45.         }  
  46.           
  47.     }  
  48.      public boolean copyApkFromAssets(Context context, String fileName, String path) {  
  49.          boolean copyIsFinish = false;  
  50.          try {  
  51.              InputStream is = context.getAssets().open(fileName);  
  52.              File file = new File(path);  
  53.              file.createNewFile();  
  54.              FileOutputStream fos = new FileOutputStream(file);  
  55.              byte[] temp = new byte[1024];  
  56.              int i = 0;  
  57.              while ((i = is.read(temp)) > 0) {  
  58.                  fos.write(temp, 0, i);  
  59.              }  
  60.              fos.close();  
  61.              is.close();  
  62.              copyIsFinish = true;  
  63.          } catch (IOException e) {  
  64.              e.printStackTrace();  
  65.          }  
  66.          return copyIsFinish;  
  67.      }  
  68. }  


注意在manifest中添加你的sd权限


现在分析一下这个 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 InputStream open(String fileName)
Open an asset using ACCESS_STREAMING mode.
final InputStream open(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

谢谢该链接的内容!

你可能感兴趣的:(android)