zoukankan      html  css  js  c++  java
  • Android项目实战_手机安全卫士splash界面

    - 根据代码的类型组织包结构
    1. 界面 com.hb.mobilesafe.activities
    2. 服务 com.hb.mobilesafe.services
    3. 业务逻辑 com.hb.mobilesafe.engine
    4. 数据库 com.hb.mobilesafe.db
    5. 数据库增删改查 com.hb.mobilesafe.db.dao
    6. 工具类 com.hb.mobilesafe.utils
    7. 自定义view com.hb.mobilesafe.ui

    ###3.splash界面的作用
    1. 展现产品的logo,提升产品的知名度.
    2. 初始化应用程序的数据.
    3. 连接服务器,查找可更新的版本,自动更新
    4. 用户操作指南
    5. 新版本特性提醒

    4.布局文件的命名规则
    SplashActivity--->activity_spalsh.xml
    XxxActivity---> activity_xxx.xml

    ###5.获取应用程序版本号
    //用PackageManager拿到PackageInfo,PackageInfo中的versionName
    PackageInfo packinfo = context.getPackageManager().getPackageInfo(
    context.getPackageName(), 0);
    String version = packinfo.versionName;

    ###6.源代码版本控制
    - 安装VisualSVN Server——SVN服务器,一直下一步即可
    - 导入仓库到服务器
    1.在Repositories处右键,选择Import Existing Repository
    2.选择Copy repository from another location,下一步
    3.点击Browse,选择仓库路径,"代码/代码仓库/Repository/mobilesafe",点击下一步
    4.点击Import
    5.点击Finish,导入完成
    - 安装TortoiseSVN——SVN客户端,一直下一步即可
    1.在想要检出代码的地方右键,选择SVN Checkout
    2.URL of repository处填https://127.0.0.1/svn/mobilesafe/,地址也可以从SVN服务器的mobilesafe处右键选择Copy URL to clipboard拷贝
    3.Checkout directory出填写检出代码要放的位置,然后点击OK
    4.完成代码的检出
    - 将代码更新到指定版本
    1.mobilesafe文件夹出右键,选择Update to version
    2.点击show log
    3.点击左下角的show all
    4.选择要更新的版本,点击OK
    5.版本更新完成

    ###7.应用自动更新的逻辑图
    ![](http://i.imgur.com/EU78wXt.png)

    ###8.获取服务器版本号
    //获取服务器地址
    String path = getResources().getString(R.string.url);
    URL url = new URL(path);

    //创建网络连接
    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    conn.setRequestMethod("GET");
    conn.setConnectTimeout(5000);

    //发出请求,获得返回码
    int code = conn.getResponseCode();
    if(code ==200){

    //获取服务器返回的流并进行解析
    InputStream is = conn.getInputStream();
    String result = StreamTools.readStream(is);

    //转化为json并解析出版本号
    JSONObject json = new JSONObject(result);
    String serverVersion = json.getString("version");
    Log.i(TAG,"服务器版本:"+serverVersion);
    }

    ###9.将流转化为字符串
    public static String readStream(InputStream is) throws IOException{

    //ByteArrayOutputStream类是在创建它的实例时,程序内部创建一个byte型数组的缓冲区,缓冲区会随着数据的不断写入而自动增长。可使用 toByteArray()和 toString()获取数据
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    byte[] buffer = new byte[1024];
    int len = -1;
    while((len = is.read(buffer))!=-1){
    baos.write(buffer, 0, len);
    }
    is.close();
    return baos.toString();
    }

    ###10.弹出对话框
    1.使用AlertDialog.Builder
    2.设置标题、信息、点击事件等
    3.调用show方法显示出来,调用dismiss方法消失

    ###11.下载apk
    1.使用开源框架xUtils
    2.使用HttpUtils的download方法,填入三个参数:服务器下载地址,手机中的存储位置、回调事件
    3.回调事件中有三个常用的方法:onSuccess下载成功、onFailure下载失败、onLoading更新下载进度

    xUtils补充
    http://my.oschina.net/u/1171837/blog/147544 作者博客

    ###12.安装apk
    1.调用系统的安装apk的界面,传入对应的参数
    2.具体实现方式
    Intent intent = new Intent();
    intent.setAction("android.intent.action.VIEW");
    intent.addCategory("android.intent.category.DEFAULT");
    intent.setDataAndType(
    Uri.fromFile(fileinfo.result),
    "application/vnd.android.package-archive");
    startActivity(intent);

    ###13.应用程序的覆盖安装要满足的条件
    1. 两个版本签名一致
    2. 两个版本包名一致

    ###14.跑马灯效果的TextView
    1. 系统的TextView不能获取焦点,使用自定义控件
    2. 继承TextView控件,重写isFocused方法,直接返回true,让其获取焦点
    3. 设置android:ellipsize="marquee"

    ###15.旋转的弘博logo
    1. 使用系统提供的属性动画
    2. 具体实现方式
    ObjectAnimator oa = ObjectAnimator.ofFloat(iv_home_logo, "rotationY",
    45, 90, 135, 180, 225, 270, 315);
    oa.setDuration(3000);
    oa.setRepeatCount(ObjectAnimator.INFINITE);
    oa.setRepeatMode(ObjectAnimator.RESTART);
    oa.start();

    贴上对应的源码:

      1 package com.hb.mobilesafe.activities;
      2 
      3 import java.io.File;
      4 import java.io.FileOutputStream;
      5 import java.io.IOException;
      6 import java.io.InputStream;
      7 import java.net.HttpURLConnection;
      8 import java.net.URL;
      9 
     10 import org.json.JSONObject;
     11 
     12 import android.app.Activity;
     13 import android.app.AlertDialog;
     14 import android.app.AlertDialog.Builder;
     15 import android.app.ProgressDialog;
     16 import android.content.DialogInterface;
     17 import android.content.DialogInterface.OnClickListener;
     18 import android.content.Intent;
     19 import android.content.SharedPreferences;
     20 import android.content.res.AssetManager;
     21 import android.net.Uri;
     22 import android.os.Bundle;
     23 import android.os.Environment;
     24 import android.os.Handler;
     25 import android.os.Message;
     26 import android.os.SystemClock;
     27 import android.view.Window;
     28 import android.widget.TextView;
     29 import android.widget.Toast;
     30 
     31 import com.hb.demo_mobilesafe.R;
     32 import com.hb.mobilesafe.utils.GetVersonName;
     33 import com.hb.mobilesafe.utils.ReadStrem;
     34 import com.lidroid.xutils.HttpUtils;
     35 import com.lidroid.xutils.exception.HttpException;
     36 import com.lidroid.xutils.http.ResponseInfo;
     37 import com.lidroid.xutils.http.callback.RequestCallBack;
     38 
     39 public class SplashActivities extends Activity {
     40     protected static final int SUCCESS = 1;
     41     protected static final int ERROR = 2;
     42     private TextView tv_splash_version;
     43     private String localVersion;
     44     private String serviceVerson;
     45     private String apkpath;
     46     private String descritoin;
     47     private Handler handler=new Handler(){
     48         public void handleMessage(android.os.Message msg) {
     49             switch (msg.what) {
     50             case SUCCESS:
     51                 //判断出的版本号不一样进行升级
     52                 builderLoading();
     53                 break;
     54 
     55             case ERROR:
     56                 Toast.makeText(SplashActivities.this, "错误信息:"+msg.obj, 0).show();
     57                 loadUI();
     58                 break;
     59             }
     60         }
     61 
     62 
     63     };
     64 
     65     @Override
     66     protected void onCreate(Bundle savedInstanceState) {
     67         super.onCreate(savedInstanceState);
     68         requestWindowFeature(Window.FEATURE_NO_TITLE);
     69         setContentView(R.layout.activity_splash);
     70         tv_splash_version = (TextView) findViewById(R.id.tv_splash_version);
     71         SharedPreferences sp=getSharedPreferences("config", MODE_PRIVATE);
     72         //获取开关状态判断是否进行升级提示
     73         boolean tag = sp.getBoolean("update", true);
     74         if(tag){
     75             initDate();
     76         }else{
     77             new Thread(){
     78                 public void run() {
     79                     SystemClock.sleep(1500);
     80                     loadUI();
     81                 };
     82             }.start();
     83         }
     84         localVersion = GetVersonName.version(this);
     85         tv_splash_version.setText("版本号:"+localVersion);
     86         //初始化导入数据库到手机
     87         importDataBase("antivirus.db");
     88 
     89     }
     90     //初始化导入数据库到手机
     91     private void importDataBase(String fileName) {
     92         File file=new File(getFilesDir(), fileName);
     93         if(file.exists() && file.length()>0){
     94             return;
     95         }
     96         try {
     97             AssetManager assets = getAssets();
     98             InputStream is= assets.open(fileName);
     99             FileOutputStream fs=new FileOutputStream(file);
    100             int len=-1;
    101             byte [] arr=new byte[1024];
    102             while ((len =is.read(arr))!=-1) {
    103                 fs.write(arr, 0, len);
    104             }
    105             fs.close();
    106             is.close();
    107         } catch (IOException e) {
    108             // TODO Auto-generated catch block
    109             e.printStackTrace();
    110         }
    111     }
    112 
    113     private void initDate() {
    114 
    115         new Thread(){
    116 
    117             private long start;
    118             private Message message;
    119             public void run() {
    120                 String path=getResources().getString(R.string.path);
    121 
    122                 try {
    123                     URL url = new URL(path);
    124                     HttpURLConnection conn =(HttpURLConnection) url.openConnection();
    125                     conn.setConnectTimeout(5000);
    126                     conn.setRequestMethod("GET");
    127                     int code = conn.getResponseCode();
    128                     if(code == 200){
    129                         InputStream stream = conn.getInputStream();
    130                         String json = ReadStrem.readSreamUtil(stream);
    131                         JSONObject ob=new JSONObject(json);
    132                         serviceVerson = ob.getString("verson");
    133                         descritoin = ob.getString("descritoin");
    134                         apkpath = ob.getString("apkpath");
    135                         start=SystemClock.currentThreadTimeMillis();
    136                         /**
    137                          * 进行本地版本与服务器版本的对比
    138                          */
    139                         if(localVersion.equals(serviceVerson)){
    140                             //不需要升级直接调转
    141                             //                            loadUI();
    142                         }else{
    143                             message = new Message();
    144                             message.what=SUCCESS;
    145                             handler.sendMessage(message);
    146 
    147 
    148                         }
    149                     }
    150 
    151                 } catch (Exception e) {
    152                     e.printStackTrace();
    153                     message = new Message();
    154                     message.what=ERROR;
    155                     message.obj="code:404";
    156                     handler.sendMessage(message);
    157 
    158                 }finally{
    159                     long end=SystemClock.currentThreadTimeMillis();
    160                     long et=end-start;
    161                     if(et>2000){
    162                     }else{
    163                         SystemClock.sleep(2000-et);
    164                     }
    165 
    166                 }
    167             }
    168 
    169 
    170         }.start();
    171     }
    172     /**
    173      * 更新UI
    174      */
    175     private void loadUI() {
    176         Intent intent=new Intent(SplashActivities.this, HomeActivities.class);
    177         startActivity(intent);
    178         finish();
    179     };
    180     //提示用户升级
    181     private void builderLoading() {
    182         AlertDialog.Builder alert=new Builder(SplashActivities.this);
    183         alert.setTitle("版本升级提示");
    184         alert.setCancelable(false);//设置锁定其他界面点击事件
    185         alert.setMessage(descritoin);
    186         //        alert.setIcon(R.drawable.);
    187         alert.setPositiveButton("立刻升级", new OnClickListener() {
    188 
    189             private ProgressDialog pd;
    190 
    191             @Override
    192             public void onClick(DialogInterface dialog, int which) {
    193                 Toast.makeText(SplashActivities.this, "升级吧", 0).show();
    194                 pd = new ProgressDialog(SplashActivities.this);
    195                 pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
    196                 pd.show();
    197                 
    198                 HttpUtils utils=new HttpUtils();
    199                 if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
    200                     //获取SD卡的对象
    201                     File sd=Environment.getExternalStorageDirectory();
    202                     File file=new File(sd, SystemClock.currentThreadTimeMillis()+".apk");
    203                     utils.download(apkpath, file.getAbsolutePath(),new RequestCallBack<File>(){
    204 
    205                         @Override
    206                         public void onFailure(HttpException arg0, String arg1) {
    207                             pd.dismiss();
    208                         }
    209 
    210                         @Override
    211                         public void onSuccess(ResponseInfo<File> arg0) {
    212                             pd.dismiss();
    213                             //安装APP
    214                             Intent intent=new Intent();
    215                             intent.setAction("android.intent.action.VIEW");
    216                             intent.addCategory("android.intent.category.DEFAULT");
    217                             intent.setDataAndType(
    218                                     Uri.fromFile(arg0.result),
    219                                     "application/vnd.android.package-archive");
    220                             startActivity(intent);
    221                             finish();
    222                         }
    223 
    224                         @Override
    225                         public void onLoading(long total, long current,
    226                                 boolean isUploading) {
    227                             pd.setMax((int)total);
    228                             pd.setProgress((int)current);
    229                             super.onLoading(total, current, isUploading);
    230                         }
    231                     });
    232 
    233                 }
    234             }
    235         });
    236         alert.setNegativeButton("下次再说", new OnClickListener() {
    237 
    238             @Override
    239             public void onClick(DialogInterface dialog, int which) {
    240                 loadUI();
    241             }
    242         });
    243         alert.show();
    244 
    245     }
    246 
    247 
    248 }

    布局文件:

    <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:background="@drawable/splash"
        tools:context="${relativePackage}.${activityClass}" >
    
        <TextView
            android:id="@+id/tv_splash_version"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_centerHorizontal="true"
            android:layout_marginBottom="15dip"
            android:textSize="16sp"
            android:text="版本号:1.0" />
    
    </RelativeLayout>

    给上这个项目中所需的所有权限不懂的可以百度一下:

    <uses-permission android:name="android.permission.CALL_PHONE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
    <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.READ_CONTACTS" />
    <uses-permission android:name="android.permission.WRITE_CONTACTS" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.SEND_SMS" />
    <uses-permission android:name="android.permission.RECEIVE_SMS" />
    <uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.GET_TASKS" />
    <uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES" />
    <uses-permission android:name="android.permission.GET_PACKAGE_SIZE" />
    <uses-permission android:name="android.permission.READ_CALL_LOG" />
    <uses-permission android:name="android.permission.WRITE_CALL_LOG" />

    <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
    <!-- 短信备份 -->
    <uses-permission android:name="android.permission.READ_SMS" />
    <uses-permission android:name="android.permission.WRITE_SMS" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <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" />

  • 相关阅读:
    数组最值和两种排序
    整数翻转,99乘法表,百钱买百鸡
    运算符综合练习题
    五子棋实现体验其过程
    二维数组斜线扫描2(方法逻辑清晰)
    字符串链接练习题
    母串中有几个相同的子串
    递归求菲波拉契前N项的和
    [LeetCode] Mini Parser
    Linked List 小结
  • 原文地址:https://www.cnblogs.com/boket/p/6991375.html
Copyright © 2011-2022 走看看