模仿360安全卫士项目笔记1

来源:互联网 发布:淘宝新店宝贝上架 编辑:程序博客网 时间:2024/05/16 19:33


01_项目介绍_20

演示项目功能;

1、对前面知识的综合应用,复习基础一遍。

2、熟悉代码,找到敲代码的感觉;

3、每天会有1000-1500行代码量;这几天下来一共就会有1万多行代码量。

4、大学软件工程的学生毕业要求3-5万行的代码量。10几天完成三分之一、五分之一;

5、版本控制,每一天的代码用版本控制起来,可以看到每天的代码;

6、演示程序代码。

7、演示功能有:

   启动页面

   主页

   手机防盗(注意:演示时模拟器要提前设置有联系人);

   通讯卫士:黑名单的管理:电话拦截、短信拦截的演示;

   软件管理:列出系统的所以软件,启动软件、卸载软件、系统的卸载失败(需要root权 限这个后面也会介绍)

   进程管理:列出系统中正在运行的程序;演示杀死软件

   窗口小部件:添加桌面;

   流量统计:模拟器并不支持,在真机上才能演示,只做个UI效果;

   手机杀毒:检查手机安装的软件,发现那个是病毒,提醒用户就杀掉;

   系统优化:清除系统的垃圾,刚开始运行,没用多余数据;

   高级工具:归属地查询;常用号码查询;短信备份;

 

 

 

 

02_Svn服务器的使用_20

 1、演示svn安装好的样子;

 2、查看提交了哪些文件,修改了哪些代码

 

 3、基于已经存在的RepositoriesX代码仓库,创建代码创库;

 4、建立创库RepositoriesX代码仓库,导入代码;----基于已有的创库;

 5、基于创库建立新MobileSafe代码工程;----建立一个新的工程;

 

 

03_代码组织结构_10

 

 

1、按照模块 组织代码的包结构。 业务之间彼此独立;

 

办公软件

 

     --  开会               com.itheima.meeting

     --  发放工资        com.itheima.money

     --  出差            com.itheima.travel

 

车载电脑 

 

     -- 多媒体

     -- 导航

     -- 领航

     

 

2、按照代码的类型组织包结构;

 界面      com.itheima.mobilesafe.activies

 自定义UI      com.itheima.mobilesafe.ui

 业务逻辑代码    com.itheima.mobilesafe.engine 数据引擎业务逻辑 获取解析数据

 持久化       com.itheima.mobilesafe.db

           com.itheima.mobilesafe.db.dao

 广播接收者      com.itheima.mobilesafe.receiver

 长期在后台运行  com.itheima.mobilesafe.service

 公用的api工具类com.itheima.mobilesafe.utils

 

04_Splash界面的UI_20

第一: splash界面的作用

1、用来展现产品的Logo

2、应用程序初始化的操作;

3、检查应用程序的版本;

4、检查当前应用程序是否合法注册;

 

第二:写界面

 

      android:id="@+id/tv_splash_version"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:textColor="#000000"

        android:textStyle="bold"

        android:shadowDx="1"

        android:shadowDy="1"

        android:shadowRadius="0.2"

        android:shadowColor="#ffff00"

        android:text="版本:1.0"

        android:textSize="16sp"

        android:layout_centerInParent="true"

 

 第三:动态获取程序的版本名称的方法

  /**

 * 得到应用程序的版本号

 */

public String getAppVersion(){

PackageManager pm = getPackageManager();

try {

PackageInfo info = pm.getPackageInfo(getPackageName(), 0);

return info.versionName;

catch (NameNotFoundException e) {

e.printStackTrace();

//不可能发生;

return "";

}

}

 

运行演示看效果。

知识拓展:http://blog.csdn.net/qinjuning/article/details/6867806

http://www.umindex.com/#android_system

 

 

4、演示提交代码;

05_连接服务器获取更新信息_50

1、查看当前升级提醒对话框效果图

2、画升级流程图

 

3、到webservice里去写json文件:update.json

4、Anddroid工程添加联网权限:android.permission.INTERNET

5、在子线程钟请求服务器代码checkVersion()

6、请求网络的代码

   URL url = new URL(getString(R.string.serviceurl));

HttpURLConnection conn = (HttpURLConnection)  url.openConnection();

conn.setRequestMethod("GET");

 conn.setReadTimeout(5000);

7、参照一个解析流的类StreamTools

8、解析JSON

   JSONObject obj = new JSONObject(result);

//服务器的版本号

String version = (String) obj.get("version");

description = (String) obj.get("description");

apkurl = (String) obj.get("apkurl");

9、用Handler更新信息

10、创建主页面HomeActivity和布局文件

11、写延迟2秒进入主页面代码

   long startTime = System.currentTimeMillis();

   long endTime = System.currentTimeMillis();

long dTime = endTime - startTime;

if(dTime<2000){

try {

Thread.sleep(2000-dTime);

catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

12、添加AlphaAnimation动画效果

    AlphaAnimation aa = new AlphaAnimation(0.3f, 1.0f);

findViewById(R.id.rl_root_splash).startAnimation(aa);

13、测试异常况好不好用

14、提交代码到SVN服务器

06_应用程序的签名_30

准备:webservice 上放置一个正式签名的应用

 

1、显示更新对话框showUpdateDialog();

   protected void showUpdateDialog() {

AlertDialog.Builder build = new Builder(this);

build.setTitle("发现新版本");

build.setMessage(description);

build.setNegativeButton("立刻升级", new OnClickListener() {

@Override

public void onClick(DialogInterface dialog, int which) {

//升级的代码;

};

});

build.setPositiveButton("下次再说", new OnClickListener() {

@Override

public void onClick(DialogInterface dialog, int which) {

dialog.dismiss();

enterHome();

}

});

build.show();

 

2、下载功能,用到afinal下载框架:FinalHttp

 判断SDcard代码:

if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))

下载代码

 FinalHttp http = new FinalHttp();

//mnt/sdcard/updata.apk

  Http.download();

 

更新进度代码

 int progress = (int) (current * 100/count);

 tv_splash_updateinfo.setText("下载了:"+progress+"%");

 

 

3、添加SDcard写权限

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

 

3、调用系统安装工具安装APK

   private void installAPK(File t) {

Intent intent = new Intent(); intent.setAction("android.intent.action.INSTALL_PACKAGE" ); intent.addCategory("android.intent.category.DEFAULT");

intent.setDataAndType(Uri.fromFile(t), "application/vnd.android.package-archive");

startActivity(intent);

}

 

4、安装失败

 

5、引入apk签名

 在Android手机里不允许有两个应用程序有相同的包名;

 

 假设A应用的包名:com.itheima.mobilesafeA;

 A应用已经在系统中存在了。

 

 这个时候再去安装一个应用,他的报名也叫 con.itheima.mobilesafeA

 系统就会去检查这两应用的签名是否相同。如果相同,B会把A给覆盖安装掉;

 如果不相同 B安装失败;

 

 要想自动安装成功,必须保证应用程序不同版本的签名完成一样。

 

6、签名演示

7、签名两个应用1.02.0,并演示升级不成功和升级成功:如果签名搞丢了怎么办

 

07_Splash界面的细节_6

 准备:启动webserver服务器

 1、显示4.0的样式:方式是去掉功能清单里的Activity对应的android:theme

  放到application里面;

 2、当splash页面弹出升级提示框过滤点击返回的是两种方式:

     一、builder.setCancelable(false);

    二、设置setOnCancelListener 当触屏的时候直接进入主页面

08_两种上下文的区别_8

  对话框是Activity的一部分。

  对话框是挂载在Activity上面的 。

  如果Activity不存在,对话框就不能被创建。

 

  Activity 实际上是应用程序context上下文的一个子集。

 

  子类有的东西父类不一定有

  父类有的东西子类一定有

 

  getApplicationContext();生命周期长,只要应用还存活它就存在;

  this 生命周期短,只要Activity不存在了,系统就会回收;  

 

  其中:getBaseContext(),getApplication(),getApplicationContext();

  都不能放在AlertDialog做上下文;

 

  getApplicationContext() 使用场景是比如频繁需要操作的数据库

 

  推荐用法:Activity.this

 

  

09_应用程序主界面_15

1、画图九宫格和列表

 

 功能列表颜色值:#8866ff00

 textSize:22sp

 

 <GridView

        android:id="@+id/gv_home_gridview"

        android:layout_width="match_parent"

        android:layout_height="match_parent"

        android:numColumns="3"

        android:verticalSpacing="15dip" />

 

 Names:手机防盗、通讯卫士、软件管理

         进程管理、流量统计、手机杀毒

         缓存清理、高级工具、设置中心

 

10_自定义可以滚动TextView_10

   写完主页面后

   Button 有文字滚动

 <Button

        android:focusableInTouchMode="true"

        android:textColor="#000000"

        android:layout_width="fill_parent"

        android:singleLine="true"

        android:layout_height="wrap_content"

        android:ellipsize="marquee"

        android:layout_gravity="center_horizontal"

        android:text="欢迎使用手机卫士,呵呵欢迎使用手机卫士"

        android:textSize="16sp"

         />

 

   FocusedTextView  

 

<com.itheima.mobilesafe.ui.FocusedTextView

        android:textColor="#000000"

        android:layout_width="fill_parent"

        android:singleLine="true"

        android:layout_height="wrap_content"

        android:ellipsize="marquee"

        android:layout_gravity="center_horizontal"

        android:text="欢迎使用手机卫士,呵呵欢迎使用手机卫士,呵呵欢迎使用手机卫士,呵呵欢迎使用手机卫士,呵呵"

        android:textSize="16sp"

         />

11_自动更新的组合控件_50

  准备:开启webserver服务器

 1、每次都升级消耗多余的流量

 2、在主页面增加点击事件进入设置类;

 3、创建SettingActivity类,并在功能清单文件配置;

 4SettingActivity的布局文件,基于activity_home.xml修改;

 5、运行可以点击进入设置中心;

 6、开始写设置里的布局文件了,参照系统的设置里的“位置服务

 7、布局文件

   <RelativeLayout

        android:layout_width="match_parent"

        android:layout_height="60dip" >

 

        <TextView

            android:id="@+id/tv_title"

            android:layout_width="match_parent"

            android:layout_height="wrap_content"

            android:layout_marginLeft="5dip"

            android:layout_marginTop="5dip"

            android:text="更新设置"

            android:textColor="#000000"

            android:textSize="22sp" />

 

        <TextView

            android:id="@+id/tv_desc"

            android:layout_width="match_parent"

            android:layout_height="wrap_content"

            android:layout_below="@id/tv_title"

            android:layout_marginLeft="5dip"

            android:text="自动升级已经关闭"

            android:textColor="#88000000"

            android:textSize="15sp" />

 

        <CheckBox

            android:id="@+id/cb_status"

            android:layout_centerVertical="true"

            android:layout_marginRight="10dip"

            android:layout_alignParentRight="true"

            android:layout_width="wrap_content"

            android:layout_height="wrap_content" />

        

        <View  

            android:layout_alignParentBottom="true"

            android:layout_marginLeft="5dip"

            android:layout_marginRight="5dip"

            android:background="#66000000"

            android:layout_width="fill_parent"

            android:layout_height="0.2dip"/>

    </RelativeLayout>

 8、抽取出来单独类SettingItemView 

 9、单独的布局文件setting_item_view.xml

 10、演示多个设置条目当时的方便;

 11、相应组合控件的点击事件;

 12、判断组合控件是否被选中,其实就是CheckBox的状态是否被选中;

 13、在SettingItemView 增加isChecked()setChecked();方法;并演示

 14、在在SettingItemView 增加setDesc()方法;并演示;

 15、演示并处理CheckBox的点击事件---解决方案:禁用点击事件;

   android:clickable=”false”

   android:focusable=”false”

 16、记录选中状态,并在进入的时候读取保存的状态;

 17、在SplashActivity根据是否开启升级而相应的是否升级;

 18、延迟两秒进入主页面的代码;

   //停留2秒后进入主页面;

handler.postDelayed(new Runnable() {

@Override

public void run() {

enterHome();

}

}, 2000);

 

12_定义自定义控件的属性_25

1、演示当前扩展的麻烦性,再增加自定义组合控件的使用情境;

2、去掉setting_item_view.xml的文字,运行演示;

3、在SettingItemView里加自定义组合控件的标题方法setTitle();

4、在SettingActivity代码里写另外一个设置条的标题和描述信息赋值;

5、参照系统控件TextView讲解系控件的属性特点;

6、自定义标题属性title、描述打开属性descon、描述关闭属性descoff

7、参照系统的命名空间写自定义的命名空间,并演示删除系统命名空间报错;

8、讲解自定命名空间;

9、演示运行时报错;

10、找到目录platforms\android-16\data\res\values\attrs.xml,参照TextView讲解;

11、在工程里res/values目录下创建attrs.xm文件内容如下:

 <?xml version="1.0" encoding="utf-8"?>

<resources>

    <declare-styleable name="SettingItemView">

        <attr name="title" format="string" />

        <attr name="desc_on" format="string" />

        <attr name="desc_off" format="string" />

    </declare-styleable>

</resources>

12、属性使用,讲解两个参数的构造方法:

   在布局文件里面所定义的所有属性,都会被封装到AttributeSet 的属性集合里面;

13、得到属性值(attrs.getAttributeValue(0))并打印出来;

14、使用更方便的方法:

 attrs.getAttributeValue("http://schemas.android.com/apk/res/com.itheima.mobilesafe""title");

 

15、把得到的值关联到各个控件里去;

16、删除SettingActivity用代码设置的描述信息和标题信息;

17、在布局文件里多次使用自定义控件,并演示;

 

 

13_总结自定义组合控件的过程_10

 1、声明一个View对象 继承相对布局,或者线性布局 或者其他的ViewGroup

 2、在自定义的View对象里面重写它的构造方法。在构造方法里面就把布局都初始化完毕。

 3、根据业务需求 添加一些api方法,扩展自定义的组合控件;

 

 

 4、希望在布局文件里面 可以自定义一些属性。

 5、声明自定义属性的命名空间。

          xmlns:itheima="http://schemas.android.com/apk/res/com.itheima.mobilesafe"

 

 6、在res目录下的values目录下创建attrs.xml的文件 声明你写的属性。

     <declare-styleable name="SettingItemView">

        <attr name="title" format="string" />

        <attr name="desc_on" format="string" />

        <attr name="desc_off" format="string" />

</declare-styleable>

 

7、在布局文件中写哪些你自定义的属性。

8、使用这些定义的属性。自定义View对象的构造方法里面 有一个带两个参数的构造方法

   布局文件里面定义的属性都放在 AttributeSet attrs

   获取那些定义的属性。 

 

 

知识点

1、项目的代码组织结构

2、PackageManager 获取应用程序的版本号;

3、URL HttpUrlConntion

4、子线程 handler + message

5、Json解析

6、Intent  显示意图

7、Alterdialog

8、两种上下文

9、下载--FinalHttp

10、安装apk

11、应用程序的签名;

12、ListView gridView 数据适配

13、滚动的TextView

14、自定义组合控件 实现关闭自动更新;

 

-----------------------------------------------------------------------------------------------

代码组织结构

  • 根据业务逻辑划分

    • 办公软件

      • 出差 com.itheima.travel
      • 工资 com.itheima.money
      • 会议 com.itheima.meeting
    • 网盘

      • 上传 com.vdisk.upload
      • 下载 com.vdisk.download
      • 分享 com.vdisk.share
  • 根据功能模块划分(Android开发推荐此方法)

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

项目创建

  • minimum SDK 要求最低的安装版本, 安装apk前,系统会判断当前版本是否高于(包含)此版本, 是的话才允许安装

  • maxSdkVersion 要求最高的安装版本(一般不用)

  • Target SDK 目标SDK, 一般设置为开发时使用的手机版本, 这样的话,系统在运行我的apk时,就认为我已经在该做了充分的测试, 系统就不会做过多的兼容性判断, 从而提高运行效率

  • Compile With 编译程序时使用的版本

闪屏页面(Splash)

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

什么是奋斗

奋斗就是,你每天都很辛苦, 但是,你一年一年会越来越轻松 不奋斗就是, 你每天都很轻松, 但是,你一年一年会越来越辛苦

签名冲突

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

正式签名

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

测试签名(debug.keystore)

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

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

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

常用快捷键

  • ctrl + shift + o 导包
  • ctrl + shift + t 快速查找某个类
  • 先按ctrl + 2 ,再点L, 创建变量并命名
  • ctrl + o , 在当前类中,快速查找某个方法
  • ctrl + k, 向下查找某个字符串
  • ctrl + shift + k, 向上查找某个字符串
  • alt + 左方向键 跳转上一个页面
  • ctrl + d 删除当前选中的一行
  • ctrl + shift + x 将选中的文字全部变成大写,中文不变
  • ctrl + shift + y 将选中的文字全部变成小写,中文不变

子类和父类

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

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

minSdkVersion、targetSdkVersion、maxSdkVersion、target API level四个数值到底有什么区别

这里面的minSdkVersion、targetSdkVersion、maxSdkVersion、target API level四个数值到底有什么区别?minSdkVersion与maxSdkVersion比较容易理解,就是在安装程序的时候,如果目标设备的API版本小于minSdkVersion,或者大于maxSdkVersion,程序将无法安装。一般来说没有必要设置maxSdkVersion。
targetSdkVersion相对复杂一些,如果设置了此属性,那么在程序执行时,如果目标设备的API版本正好等于此数值,他会告诉Android平台:此程序在此版本已经经过充分测,没有问题。不必为此程序开启兼容性检查判断的工作了。也就是说,如果targetSdkVersion与目标设备的API版本相同时,运行效率可能会高一些。但是,这个设置仅仅是一个声明、一个通知,不会有太实质的作用,比如说,使用了targetSdkVersion这个SDK版本中的一个特性,但是这个特性在低版本中是不支持的,那么在低版本的API设备上运行程序时,可能会报错:java.lang.VerifyError。也就是说,此属性不会帮你解决兼容性的测试问题。你至少需要在minSdkVersion这个版本上将程序完整的跑一遍来确定兼容性是没有问题的。
在default.properties中的target是指在编译的时候使用哪个版本的API进行编译。 




综上,上面的四个值其实是作用于不同的时期:target API level是在编译的时候起作用,用于指定使用哪个API版本(SDK版本)进行编译。minSdkVersion和maxSdkVersion是在程序安装的时候起作用,用于指定哪些版本的设备可以安装此应用。targetSdkVersion是在程序运行的时候起作用,用于提高指定版本的设备上程序运行体验。这四个数值在程序编译时也没有严格的检查,比如说,你可以将minSdkVersion设置的比maxSdkVersion还大,他会自动忽略掉错误的maxSdkVersion。


升级流程



0 0
原创粉丝点击