binbinyang---Android自动检测更新功能的实现--杨彬
2016-04-24 17:17
603 查看
今天来说说 安卓开发中任何APP都会要用到的升级 更新的问题
首先写了一个 在通知栏弹出 一个简单的 带有图片.文字的 更新提示
public class MainActivity extends Activity implements OnClickListener{ public static final int NOTIFICATION_ID = 24; private Button but; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); but = (Button)findViewById(R.id.but); but.setOnClickListener(this); } @Override public void onClick(View v) { // TODO Auto-generated method stub switch (v.getId()) { case R.id.but: Builder builder = new NotificationCompat.Builder(MainActivity.this); builder.setSmallIcon(R.drawable.ic_launcher); builder.setContentTitle("下载"); builder.setContentText("正在下载"); Notification notification= builder.build(); NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); /** * id NOTIFICATION_ID通过这个ID 来更新 */ manager.notify(NOTIFICATION_ID,notification); break; default: break; } } }
下面是关于友盟---自动更新升级下载的步骤
1.集成过程客户端集成
2首先到友盟官网下载更新的SDK,复制jar包到目标项目中的libs目录:
3. 配置AndroidManifest.xml
android.permission.WRITE_EXTERNAL_STORAGE权限允许将下载的apk保存到sd卡中。
android.permission.ACCESS_NETWORK_STATE权限允许检查网络状态,从而根据不同网络环境决定何种下载策略,务必添加该权限。
3.2 添加APPKEY和渠道到
<application>标签下: (如果已经集成了统计SDK等友盟其他服务,不需要重复添加APPKEY)
<meta-data android:value="YOUR APP KEY" android:name="UMENG_APPKEY"/> <meta-data android:value="Channel ID" android:name="UMENG_CHANNEL"/>
[/code]
UMENG_APPKEY:用来定位该应用的唯一性,用您该应用的UMENG APPKEY,替换value中的"YOUR APP KEY"。
UMENG_CHANNEL:用来标注应用推广渠道,不同渠道可以上传不同更新包,您可以使用20位以内的英文和数字为渠道定名,替换value中的"Channel ID"。如果不改动,将代表默认渠道。
(特别提示:如果需要使用友盟自动更新多渠道更新,必须先集成友盟统计SDK)
渠道ID
请参考第5节如何上传APK。
3.3 添加Service和Activity到
<application>标签下: (请注意:v2.4的SDK中,对话框改为Activity实现)
注意
com.umeng包名可能有变,如果不能下载,请检查包名,替换成正确的包名。
<service android:name="com.umeng.update.net.DownloadingService" android:process=":DownloadingService" > </service> <activity android:name="com.umeng.update.UpdateDialogActivity" android:theme="@android:style/Theme.Translucent.NoTitleBar" > </activity>
4.调用接口
<pre name="code" class="html">public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
UmengUpdateAgent.update(this);
}
5.上传最新的APK
<h2 id="1_5" style="box-sizing: border-box; font-family: 'Helvetica Neue', Helvetica, 'Microsoft Yahei', Arial, sans-serif; font-weight: normal; line-height: 1.1; color: rgb(62, 62, 62); margin: 1em 0px 0.25em; font-size: 24px; padding: 0.5em; text-align: justify;"> <img src="https://img-blog.csdn.net/20160423190619605?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" /><img src="https://img-blog.csdn.net/20160423190625855?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" /></h2>
public class MainActivity extends Activity implements OnClickListener { //public static final int NOTIFICATION_ID = 24; private Button but; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); UmengUpdateAgent.update(this); }
如果是自己写一个
升级 跟检测是否当前是最新版本
public class UpdateManager { private ProgressBar mpProgressBar; private Dialog mDownloadDialog; private String mSavePath; private int mProgress;// 进度条值 private boolean mIsCancel = false; private static final int DOWNLOADING = 1; private static final int DOWNLOAD_FINISH = 2; private static final String PATH = "http://192.168.0.103/autoupdate/version.html"; private String mVersion_code; private String mVersion_name; private String mVersion_desc; private String mVersion_path; private Context mContext; public UpdateManager(Context context) { mContext = context; } private Handler mGetVersionHandler = new Handler() { public void handleMessage(Message msg) { JSONObject jsonObject = (JSONObject) msg.obj; // Toast.makeText(mContext, "出错了" + jsonObject.toString(), // 1).show(); System.out.println(jsonObject.toString() + "=========="); try { mVersion_code = jsonObject.getString("version_code"); mVersion_name = jsonObject.getString("version_name"); mVersion_desc = jsonObject.getString("version_desc"); mVersion_path = jsonObject.getString("version_path"); if (isUpdate()) { Toast.makeText(mContext, "需要更新", Toast.LENGTH_LONG).show(); // 需要更新 显示要更新的提示对话框 showNoticeDialog(); } else { Toast.makeText(mContext, "不需要更新", Toast.LENGTH_LONG).show(); } } catch (Exception e) { // TODO: handle exception } }; }; private Handler mUpdateProgressHandler = new Handler() { public void handleMessage(Message msg) { switch (msg.what) { case DOWNLOADING: mpProgressBar.setProgress(mProgress); break; case DOWNLOAD_FINISH: // 隐藏 销毁 下载对话框 mDownloadDialog.dismiss(); // 安装本地apk文件 break; default: break; } }; }; /* * 检测软件是否需要更新 */ public void checkUpdate() { RequestQueue requestQueue = Volley.newRequestQueue(mContext); JsonObjectRequest request = new JsonObjectRequest(PATH, null, new Listener<JSONObject>() { @Override public void onResponse(JSONObject jsonObject) { Message msg = Message.obtain(); msg.obj = jsonObject; mGetVersionHandler.sendMessage(msg); } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError arg0) { // TODO Auto-generated method stub // Toast.makeText(mContext, "出错了" + arg0.toString(), 1) // .show(); System.out.println(arg0.toString() + "bbbbbbbbbbb"); } }); requestQueue.add(request); } /* * 与本地版本比较判断是否需要更新 */ protected boolean isUpdate() { int serverVersion = Integer.parseInt(mVersion_code); int localVersion = 1; /** * 拿到本地的包名 */ try { localVersion = mContext.getPackageManager().getPackageInfo( "com.example.notification", 0).versionCode; } catch (NameNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } if (serverVersion > localVersion) return true; else return false; } /* * 有更新时显示提示对话框 */ protected void showNoticeDialog() { AlertDialog.Builder builder = new Builder(mContext); builder.setTitle("提示"); String message = "软件有更新,需要下载吗\n" + mVersion_desc; builder.setMessage(message); /** * 确认的那个按钮 */ builder.setPositiveButton("更新", new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // 隐藏当前对话框 dialog.dismiss(); // 显示下载的对话框 showDownloadDialog(); } }); /** * 取消的按钮 */ builder.setNegativeButton("取消", new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { Toast.makeText(mContext, "取消", 1).show(); // 隐藏当前对话框 dialog.dismiss(); } }); builder.create().show(); } /* * 显示正在下载对话框 */ protected void showDownloadDialog() { AlertDialog.Builder builder = new Builder(mContext); View view = LayoutInflater.from(mContext).inflate( R.layout.dialog_progress, null); builder.setTitle("正在下载"); mpProgressBar = (ProgressBar) view.findViewById(R.id.prog); builder.setView(view); builder.setNegativeButton("取消", new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // TODO Auto-generated method stub // 隐藏对话框 dialog.dismiss(); // 设置下载状态为取消 } }); mDownloadDialog = builder.create();// 创建对话框 mDownloadDialog.show(); // 下载文件 downloadAPK(); } /* * 开启新线程下载文件 */ private void downloadAPK() { new Thread(new Runnable() { @Override public void run() { try { if (Environment.getExternalStorageState().equals( Environment.MEDIA_MOUNTED)) { String sdPath = Environment .getExternalStorageDirectory() + "/"; mSavePath = sdPath + "jikedownload"; File dir = new File(mSavePath); if (!dir.exists()) dir.mkdir(); // 下载文件 HttpURLConnection conn = (HttpURLConnection) new URL( mVersion_path).openConnection(); conn.connect(); InputStream is = conn.getInputStream(); int length = conn.getContentLength(); File apkFile = new File(mSavePath, mVersion_name); FileOutputStream fos = new FileOutputStream(apkFile); int count = 0; byte[] buffer = new byte[1024]; while (!mIsCancel) { int numread = is.read(buffer); count += numread; // 计算进度条的当前位置 mProgress = (int) (((float) count / length) * 1); // 更新进度条 mUpdateProgressHandler .sendEmptyMessage(DOWNLOADING); // 下载完成 if (numread < 0) { mUpdateProgressHandler .sendEmptyMessage(DOWNLOAD_FINISH); break; } fos.write(buffer, 0, numread); } fos.close(); is.close(); } } catch (Exception e) { e.printStackTrace(); } } }).start(); } /* * 下载到本地后执行安装 */ protected void installAPK() { } }
相关文章推荐
- Android For JNI(六)——交叉编译,NDK概述以及文件结构,编写自己的第一个JNI工程
- Android For JNI(六)——交叉编译,NDK概述以及文件结构,编写自己的第一个JNI工程
- 固定ListView的HeadViev的高度
- android仿IOS底部弹对话框
- Android开发性能优化总结(二)
- [android] 新闻客户端实现左侧导航点击切换
- Android-ViewFlipper动画导航(可手动翻页)
- 续 Android APK免安装启动
- 开发中最常用的GitHub上 优秀的 Android 开源项目整理(精品)
- 《Android 开发艺术探索》读书笔记六 IPC机制之Binder
- Mac OS下 Android studio更新SDK的办法
- android 中 listview 设置自动匹配高度
- Android开发:最全面、最易懂的Android屏幕适配解决方案
- 文章标题
- Android中使用Camera类编写手机拍照App的实例教程
- Android—ProgressBar进度条应用
- Android控件颜色设置总结
- android studio导入第三方库(以SlidingMenu、xUtils为例)
- Android文件图片上传的详细讲解(二)--AsyncTask的用法
- Android进阶笔记17:Android手机屏幕坐标系