做接受老大的要求,一定要在今天完成下载安装apk的方法;
下载安装在有SD卡的手机、电视上是很容易的实现的,网上有方法众多;
但是没有SD卡的情况下却不是那么容易找,我找了很久,也没有人给个具体的答案,最后自己解决的方案如下:
1、解析包错误,重点在权限上,无论你下载到手机的哪,都要权限;如果没有会有如下的提示错误:
<span style="font-size:18px;">Parse error when parsing manifest. Discontinuing installation
AndroidManifest.xml of /data/data/com.hsee.o2o/files/***meitu.apk
java.io.FileNotFoundException: AndroidManifest.xml</span>
可以看出是权限的问题,就是不能对文件操作,那就对apk修改权限不就行了。
修改权限的方法如下:
/**
* @param updateDir 就是可以执行的文件
*void 修改文件的权限,可读、可写、可执行
* @date 2015年9月13日
* @author liuyonghong
*/
private void setUpdateDir(File updateDir) {
try {
Process p = Runtime.getRuntime().exec("chmod 777 " + updateDir );
int status = p.waitFor();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
2、确定文件路径和文件名字
<pre class="html" name="code"> //这个判断是有SD卡的情况的下载情况路径 if (android.os.Environment.MEDIA_MOUNTED.equals(android.os.Environment
.getExternalStorageState())) {
DebugLog.i(TAG, "MEDIA_MOUNTED");
updateDir = new File(Environment.getExternalStorageDirectory(),
Global.downloadDir);
updateFile = new File(updateDir.getPath(),titleId+ ".apk");
//titleID是文件名
}else{
updateDir=new File(Environment.getDataDirectory().toString());
//获取"/data"路径,问什么是/data,下面会说。
DebugLog.i(TAG, "Environment="+Environment.getDataDirectory().toString());
updateFile = new File(updateDir.getPath(),titleId+ ".apk");
DebugLog.i(TAG,"updateFile="+updateFile.toString());
}
3、为什么在没有SD卡的情况下是“/data”
如下图,是查看了手机内置存储的路径权限一表,是系统的文件夹的只有/data。其他都要root。
4、确定了路径就是显示一个NotificationManager,来看一下下载的进度,并且启动一个线程来下载;
this.updateNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
this.updateNotification = new Notification();
//点击通知栏以后自动消失的标记
this.updateNotification.flags |= Notification.FLAG_AUTO_CANCEL;
// 设置下载过程中,点击通知栏,回到主界面
updateIntent = new Intent(this, O2oMainActivity.class);
updatePendingIntent = PendingIntent.getActivity(this, 0, updateIntent,
0);
// 设置通知栏显示内容
updateNotification.icon = R.drawable.logo;
updateNotification.tickerText = "开始下载";
updateNotification.setLatestEventInfo(this, R.string.app_name+"", "0%",
updatePendingIntent);
// 发出通知
updateNotificationManager.notify(0, updateNotification);
// 开启一个新的线程下载,如果使用Service同步下载,会导致ANR问题,Service本身也会阻塞
new Thread(new UpdateRunnable()).start();// 这个是下载的重点,是下载的过程
线程代码:
//这里有最关键的几个步骤
class UpdateRunnable implements Runnable { Message message = updateHandler.obtainMessage();
public void run() { message.what = DOWNLOAD_COMPLETE; try { // 增加权限<uses-permission // android:name="android.permission.WRITE_EXTERNAL_STORAGE">; if (!updateDir.exists()) { updateDir.mkdirs(); } if (!updateFile.exists()) { updateFile.createNewFile(); } setUpdateDir(updateFile);//这个在创建了下载了这个文件就改变了它的权限,apk就可以执行安装了;</span> // 增加权限<uses-permission // android:name="android.permission.INTERNET">; long downloadSize = downloadUpdateFile( downloadUrl, updateFile); if (downloadSize > 0) { // 下载成功 updateHandler.sendMessage(message); } } catch (Exception ex) { ex.printStackTrace(); message.what = DOWNLOAD_FAIL; // 下载失败 updateHandler.sendMessage(message); } } }
4、其他的下载代码我就不写下去了,最关键的也就几行代码而已,其他的其他高手也写过了;
下载、自动识别安装的过程都在一个文件UpdateVersionService.java
最后别忘了如下如下代码打开:
<service android:name="com.o2o.uitl.UpdateVersionService" android:exported="false" />
Intent updateIntent = new Intent(O2oMainActivity.this,UpdateVersionService.class
O2oMainActivity.this.startService(updateIntent);
写代码时有的代码参考了网上的代码,如有涉及版权请提醒;
UpdateVersionService.java百度网盘下载如下:
链接:http://pan.baidu.com/s/1jGs5ZCE 密码:0iuy