Android apk下载更新,如何实现apk部分更新

1 , 如何实现apk部分更新你如果是在谷歌market上发布的,你把你的新apk发上去 ,新的apk里的android:versionCode要加一 。发布后用户手机上的market客户端就会提醒他更新 , 他下载了新的就会安装新的 。你说的 只更新要更新的地方 , 这你除非自己弄服务器 ,自己提示用户更...
2,android更新完软件后的APK在哪就是说他旧的APK会自动覆盖或删除吗android更新apk时会自动覆盖较旧的版本 。一般更新后的apk会放在system/app目录下面,如果需要可以先获取root权限,再从这个目录下面copy出来 。
3,昨天晚上手机突然下载了一个apk系统更新我想退回之前的老版本如果更新后的风格很不适应的话,可以去手机的设置->备份与重置->备份你的数据->恢复出厂设置;但是如果系统是大版本的升级,恢复出厂设置不能退到低版本,比如Android7.X可以退到7.0,但是8.X就只能退到8.0;不能由恢复出厂设置回退的版本,需要一点点专业的知识自己去下官方的系统安装包进行刷机换一部新手机就可以了 , 这个问题很简单再看看别人怎么说的 。一般后缀是APK的是安卓应用程序,不是系统更新 。建议到手机已安装的应用里查看一下是否安装了新应用,一般APK文件就是应用打包文件 , 点击就可以安装的 。如果下载了没安装,那么你的系统还是旧版本,删除那个apk文件就行了 。如果已经安装好了的话,那么可以在设置–关于手机里看清自己的手机型号,到官网上下载对应的旧版本系统固件 , 根据百度的教程来刷机 , 刷回原来版本 。【Android apk下载更新,如何实现apk部分更新】
4,android 怎么检查新版本并且更新一、准备1.检测当前版本的信息AndroidManifest.xml-->manifest-->android:versionName 。2.从服务器获取版本号(版本号存在于xml文件中)并与当前检测到的版本进行匹配,如果不匹配,提示用户进行升级,如果匹配则进入程序主界面 。3.当提示用户进行版本升级时 , 如果用户点击了确定 , 系统将自动从服务器上下载并进行自动升级,如果点击取消将进入程序主界面 。二、效果图三、必要说明服务器端存储apk文件,同时有version.xml文件便于比对更新 。<?xml version="1.0" encoding="utf-8"?><info><version>2.0</version><url>http://192.168.1.187:8080/mobilesafe.apk</url><description>检测到最新版本,请及时更新!</description><url_server>http://192.168.1.99/version.xml</url_server></info>通过一个实体类获取上述信息 。package com.android;public class UpdataInfoprivate String version;private String url;private String description;private String url_server;public String getUrl_server()return url_server;}public void setUrl_server(String url_server)this.url_server = url_server;}public String getVersion()return version;}public void setVersion(String version)this.version = version;}public String getUrl()return url;}public void setUrl(String url)this.url = url;}public String getDescription()return description;}public void setDescription(String description)this.description = description;}}apk和版本信息地址都放在服务器端的version.xml里比较方便,当然如果服务器端不变动 , apk地址可以放在strings.xml里,不过版本号信息是新的,必须放在服务器端,xml地址放在strings.xml 。<?xml version="1.0" encoding="utf-8"?><resources><string name="hello">Hello World, VersionActivity!</string><string name="app_name">Version</string><string name="url_server">http://192.168.1.99/version.xml</string></resources>不知道读者发现没有 , 笔者犯了个错误,那就是url_server地址必须放在本地,否则怎么读取version.xml,所以url_server不必在实体类和version里添加,毕竟是现需要version地址也就是url_server,才能够读取version 。三、代码实现<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="fill_parent"android:layout_height="fill_parent"android:orientation="vertical" ><Buttonandroid:id="@+id/btn_getVersion"android:text="检查更新"android:layout_width="wrap_content"android:layout_height="wrap_content"/></LinearLayout>package com.android;import java.io.InputStream;import org.xmlpull.v1.XmlPullParser;import android.util.Xml;public class UpdataInfoParserpublic static UpdataInfo getUpdataInfo(InputStream is) throws ExceptionXmlPullParserparser = Xml.newPullParser();parser.setInput(is, "utf-8");int type = parser.getEventType();UpdataInfo info = new UpdataInfo();while(type != XmlPullParser.END_DOCUMENT )switch (type)case XmlPullParser.START_TAG:if("version".equals(parser.getName()))info.setVersion(parser.nextText());}else if ("url".equals(parser.getName()))info.setUrl(parser.nextText());}else if ("description".equals(parser.getName()))info.setDescription(parser.nextText());}break;}type = parser.next();}return info;}}package com.android;import java.io.File;import java.io.InputStream;import java.net.HttpURLConnection;import java.net.URL;import android.app.Activity;import android.app.AlertDialog;import android.app.AlertDialog.Builder;import android.app.ProgressDialog;import android.content.DialogInterface;import android.content.Intent;import android.content.pm.PackageInfo;import android.content.pm.PackageManager;import android.net.Uri;import android.os.Bundle;import android.os.Environment;import android.os.Handler;import android.os.Message;import android.util.Log;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.TextView;import android.widget.Toast;public class VersionActivity extends Activityprivate final String TAG = this.getClass().getName();private final int UPDATA_NONEED = 0;private final int UPDATA_CLIENT = 1;private final int GET_UNDATAINFO_ERROR = 2;private final int SDCARD_NOMOUNTED = 3;private final int DOWN_ERROR = 4;private Button getVersion;private UpdataInfo info;private String localVersion;@Overridepublic void onCreate(Bundle savedInstanceState)super.onCreate(savedInstanceState);setContentView(R.layout.main);getVersion = (Button) findViewById(R.id.btn_getVersion);getVersion.setOnClickListener(new OnClickListener()@Overridepublic void onClick(View v)trylocalVersion = getVersionName();CheckVersionTask cv = new CheckVersionTask();new Thread(cv).start();} catch (Exception e)// TODO Auto-generated catch blocke.printStackTrace();}}});}private String getVersionName() throws Exception//getPackageName()是你当前类的包名,0代表是获取版本信息PackageManager packageManager = getPackageManager();PackageInfo packInfo = packageManager.getPackageInfo(getPackageName(),0);return packInfo.versionName;}public class CheckVersionTask implements RunnableInputStream is;public void run()tryString path = getResources().getString(R.string.url_server);URL url = new URL(path);HttpURLConnection conn = (HttpURLConnection) url.openConnection();conn.setConnectTimeout(5000);conn.setRequestMethod("GET");int responseCode = conn.getResponseCode();if (responseCode == 200)// 从服务器获得一个输入流is = conn.getInputStream();}info = UpdataInfoParser.getUpdataInfo(is);if (info.getVersion().equals(localVersion))Log.i(TAG, "版本号相同");Message msg = new Message();msg.what = UPDATA_NONEED;handler.sendMessage(msg);// LoginMain();} elseLog.i(TAG, "版本号不相同 ");Message msg = new Message();msg.what = UPDATA_CLIENT;handler.sendMessage(msg);}} catch (Exception e)Message msg = new Message();msg.what = GET_UNDATAINFO_ERROR;handler.sendMessage(msg);e.printStackTrace();}}}Handler handler = new Handler()@Overridepublic void handleMessage(Message msg)// TODO Auto-generated method stubsuper.handleMessage(msg);switch (msg.what)case UPDATA_NONEED:Toast.makeText(getApplicationContext(), "不需要更新",Toast.LENGTH_SHORT).show();case UPDATA_CLIENT://对话框通知用户升级程序showUpdataDialog();break;case GET_UNDATAINFO_ERROR://服务器超时Toast.makeText(getApplicationContext(), "获取服务器更新信息失败", 1).show();break;case DOWN_ERROR://下载apk失败Toast.makeText(getApplicationContext(), "下载新版本失败", 1).show();break;}}};/*** 弹出对话框通知用户更新程序** 弹出对话框的步骤:*1.创建alertDialog的builder.*2.要给builder设置属性, 对话框的内容,样式,按钮*3.通过builder 创建一个对话框*4.对话框show()出来*/protected void showUpdataDialog()AlertDialog.Builder builer = new Builder(this);builer.setTitle("版本升级");builer.setMessage(info.getDescription());//当点确定按钮时从服务器上下载 新的apk 然后安装?builer.setPositiveButton("确定", new DialogInterface.OnClickListener()public void onClick(DialogInterface dialog, int which)Log.i(TAG, "下载apk,更新");downLoadApk();}});builer.setNegativeButton("取消", new DialogInterface.OnClickListener()public void onClick(DialogInterface dialog, int which)// TODO Auto-generated method stub//do sth}});AlertDialog dialog = builer.create();dialog.show();}/** 从服务器中下载APK*/protected void downLoadApk()final ProgressDialog pd;//进度条对话框pd = newProgressDialog(this);pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);pd.setMessage("正在下载更新");pd.show();new Thread()@Overridepublic void run()tryFile file = DownLoadManager.getFileFromServer(info.getUrl(), pd);sleep(3000);installApk(file);pd.dismiss(); //结束掉进度条对话框} catch (Exception e)Message msg = new Message();msg.what = DOWN_ERROR;handler.sendMessage(msg);e.printStackTrace();}}}.start();}//安装apkprotected void installApk(File file)Intent intent = new Intent();//执行动作intent.setAction(Intent.ACTION_VIEW);//执行的数据类型intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");startActivity(intent);}}package com.android;import java.io.BufferedInputStream;import java.io.File;import java.io.FileOutputStream;import java.io.InputStream;import java.net.HttpURLConnection;import java.net.URL;import android.app.ProgressDialog;import android.os.Environment;public class DownLoadManagerpublic static File getFileFromServer(String path, ProgressDialog pd) throws Exception//如果相等的话表示当前的sdcard挂载在手机上并且是可用的if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))URL url = new URL(path);HttpURLConnection conn =(HttpURLConnection) url.openConnection();conn.setConnectTimeout(5000);//获取到文件的大小pd.setMax(conn.getContentLength());InputStream is = conn.getInputStream();File file = new File(Environment.getExternalStorageDirectory(), "updata.apk");FileOutputStream fos = new FileOutputStream(file);BufferedInputStream bis = new BufferedInputStream(is);byte[] buffer = new byte[1024];int len ;int total=0;while((len =bis.read(buffer))!=-1)fos.write(buffer, 0, len);total+= len;//获取当前下载量pd.setProgress(total);}fos.close();bis.close();is.close();return file;}elsereturn null;}}}<uses-permission android:name="android.permission.INTERNET"/><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>5 , Android APK增量更新哪种实现方案最好目前主流差分更新实现有BSDiff/Patch、HPatch、XDelta三种,具体可参考Android 增量更新全解升级机制:我们打算采用delta编码的patch升级android应用 。新的升级机制可以描述如下:1、在服务器上生成一个patch 。2、下载patch到手机中 。3、通过补丁获取一个已安装应用的新的安装apk 。4、安装应用的新版本并删掉旧的版本和patch 。统计数据:我们当前正在研究应用怎样在android中升级 。这个研究结果将允许我们在新的升级机制下节约大量的流量 。我们创建了一个android应用用来收集统计数据(可能会用于将来的研究) 。应用会收集以下数据:1、应用的名字,版本,大小和每个应用最后升级的时间 。2、统计wifi和3g的链接状态 。谷歌增量升级技术:在谷歌2012i/o大会上宣布googleplaystroe的增量升级技术 。它始于八月中旬 。他们使用跟我们相同的升级机制 。比较两个应用的不同,并将patch部署在终端上 。

    推荐阅读