码迷,mamicode.com
首页 > 其他好文 > 详细

1.闪屏页面(Splash)

时间:2015-10-29 10:46:48      阅读:411      评论:0      收藏:0      [点我收藏+]

标签:

闪屏页面(Splash) 

展示logo,公司品牌
项目初始化
检测版本更新
校验程序合法性(比如:判断是否有网络,有的话才运行)

 检测版本更新
技术分享
  1. 在toncat中放入一个json数据用来判断版本信息
  1. {"versionName": "2.0", "versionCode": 2, "description": "新增NB功能,赶紧体验!!!",
  2. "downloadUrl": "http://www.baidu.com"}
2.闪屏页面布局有一个textview用来显示版本号,一个圆圈进度条,一个textview用来显示下载进度
3.打包一个软件用来升级,此时需要注意签名

## 签名冲突 ##

> 如果两个应用程序, 包名相同, 但是签名不同, 就无法覆盖安装

> 正式签名

1. 有效期比较长,一般大于25年
2. 需要设置密码
3. 正式发布应用时,必须用正式签名来打包

> 测试签名(debug.keystore)

1. 有效期是1年,很短
2. 有默认的别名,密码, alias=android, 密码是androiddebugkey
3. 在eclipse中直接运行项目是,系统默认采用此签名文件

> 如果正式签名丢失了怎么办?

1. 修改包名, 发布, 会发现有两个手机卫士, 用户会比较纠结
2. 请用户先删掉原来的版本,再进行安装, 用户会流失
3. 作为一名有经验的开发人员,请不要犯这种低级错误

4.将闪屏页设为初始界面,以下是闪屏页的逻辑
  1. public class SplashActivity extends Activity {
  2. protected static final int CODE_UPDATE_DIALOG = 0;
  3. protected static final int CODE_URL_ERROR = 1;
  4. protected static final int CODE_NET_ERROR = 2;
  5. protected static final int CODE_JSON_ERROR = 3;
  6. protected static final int CODE_ENTER_HOME = 4;// 进入主页面
  7. private TextView tvVersion;
  8. private TextView tvProgress;// 下载进度展示
  9. // 服务器返回的信息
  10. private String mVersionName;// 版本名
  11. private int mVersionCode;// 版本号
  12. private String mDesc;// 版本描述
  13. private String mDownloadUrl;// 下载地址
  14. private Handler mHandler = new Handler() {
  15. public void handleMessage(android.os.Message msg) {
  16. switch (msg.what) {
  17. case CODE_UPDATE_DIALOG:
  18. showUpdateDailog();
  19. break;
  20. case CODE_URL_ERROR:
  21. Toast.makeText(SplashActivity.this, "url错误", Toast.LENGTH_SHORT)
  22. .show();
  23. enterHome();
  24. break;
  25. case CODE_NET_ERROR:
  26. Toast.makeText(SplashActivity.this, "网络错误", Toast.LENGTH_SHORT)
  27. .show();
  28. enterHome();
  29. break;
  30. case CODE_JSON_ERROR:
  31. Toast.makeText(SplashActivity.this, "数据解析错误",
  32. Toast.LENGTH_SHORT).show();
  33. enterHome();
  34. break;
  35. case CODE_ENTER_HOME:
  36. enterHome();
  37. break;
  38. default:
  39. break;
  40. }
  41. };
  42. };
  43. private SharedPreferences mPref;
  44. private RelativeLayout rlRoot;// 根布局
  45. @Override
  46. protected void onCreate(Bundle savedInstanceState) {
  47. super.onCreate(savedInstanceState);
  48. setContentView(R.layout.activity_splash);
  49. tvVersion = (TextView) findViewById(R.id.tv_version);
  50. tvVersion.setText("版本名:" + getVersionName());
  51. tvProgress = (TextView) findViewById(R.id.tv_progress);// 默认隐藏
  52. rlRoot = (RelativeLayout) findViewById(R.id.rl_root);
  53. mPref = getSharedPreferences("config", MODE_PRIVATE);
  54. // 判断是否需要自动更新
  55. boolean autoUpdate = mPref.getBoolean("auto_update", true);
  56. if (autoUpdate) {
  57. checkVerson();
  58. } else {
  59. mHandler.sendEmptyMessageDelayed(CODE_ENTER_HOME, 2000);// 延时2秒后发送消息
  60. }
  61. // 渐变的动画效果
  62. AlphaAnimation anim = new AlphaAnimation(0.3f, 1f);
  63. anim.setDuration(2000);
  64. rlRoot.startAnimation(anim);
  65. }
  66. /**
  67. * 获取版本名称
  68. *
  69. * @return
  70. */
  71. private String getVersionName() {
  72. PackageManager packageManager = getPackageManager();
  73. try {
  74. PackageInfo packageInfo = packageManager.getPackageInfo(
  75. getPackageName(), 0);// 获取包的信息
  76. int versionCode = packageInfo.versionCode;
  77. String versionName = packageInfo.versionName;
  78. System.out.println("versionName=" + versionName + ";versionCode="
  79. + versionCode);
  80. return versionName;
  81. } catch (NameNotFoundException e) {
  82. // 没有找到包名的时候会走此异常
  83. e.printStackTrace();
  84. }
  85. return "";
  86. }
  87. /**
  88. * 获取本地app的版本号
  89. *
  90. * @return
  91. */
  92. private int getVersionCode() {
  93. PackageManager packageManager = getPackageManager();
  94. try {
  95. PackageInfo packageInfo = packageManager.getPackageInfo(
  96. getPackageName(), 0);// 获取包的信息
  97. int versionCode = packageInfo.versionCode;
  98. return versionCode;
  99. } catch (NameNotFoundException e) {
  100. // 没有找到包名的时候会走此异常
  101. e.printStackTrace();
  102. }
  103. return -1;
  104. }
  105. /**
  106. * 从服务器获取版本信息进行校验
  107. */
  108. private void checkVerson() {
  109. final long startTime = System.currentTimeMillis();
  110. // 启动子线程异步加载数据
  111. new Thread() {
  112. @Override
  113. public void run() {
  114. Message msg = Message.obtain();
  115. HttpURLConnection conn = null;
  116. try {
  117. // 本机地址用localhost, 但是如果用模拟器加载本机的地址时,可以用ip(10.0.2.2)来替换
  118. URL url = new URL("http://10.0.2.2:8080/update.json");
  119. conn = (HttpURLConnection) url.openConnection();
  120. conn.setRequestMethod("GET");// 设置请求方法
  121. conn.setConnectTimeout(5000);// 设置连接超时
  122. conn.setReadTimeout(5000);// 设置响应超时, 连接上了,但服务器迟迟不给响应
  123. conn.connect();// 连接服务器
  124. int responseCode = conn.getResponseCode();// 获取响应码
  125. if (responseCode == 200) {
  126. InputStream inputStream = conn.getInputStream();
  127. String result = StreamUtils.readFromStream(inputStream);
  128. // System.out.println("网络返回:" + result);
  129. // 解析json
  130. JSONObject jo = new JSONObject(result);
  131. mVersionName = jo.getString("versionName");
  132. mVersionCode = jo.getInt("versionCode");
  133. mDesc = jo.getString("description");
  134. mDownloadUrl = jo.getString("downloadUrl");
  135. // System.out.println("版本描述:" + mDesc);
  136. if (mVersionCode > getVersionCode()) {// 判断是否有更新
  137. // 服务器的VersionCode大于本地的VersionCode
  138. // 说明有更新, 弹出升级对话框
  139. msg.what = CODE_UPDATE_DIALOG;
  140. } else {
  141. // 没有版本更新
  142. msg.what = CODE_ENTER_HOME;
  143. }
  144. }
  145. } catch (MalformedURLException e) {
  146. // url错误的异常
  147. msg.what = CODE_URL_ERROR;
  148. e.printStackTrace();
  149. } catch (IOException e) {
  150. // 网络错误异常
  151. msg.what = CODE_NET_ERROR;
  152. e.printStackTrace();
  153. } catch (JSONException e) {
  154. // json解析失败
  155. msg.what = CODE_JSON_ERROR;
  156. e.printStackTrace();
  157. } finally {
  158. long endTime = System.currentTimeMillis();
  159. long timeUsed = endTime - startTime;// 访问网络花费的时间
  160. if (timeUsed < 2000) {
  161. // 强制休眠一段时间,保证闪屏页展示2秒钟
  162. try {
  163. Thread.sleep(2000 - timeUsed);
  164. } catch (InterruptedException e) {
  165. e.printStackTrace();
  166. }
  167. }
  168. mHandler.sendMessage(msg);
  169. if (conn != null) {
  170. conn.disconnect();// 关闭网络连接
  171. }
  172. }
  173. }
  174. }.start();
  175. }
  176. /**
  177. * 升级对话框
  178. */
  179. protected void showUpdateDailog() {
  180. AlertDialog.Builder builder = new AlertDialog.Builder(this);
  181. builder.setTitle("最新版本:" + mVersionName);
  182. builder.setMessage(mDesc);
  183. // builder.setCancelable(false);//不让用户取消对话框, 用户体验太差,尽量不要用
  184. builder.setPositiveButton("立即更新", new OnClickListener() {
  185. @Override
  186. public void onClick(DialogInterface dialog, int which) {
  187. System.out.println("立即更新");
  188. download();
  189. }
  190. });
  191. builder.setNegativeButton("以后再说", new OnClickListener() {
  192. @Override
  193. public void onClick(DialogInterface dialog, int which) {
  194. enterHome();
  195. }
  196. });
  197. // 设置取消的监听, 用户点击返回键时会触发
  198. builder.setOnCancelListener(new OnCancelListener() {
  199. @Override
  200. public void onCancel(DialogInterface dialog) {
  201. enterHome();
  202. }
  203. });
  204. builder.show();
  205. }
  206. /**
  207. * 下载apk文件
  208. */
  209. protected void download() {
  210. if (Environment.getExternalStorageState().equals(
  211. Environment.MEDIA_MOUNTED)) {
  212. tvProgress.setVisibility(View.VISIBLE);// 显示进度
  213. String target = Environment.getExternalStorageDirectory()
  214. + "/update.apk";
  215. // XUtils
  216. HttpUtils utils = new HttpUtils();
  217. utils.download(mDownloadUrl, target, new RequestCallBack<File>() {
  218. // 下载文件的进度, 该方法在主线程运行
  219. @Override
  220. public void onLoading(long total, long current,
  221. boolean isUploading) {
  222. super.onLoading(total, current, isUploading);
  223. System.out.println("下载进度:" + current + "/" + total);
  224. tvProgress.setText("下载进度:" + current * 100 / total + "%");
  225. }
  226. // 下载成功,该方法在主线程运行
  227. @Override
  228. public void onSuccess(ResponseInfo<File> arg0) {
  229. System.out.println("下载成功");
  230. // 跳转到系统安装页面
  231. Intent intent = new Intent(Intent.ACTION_VIEW);
  232. intent.addCategory(Intent.CATEGORY_DEFAULT);
  233. intent.setDataAndType(Uri.fromFile(arg0.result),
  234. "application/vnd.android.package-archive");
  235. // startActivity(intent);
  236. startActivityForResult(intent, 0);// 如果用户取消安装的话,
  237. // 会返回结果,回调方法onActivityResult
  238. }
  239. // 下载失败,该方法在主线程运行
  240. @Override
  241. public void onFailure(HttpException arg0, String arg1) {
  242. Toast.makeText(SplashActivity.this, "下载失败!",
  243. Toast.LENGTH_SHORT).show();
  244. }
  245. });
  246. } else {
  247. Toast.makeText(SplashActivity.this, "没有找到sdcard!",
  248. Toast.LENGTH_SHORT).show();
  249. }
  250. }
  251. // 如果用户取消安装的话,回调此方法
  252. @Override
  253. protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  254. enterHome();
  255. super.onActivityResult(requestCode, resultCode, data);
  256. }
  257. /**
  258. * 进入主页面
  259. */
  260. private void enterHome() {
  261. Intent intent = new Intent(this, HomeActivity.class);
  262. startActivity(intent);
  263. finish();
  264. }
  265. }












1.闪屏页面(Splash)

标签:

原文地址:http://www.cnblogs.com/liuyu0529/p/4919481.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!