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

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

2012-05-27 14:55 555 查看
最近在研究Android动态加载APK技术,偶有小得,共享一下,欢迎交流。

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

截图:

被调用工程TestB:

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

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文件:

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是否已安装呢:

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)安装,如果已安装便可代码获取其资源:

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组件启动被调用工程:

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类,面向的是应用层:

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,到此结束,本人QQ:957411207,欢迎交流。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐