详谈闪屏页相关处理

根据功能模块划分(Android开发推荐此方法)

- Activity   mobilesafe.activty
    - 后台服务   mobilesafe.service
    - 广播接受者 mobilesafe.receiver
    - 数据库 mobilesafe.db.dao
    - 对象(java bean) mobilesafe.domain/bean
    - 自定义控件 mobilesafe.view
    - 工具类 mobilesafe.utils
    - 业务逻辑 mobilesafe.engine

闪屏页面(Splash)作用:

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

AndroidMinifest.xml      四大组件都需要在这里配置

<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.mxn.mobilesafe" android:versionCode="1" //版本号 android:versionName="1.0" > //版本名 <uses-sdk android:minSdkVersion="16" android:targetSdkVersion="21" /> //项目所需的权限 <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <uses-permission android:name="android.permission.READ_CONTACTS" /> <uses-permission android:name="android.permission.SEND_SMS" /> <uses-permission android:name="android.permission.RECEIVE_SMS" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" /> <uses-permission android:name="android.permission.VIBRATE" /> <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" /> <uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES"/> <uses-permission android:name="android.permission.GET_PACKAGE_SIZE"/> <uses-permission android:name="android.permission.CLEAR_APP_CACHE"/> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > //主题 //activity的注册 <activity android:name="com.mxn.mobilesafe.activity.SplashActivity" android:label="@string/app_name" > <intent-filter> //起始的activity <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name="com.mxn.mobilesafe.activity.HomeActivity" /> <activity android:name="com.mxn.mobilesafe.activity.SettingActivity" /> <activity android:name="com.mxn.mobilesafe.activity.LostFindActivity" > </activity> <activity android:name="com.mxn.mobilesafe.activity.Setup1Activity" > </activity> <activity android:name="com.mxn.mobilesafe.activity.Setup2Activity" > </activity> <activity android:name="com.mxn.mobilesafe.activity.Setup3Activity" > </activity> <activity android:name="com.mxn.mobilesafe.activity.Setup4Activity" > </activity> <activity android:name="com.mxn.mobilesafe.activity.ContactActivity" > </activity> <activity android:name="com.mxn.mobilesafe.activity.AtoolsActivity" > </activity> <activity android:name="com.mxn.mobilesafe.activity.AddressActivity" > </activity> <activity android:name="com.mxn.mobilesafe.activity.CallSafeActivity" > </activity> <activity android:name="com.mxn.mobilesafe.activity.AppManagerActivity" > </activity> <activity android:name="com.mxn.mobilesafe.activity.TaskManagerActivity"> </activity> <activity android:name="com.mxn.mobilesafe.activity.TaskManagerSettingActivity"> </activity> <activity android:name="com.mxn.mobilesafe.activity.AntivirusActivity"></activity> <activity android:name="com.mxn.mobilesafe.activity.AppLockActivity"></activity> <activity android:name="com.mxn.mobilesafe.activity.CleanCacheActivity"></activity> //广播接收者的 注册 <receiver android:name=".receiver.BootCompleteReceiver" > <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED" /> </intent-filter> </receiver> <receiver android:name=".receiver.SmsReceiver" > <intent-filter android:priority="2147483647" > <action android:name="android.provider.Telephony.SMS_RECEIVED" /> </intent-filter> </receiver> <!-- <receiver android:name=".receiver.OutCallReceiver" >静态注册的广播 <intent-filter> <action android:name="android.intent.action.NEW_OUTGOING_CALL" /> </intent-filter> </receiver> --> //服务的注册 <service android:name="com.mxn.mobilesafe.service.LocationService" > </service> <service android:name="com.mxn.mobilesafe.service.AddressService" > </service> <service android:name="com.mxn.mobilesafe.service.KillProcessService"></service> <service android:name="com.mxn.mobilesafe.service.WatchDogService"></service> </application> </manifest>

activity_splash.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.mxn.mobilesafe.SplashActivity" android:background="@drawable/launcher_bg" android:id="@+id/rl_root"> <TextView android:id="@+id/tv_version" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:layout_marginBottom="202dp" android:textSize="22sp" android:textColor="#000" android:shadowColor="#f00" //对版本号设置阴影 android:shadowDx="1" android:shadowDy="1" android:shadowRadius="1" android:text="版本号:1.0" /> <ProgressBar android:id="@+id/progressBar1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignTop="@+id/tv_version" android:layout_centerHorizontal="true" android:layout_marginTop="54dp" /> <TextView android:id="@+id/tv_progress" android:visibility="gone" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_alignParentLeft="true" android:textColor="#f00" android:textSize="16sp" android:text="下载进度" /> </RelativeLayout>

SplashActivity.java

public class SplashActivity extends Activity { protected static final int CODE_UPDATE_DIALOG; protected static final int CODE_URL_ERROR; protected static final int CODE_NET_ERROR; protected static final int CODE_JSON_ERROR; protected static final int CODE_ENTER_HOME; private TextView tvVersion; private TextView tvProgress;// 下载进度展示 // 服务器返回的信息 private String mversionName;// 版本名 private int mversionCode;// 版本号 private String mDesc;// 版本描述 private String mdowmloadurl;// 下载地址 private Handler mHandler = new Handler() { public void handleMessage(android.os.Message msg) { switch (msg.what) { case CODE_UPDATE_DIALOG: showUpdateDialog();//显示升级对话框 break; case CODE_URL_ERROR: Toast.makeText(SplashActivity.this, "url错误", Toast.LENGTH_SHORT).show(); enterHome(); break; case CODE_NET_ERROR: Toast.makeText(SplashActivity.this, "网络错误", Toast.LENGTH_SHORT).show(); enterHome(); break; case CODE_JSON_ERROR: Toast.makeText(SplashActivity.this, "json数据解析解析错误", Toast.LENGTH_SHORT).show(); enterHome(); break; case CODE_ENTER_HOME: enterHome(); break; default: break; } }; }; private SharedPreferences sp; private RelativeLayout rlRoot; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_splash); tvVersion = (TextView) findViewById(R.id.tv_version); tvProgress = (TextView) findViewById(R.id.tv_progress);// 默认隐藏 tvVersion.setText("版本号:" + getVersionCode());//给版本号设置内容,动态获取的值 rlRoot = (RelativeLayout) findViewById(R.id.rl_root); //判断是否需要自动更新 sp = getSharedPreferences("config", MODE_PRIVATE); boolean autoUpdate = sp.getBoolean("auto_update", true); copyDB("address.db");//拷贝归属地查询数据库 copyDB("antivirus.db");//拷贝病毒库 //更新病毒库 updateVirus(); if(autoUpdate){ checkVersion(); }else{ mHandler.sendEmptyMessageDelayed(CODE_ENTER_HOME, 2000); } //闪屏页渐变动画效果 AlphaAnimation anim = new AlphaAnimation(0.3f, 1f); anim.setDuration(2000); rlRoot.startAnimation(anim); } //更新病毒数据库 private void updateVirus() { //联网从服务器获取到最近数据的MD5的特征码 HttpUtils httputils = new HttpUtils(); String url = "http://172.28.3.112:8080/virus.json"; httputils.send(HttpMethod.GET, url, new RequestCallBack<String>(){ @Override public void onFailure(HttpException arg0, String arg1) { // TODO Auto-generated method stub } @Override public void onSuccess(ResponseInfo<String> arg0) { // TODO Auto-generated method stub //System.out.println(arg0.result); // JSONObject jsonobject = new JSONObject(arg0.result); // String md5 = jsonobject.getString("md5"); // String desc = jsonobject.getString("desc"); } }); } // 获取本地版本号 private int getVersionCode() { PackageManager packgeManager = getPackageManager();//拿到包的管理者。。包管理器,获取手机里面每个apk的信息(清单文件信息) try {// 获取包的信息。。 getPackageName()当前应用程序的包名 等于 package="com.mxn.mobilesafe" PackageInfo packageInfo = packgeManager.getPackageInfo(getPackageName(), 0); int versionCode = packageInfo.versionCode; String versionName = packageInfo.versionName; System.out.println("versionname=" + versionName + ";" + "versioncode=" + versionCode); return versionCode; } catch (NameNotFoundException e) { // 没有找到包名时 e.printStackTrace(); } return -1; } // 从服务器获取版本信息进行校验 private void checkVersion() { final long startTime = System.currentTimeMillis(); new Thread() {// 网络访问在分线程异步加载数据 public void run() { Message msg = Message.obtain(); HttpURLConnection con = null; try {// 本机地址:localhost 如果用模拟器加载本机的地址:用10.0.0.2来替换 URL url = new URL("http://10.0.2.2:8080/update.json"); // 打开连接 con = (HttpURLConnection) url.openConnection(); con.setRequestMethod("GET");//设置请求方法 con.setConnectTimeout(5000);// 设置连接超时,5S con.setReadTimeout(5000);// 设置响应超时,链接上了,但服务器迟迟没有响应 con.connect();// 链接服务器 int responseCode = con.getResponseCode();//获取响应码 if (responseCode == 200) { // 获取返回值 InputStream inputStream = con.getInputStream(); // 流转化为字符串 String result = StreamUtils.readFormStream(inputStream);//自己定义的StreamUtils工具类 System.out.println("网络结果返回:" + result); //result是一个json字符串,进行解析 // 解析json JSONObject jo = new JSONObject(result); mversionName = jo.getString("versionName");//拿到服务器端的版本名 mversionCode = jo.getInt("versionCode");//拿到服务器端的版本号 mDesc = jo.getString("description");//拿到服务器端的版本描述 mdowmloadurl = jo.getString("downloadUrl");//拿到服务器端的下载链接 System.out.println(mDesc); System.out.println(mversionCode); // 服务器的大于 本地的,判断是否有更新,如果大于 则有更新需要更新,弹出升级对话框 if (mversionCode > getVersionCode()) { System.out.println("进行比较,有版本更新"); msg.what = CODE_UPDATE_DIALOG; // showUpdateDialog();//这句是在子线程更新界面,android不能在子线程更新界面,要想在子线程更新界面所以用到handler. } else {// 如果没有版本更新 msg.what = CODE_ENTER_HOME; } } } catch (MalformedURLException e) {// url错误的异常 msg.what = CODE_URL_ERROR; e.printStackTrace(); } catch (IOException e) {//网络错误异常 // 这个是可以携带数据的msg.obj = msg.what = CODE_NET_ERROR;// what只是一个标识,用来区分消息! e.printStackTrace(); } catch (JSONException e) {// json解析失败 msg.what = CODE_JSON_ERROR; e.printStackTrace(); } finally { long endTime = System.currentTimeMillis(); long timeUsed = endTime - startTime;// 访问网络花费的时间 if (timeUsed < 2000) { try {// 强制休眠2s,保证闪屏页面2S Thread.sleep(2000 - timeUsed); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } mHandler.sendMessage(msg);// 消息发送出去,在handlemessage里进行相应的处理 if (con != null) { con.disconnect(); } } } }.start(); } //升级对话框 private void showUpdateDialog() { System.out.println("正在升级对话框"); // 升级对话框 AlertDialog.Builder builder = new AlertDialog.Builder(this);//context对象 builder.setTitle("最新版本" + mversionName); builder.setMessage(mDesc); // builder.setCancelable(false);//不让用户取消对话框,用户体验太差 builder.setPositiveButton("立即更新", new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // TODO Auto-generated method stub System.out.println("立即更新"); // download方法 download(); } }); builder.setNegativeButton("以后再说", new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { enterHome(); } }); builder.setOnCancelListener(new OnCancelListener() { // 设置取消监听,用户点击返回键时触发 @Override public void onCancel(DialogInterface dialog) { enterHome(); } }); builder.show(); } protected void download() {// 下载服务器端的apk文件 if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { // 判断是否有sd卡,sd卡挂载的时候才可以 tvProgress.setVisibility(View.VISIBLE);// 显示进度 String target = Environment.getExternalStorageDirectory() + "/update.apk";//把文件下载到哪个路径下,sd卡的根目录 // xutils框架,使用HttpUtils工具下载文件,下载一个jar包 HttpUtils utils = new HttpUtils(); utils.download(mdowmloadurl, target, new RequestCallBack<File>() { @Override // 文件下载进度 public void onLoading(long total, long current, boolean isUploading) { // TODO Auto-generated method stub super.onLoading(total, current, isUploading); System.out.println("下载进度:" + current + "/" + total); tvProgress.setText("下载进度:" + current * 100 / total + "%"); } @Override public void onSuccess(ResponseInfo<File> arg0) { // TODO Auto-generated method stub Toast.makeText(SplashActivity.this, "下载成功", Toast.LENGTH_SHORT).show(); // 下载完成之后,跳到系统的安装界面。。Intent.ACTION_VIEW 是xml的action 标签 Intent intent = new Intent(Intent.ACTION_VIEW);//系统的安装界面 intent.addCategory(Intent.CATEGORY_DEFAULT); intent.setDataAndType(Uri.fromFile(arg0.result), "application/vnd.android.package-archive"); // startActivity(intent); startActivityForResult(intent, 0);// 如果用户取消安装,会返回结果,回调方法onActivityResult,下文定义 } @Override public void onFailure(HttpException arg0, String arg1) { // TODO Auto-generated method stub Toast.makeText(SplashActivity.this, "下载失败", Toast.LENGTH_SHORT).show(); } }); } else { Toast.makeText(SplashActivity.this, "没有SD卡", Toast.LENGTH_SHORT).show(); } } @Override//用户取消安装,回调此方法 protected void onActivityResult(int requestCode, int resultCode, Intent data) { // TODO Auto-generated method stub System.out.println("出现安装界面,用户点击取消时。"); enterHome(); super.onActivityResult(requestCode, resultCode, data); } private void enterHome() {// 进入主界面 Intent intent = new Intent(this, HomeActivity.class); startActivity(intent); finish(); } //拷贝数据库,从assets目录下拷贝到data/data/com.mxn.mobilesafe/files目录下 private void copyDB(String dbName){ //获取文件路径 File destFile = new File(getFilesDir(),dbName); if(destFile.exists()){ System.out.println("已存在"); } FileOutputStream out = null; InputStream in = null; try { in = getAssets().open(dbName); out = new FileOutputStream(destFile); int len = 0; byte[] buffer = new byte[1024]; while((len = in.read(buffer))!=-1){ out.write(buffer,0,len); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ try { in.close(); out.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }

StreamUtils.java

/* * 读取流的工具 * 把流对象转换成字符串对象 */ public class StreamUtils { //将输入流读取成String后返回 public static String readFormStream(InputStream in) throws IOException{ // 定义字节数组输出流对象 ByteArrayOutputStream out = new ByteArrayOutputStream(); // 定义读取的长度 int len = 0 ; // 定义读取的缓冲区 byte[] buffer = new byte[1024]; // 按照定义的缓冲区进行循环读取,直到读取完毕为止 while((len=in.read(buffer))!=-1){ // 根据读取的长度写入到字节数组输出流对象中 out.write(buffer,0,len); } String result = out.toString(); // 关闭流 in.close(); out.close(); return result; // // 把读取的字节数组输出流对象转换成字节数组 // byte data[] = out.toByteArray(); // // 按照指定的编码进行转换成字符串(此编码要与服务端的编码一致就不会出现乱码问题了,android默认的编码为UTF-8) // return new String(data, "UTF-8"); } }

系统安装界面的activity的配置:

<activity android:name=".PackageInstallerActivity" android:configChanges="orientation|keyboardHidden" android:theme="@style/Theme.Transparent"> <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <data android:scheme="content" /> <data android:scheme="file" /> <data android:mimeType="application/vnd.android.package-archive" /> </intent-filter> </activity>

我们服务器用的是tomcat,里面放置  新版本的apk和update.json:

将代码打包为apk文件:

涉及的知识点:

PackageManager  包管理器,获取手机里面每个apk的信息(清单文件信息)

版本更新流程:

网络请求

>  * URL
>  * HttpUrlConntetion

JSON解析

> * JSONObject  专门用来解析json
> * JSONArray

对话框弹出

> AlertDialog
> AlertDialog.Builder

子线程更新UI

> * Handler + message
> * runOnUiThread(runnable)

页面之间的跳转Intent

GitHub 一个开源的网站,下载xUtils框架,将下载的jar包导入工程。

AlertDialog.Builder(this)

子类拥有父类的所有方法, 而且可以有更多自己的方法。父类无法有子类的方法

Activity(token), Context(没有token)

平时,要获取context对象的话, 优先选择Activity, 避免bug出现, 尽量不用getApplicationContext()

activity是context的子类

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持脚本之家!

时间: 2024-08-24 14:48:14

详谈闪屏页相关处理的相关文章

Android 实现闪屏页和右上角的倒计时跳转实例代码_Android

以前编程的时候,遇到倒计时的功能时,经常自己去写,但其实Android已经帮封装好了一个倒计时类CountDownTimer,其实是将后台线程的创建和Handler队列封装成为了一个方便的类调用. 闪屏页用到了handler和CountDownTimer类,还需配置一下Activity的主题,这里是:android:theme="@android:style/Theme.NoTitleBar.Fullscreen" 全屏主题的意思. 给大家展示下效果图: 代码如下所示: package

android 音乐播放器-音乐播放器的闪屏页重复显示

问题描述 音乐播放器的闪屏页重复显示 我给音乐播放器加了一个闪屏页,但是当软件处于后台运行的时候再次打开软件,它依然会显示闪屏.请各位大神们支支招 解决方案 http://blog.csdn.net/jdsjlzx/article/details/7523333

Android 实现闪屏页和右上角的倒计时跳转实例代码

以前编程的时候,遇到倒计时的功能时,经常自己去写,但其实Android已经帮封装好了一个倒计时类CountDownTimer,其实是将后台线程的创建和Handler队列封装成为了一个方便的类调用. 闪屏页用到了handler和CountDownTimer类,还需配置一下Activity的主题,这里是:android:theme="@android:style/Theme.NoTitleBar.Fullscreen" 全屏主题的意思. 给大家展示下效果图: 代码如下所示: package

Android应用闪屏页延迟跳转的三种写法

闪屏页也称之为欢迎页.在打开一个App时,我们第一眼看到的往往是一个闪屏页面,之所以叫闪屏页,是因为它出现之后会短暂地停留几秒钟再跳转到其他页面.闪屏页除了使用户体验更好外,还能给app留出初始化数据的时间.下面,是我总结的闪屏页的三种写法. 准备工作 打开Android Studio,新建一个projectMyStudy,新建一个SplashActivity并在清单文件中将其设置为启动Activity.在布局文件中将SplashActivity的背景设置为一张图片(可以是手机壁纸). <?xm

Android 自定义闪屏页广告倒计时view效果

如今APP越来越多,我们每天所使用的的软件也越来越多,可是在我们不付费的情况下,App制造商如何实现,实现收入甚至是盈利呢?答案就是在我们打开软件所必须经过的地方穿插广告,当然为了顾及用户的感受,一般都会以倒计时的形式展示给用户,用户可以选择跳过.可能是因为自己的强迫症,总想着是怎么做的,自己就尝试了一下,分享给大家的同时,顺便加深自己的理解.效果如图: 1.为了满足产品和设计,先搞几个自定义属性 1)内层背景 2)数字的颜色 3)外层圆环宽度 4)文字大小 5)外层圆环颜色 6)圆的半径 这里

Android中使用Handler及Countdowntimer实现包含倒计时的闪屏页面

上一篇博文<Android中Handler使用浅析>通过实现倒计时闪屏页面的制作引出了Handler的使用方法以及实现原理,博文末尾也提到了实现过程中的Bug,有兴趣的朋友可以点击链接回去看看.今天通过使用Handler以及CountDownTimer来实现完整版的倒计时闪屏(不会出现在退出闪屏页后,依然会跳转页面的现象). 1. 实现效果如下: 1.1  正常进入跳转的效果以及log显示 1.2  倒计时未结束时退出以及log显示 对比上篇博文的实现,退出后计时停止且不会再跳到新的界面 2.

i 启动页-iOS中启动屏后再加个闪屏

问题描述 iOS中启动屏后再加个闪屏 iOS中启动屏后再加个闪屏 这个闪屏图片地址由后端获取,同时还有个MD5值(如果手机端网速太慢,可以先下载下来,在第二次启动app时再显示),这样怎么做好呢 求思路 就像网易新闻那样,启动页后面有个闪屏 但又不会出现由于网速慢加载不出来的情况 解决方案 ios 启动动画的设置(闪屏)

Android实现闪屏及注册和登录界面之间的切换效果_Android

在没给大家介绍正文之前先给大家说下实现思路: 先分别实现闪屏.注册界面.登录界面的活动,再用Intent将相关的活动连接起来,实现不同活动之间的跳转.此次试验代码较多,我只列出主要代码,详细的代码可用底部的下载链接下载. 一.实验效果图: 二.主要代码: (1)WelcomeActivity.Java(这部分代码实现的是第一页的欢迎页面) package com.example.flashscreendemo; import android.app.Activity; import androi

Android实现闪屏及注册和登录界面之间的切换效果

在没给大家介绍正文之前先给大家说下实现思路: 先分别实现闪屏.注册界面.登录界面的活动,再用Intent将相关的活动连接起来,实现不同活动之间的跳转.此次试验代码较多,我只列出主要代码,详细的代码可用底部的下载链接下载. 一.实验效果图: 二.主要代码: (1)WelcomeActivity.Java(这部分代码实现的是第一页的欢迎页面) package com.example.flashscreendemo; import android.app.Activity; import androi