注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

隐龙 为了一生的信念

今日默默沉于水,他日飞腾在九天...

 
 
 

日志

 
 

Android 动态加载APK--代码安装、获取安装包中的资源及Intent调用已安装apk  

2012-08-03 08:01:50|  分类: Android |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

最近在研究Android动态加载APK技术,偶有小得,共享一下,欢迎交流。

首先是Android 动态加载已安装的APK


被调用工程TestB:

其工程已添加了字符串、颜色和图片资源,这里不写了,读者可自行添加。

  1. public class TestBActivity extends Activity{  
  2.     /** Called when the activity is first created. */  
  3.     @Override  
  4.     public void onCreate(Bundle savedInstanceState) {  
  5.         super.onCreate(savedInstanceState);  
  6.         setContentView(R.layout.main);  
  7.         Button button=(Button)findViewById(R.id.button1);  
  8.         button.setOnClickListener(new OnClickListener() {  
  9.               
  10.             @Override  
  11.             public void onClick(View v) {  
  12.                 // TODO Auto-generated method stub  
  13.                 Toast.makeText(TestBActivity.this, "this is testB", Toast.LENGTH_SHORT).show();  
  14.             }  
  15.         });  
  16.     }  
  17. }  
public class TestBActivity extends Activity{   /** Called when the activity is first created. */   @Override   public void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.main);    Button button=(Button)findViewById(R.id.button1);    button.setOnClickListener(new OnClickListener() {          @Override     public void onClick(View v) {      // TODO Auto-generated method stub      Toast.makeText(TestBActivity.this, "this is testB", Toast.LENGTH_SHORT).show();     }    });   }  }

接着把TestB打包为TestB.apk,放到sdcard的根目录。

调用工程TestA:

首先应该是安装apk文件:

  1. protected void InstallAPK(String apkname) {  
  2.         // TODO Auto-generated method stub  
  3.   
  4.         //代码安装  
  5.         String fileName = Environment.getExternalStorageDirectory() + "/"+apkname;   
  6.         Intent intent = new Intent(Intent.ACTION_VIEW);   
  7.         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);  
  8. //       intent.setDataAndType(Uri.parse("file://"+fileName), "application/vnd.android.package-archive");   
  9.          intent.setDataAndType(Uri.fromFile(new File(fileName)), "application/vnd.android.package-archive");   
  10.         TestAActivity.this.startActivityForResult(intent, 1);  
protected void InstallAPK(String apkname) {    // TODO Auto-generated method stub      //代码安装    String fileName = Environment.getExternalStorageDirectory() + "/"+apkname;     Intent intent = new Intent(Intent.ACTION_VIEW);     intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);  //   intent.setDataAndType(Uri.parse("file://"+fileName), "application/vnd.android.package-archive");      intent.setDataAndType(Uri.fromFile(new File(fileName)), "application/vnd.android.package-archive");     TestAActivity.this.startActivityForResult(intent, 1);

但是安装之前是不是要先检测一下TestB.apk是否已安装呢:

  1. protected boolean checkInstall(String pak) {  
  2.     // TODO Auto-generated method stub  
  3.     boolean install=false;  
  4.     PackageManager pm=getPackageManager();  
  5.     try {  
  6.         PackageInfo info=pm.getPackageInfo(pak,1);  
  7.         if (info!=null&&info.activities.length>0) {  
  8.             install=true;  
  9.         }  
  10.     } catch (NameNotFoundException e) {  
  11.         // TODO Auto-generated catch block  
  12.         e.printStackTrace();  
  13.     }  
  14.     return install;  
  15. }  
 protected boolean checkInstall(String pak) {    // TODO Auto-generated method stub    boolean install=false;    PackageManager pm=getPackageManager();    try {     PackageInfo info=pm.getPackageInfo(pak,1);     if (info!=null&&info.activities.length>0) {      install=true;     }    } catch (NameNotFoundException e) {     // TODO Auto-generated catch block     e.printStackTrace();    }    return install;   }

如果未安装,便调用InstallAPK(String apkname)安装,如果已安装便可代码获取其资源:

  1. private void getRes(String pak){  
  2.     if (checkInstall(pak)) {  
  3.     try {  
  4.   
  5.             Context ctxTestB = getTestContext(pak);  
  6.             Resources res = ctxTestB.getResources();  
  7.             // 获取字符串string  
  8.             String hello = res.getString(getId("string", "hello", pak));  
  9.             ((TextView) findViewById(R.id.testb_string)).setText(hello);  
  10.               
  11.             // 获取图片Drawable  
  12.             Drawable drawable = res.getDrawable(getId("drawable", "testb",pak));  
  13.             ((ImageView) findViewById(R.id.testb_drawable)).setImageDrawable(drawable);  
  14.               
  15.             // 获取颜色值  
  16.             int color = res.getColor(getId("color", "white",pak));  
  17.             ((TextView) findViewById(R.id.testb_color)).setBackgroundColor(color);  
  18.               
  19.             // 获取布局文件  
  20.             View view = getView(ctxTestB, getId("layout", "main",pak));  
  21.             LinearLayout layout = (LinearLayout) findViewById(R.id.testb_layout);  
  22.             layout.addView(view);  
  23.   
  24.     } catch (NameNotFoundException e) {  
  25.     e.printStackTrace();  
  26. }}  
  27. }  
  28.  //获取资源对应的编号  
  29. private int getId(String name, String type,String pak) {  
  30.     return testb.getIdentifier(name, type, pak);  
  31. }  
  32.   
  33.   
  34.  // 获取视图  
  35. public View getView(Context ctx, int id) {  
  36.     return ((LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(id,null);  
  37. }  
  38.   
  39.   
  40.  //获取TestB的Context  
  41. private Context getTestContext(String pak) throws NameNotFoundException {  
  42.     return createPackageContext(pak,Context.CONTEXT_IGNORE_SECURITY | Context.CONTEXT_INCLUDE_CODE);  
  43. }  
 private void getRes(String pak){    if (checkInstall(pak)) {    try {        Context ctxTestB = getTestContext(pak);      Resources res = ctxTestB.getResources();      // 获取字符串string      String hello = res.getString(getId("string", "hello", pak));      ((TextView) findViewById(R.id.testb_string)).setText(hello);            // 获取图片Drawable      Drawable drawable = res.getDrawable(getId("drawable", "testb",pak));      ((ImageView) findViewById(R.id.testb_drawable)).setImageDrawable(drawable);            // 获取颜色值      int color = res.getColor(getId("color", "white",pak));      ((TextView) findViewById(R.id.testb_color)).setBackgroundColor(color);            // 获取布局文件      View view = getView(ctxTestB, getId("layout", "main",pak));      LinearLayout layout = (LinearLayout) findViewById(R.id.testb_layout);      layout.addView(view);      } catch (NameNotFoundException e) {    e.printStackTrace();   }}   }    //获取资源对应的编号   private int getId(String name, String type,String pak) {    return testb.getIdentifier(name, type, pak);   }        // 获取视图   public View getView(Context ctx, int id) {    return ((LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(id,null);   }        //获取TestB的Context   private Context getTestContext(String pak) throws NameNotFoundException {    return createPackageContext(pak,Context.CONTEXT_IGNORE_SECURITY | Context.CONTEXT_INCLUDE_CODE);   }

接下来再来看看怎么使用Intent组件启动被调用工程:

  1. protected void startAPK(String pak) {  
  2.     // TODO Auto-generated method stub  
  3.   
  4.     //代码启动  
  5.     try {  
  6.                       //pak=PACKAGE_TEST_B+".TestBActivity"  
  7.         Context ctxTestB = getTestContext(PACKAGE_TEST_B);  
  8.         Class cls = ctxTestB.getClassLoader().loadClass(pak);  
  9.         TestAActivity.this.startActivity(new Intent(ctxTestB, cls));  
  10.     } catch (ClassNotFoundException e) {  
  11.         e.printStackTrace();  
  12.     } catch (NameNotFoundException e) {  
  13.         // TODO Auto-generated catch block  
  14.         e.printStackTrace();  
  15.     }  
  16. }  
 protected void startAPK(String pak) {    // TODO Auto-generated method stub      //代码启动    try {                         //pak=PACKAGE_TEST_B+".TestBActivity"     Context ctxTestB = getTestContext(PACKAGE_TEST_B);     Class cls = ctxTestB.getClassLoader().loadClass(pak);     TestAActivity.this.startActivity(new Intent(ctxTestB, cls));    } catch (ClassNotFoundException e) {     e.printStackTrace();    } catch (NameNotFoundException e) {     // TODO Auto-generated catch block     e.printStackTrace();    }   }

以下为扩展内容:

比如加上网络下载apk文件功能,然后再安装,这里使用的是URL通信协议,用HttpURLConnection类,面向的是应用层:

  1. protected File downLoadFile(String httpUrl) {  
  2.                     // TODO Auto-generated method stub  
  3.         String filename="down_TestB.apk";  
  4.         File file=new File(Environment.getExternalStorageDirectory() + "/"+filename);  
  5.   
  6.                     try {  
  7.                             URL url = new URL(httpUrl);  
  8.                             try {  
  9.                                     HttpURLConnection conn = (HttpURLConnection) url  
  10.                                                     .openConnection();  
  11.                                     InputStream is = conn.getInputStream();  
  12.                                     FileOutputStream fos = new FileOutputStream(file);  
  13.                                     byte[] buf = new byte[256];  
  14.                                     conn.connect();  
  15.                                     int count = 0;  
  16.                                     if (conn.getResponseCode()==200) {  
  17.                                            while ((count=is.read(buf))>0) {  
  18.                                               
  19.                                                fos.write(buf, 0, count);  
  20.                                         }  
  21.                                     }  
  22.   
  23.                                     conn.disconnect();  
  24.                                     fos.close();  
  25.                                     is.close();  
  26.                             } catch (IOException e) {  
  27.                                     // TODO Auto-generated catch block  
  28.   
  29.                                     e.printStackTrace();  
  30.                             }  
  31.                     } catch (MalformedURLException e) {  
  32.                             // TODO Auto-generated catch block  
  33.   
  34.                             e.printStackTrace();  
  35.                     }  
  36.   
  37.                     return file;  
  38.             }  
protected File downLoadFile(String httpUrl) {                   // TODO Auto-generated method stub    String filename="down_TestB.apk";    File file=new File(Environment.getExternalStorageDirectory() + "/"+filename);                     try {                           URL url = new URL(httpUrl);                           try {                                   HttpURLConnection conn = (HttpURLConnection) url                                                   .openConnection();                                   InputStream is = conn.getInputStream();                                   FileOutputStream fos = new FileOutputStream(file);                                   byte[] buf = new byte[256];                                   conn.connect();                                   int count = 0;                                   if (conn.getResponseCode()==200) {                                          while ((count=is.read(buf))>0) {                                                        fos.write(buf, 0, count);            }                                   }                                     conn.disconnect();                                   fos.close();                                   is.close();                           } catch (IOException e) {                                   // TODO Auto-generated catch block                                     e.printStackTrace();                           }                   } catch (MalformedURLException e) {                           // TODO Auto-generated catch block                             e.printStackTrace();                   }                     return file;           }

此工程还可扩展,比如获取未安装apk或者已安装apk的版本、图标等资源,和已安装的apk进行版本比较,以确定是否要升级新版本。关于此可以看下我的另一篇博文《Android获取未安装和已安装apk的版本、图标等资源》。

Ok,到此结束!


  评论这张
 
阅读(1392)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018