- 根据代码的类型组织包结构
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();

贴上对应的源码:

 package com.hb.mobilesafe.activities;

 import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL; import org.json.JSONObject; import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.AssetManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.view.Window;
import android.widget.TextView;
import android.widget.Toast; import com.hb.demo_mobilesafe.R;
import com.hb.mobilesafe.utils.GetVersonName;
import com.hb.mobilesafe.utils.ReadStrem;
import com.lidroid.xutils.HttpUtils;
import com.lidroid.xutils.exception.HttpException;
import com.lidroid.xutils.http.ResponseInfo;
import com.lidroid.xutils.http.callback.RequestCallBack; public class SplashActivities extends Activity {
protected static final int SUCCESS = 1;
protected static final int ERROR = 2;
private TextView tv_splash_version;
private String localVersion;
private String serviceVerson;
private String apkpath;
private String descritoin;
private Handler handler=new Handler(){
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case SUCCESS:
//判断出的版本号不一样进行升级
builderLoading();
break; case ERROR:
Toast.makeText(SplashActivities.this, "错误信息:"+msg.obj, 0).show();
loadUI();
break;
}
} }; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_splash);
tv_splash_version = (TextView) findViewById(R.id.tv_splash_version);
SharedPreferences sp=getSharedPreferences("config", MODE_PRIVATE);
//获取开关状态判断是否进行升级提示
boolean tag = sp.getBoolean("update", true);
if(tag){
initDate();
}else{
new Thread(){
public void run() {
SystemClock.sleep(1500);
loadUI();
};
}.start();
}
localVersion = GetVersonName.version(this);
tv_splash_version.setText("版本号:"+localVersion);
//初始化导入数据库到手机
importDataBase("antivirus.db"); }
//初始化导入数据库到手机
private void importDataBase(String fileName) {
File file=new File(getFilesDir(), fileName);
if(file.exists() && file.length()>0){
return;
}
try {
AssetManager assets = getAssets();
InputStream is= assets.open(fileName);
FileOutputStream fs=new FileOutputStream(file);
int len=-1;
byte [] arr=new byte[1024];
while ((len =is.read(arr))!=-1) {
fs.write(arr, 0, len);
}
fs.close();
is.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} private void initDate() { new Thread(){ private long start;
private Message message;
public void run() {
String path=getResources().getString(R.string.path); try {
URL url = new URL(path);
HttpURLConnection conn =(HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5000);
conn.setRequestMethod("GET");
int code = conn.getResponseCode();
if(code == 200){
InputStream stream = conn.getInputStream();
String json = ReadStrem.readSreamUtil(stream);
JSONObject ob=new JSONObject(json);
serviceVerson = ob.getString("verson");
descritoin = ob.getString("descritoin");
apkpath = ob.getString("apkpath");
start=SystemClock.currentThreadTimeMillis();
/**
* 进行本地版本与服务器版本的对比
*/
if(localVersion.equals(serviceVerson)){
//不需要升级直接调转
// loadUI();
}else{
message = new Message();
message.what=SUCCESS;
handler.sendMessage(message); }
} } catch (Exception e) {
e.printStackTrace();
message = new Message();
message.what=ERROR;
message.obj="code:404";
handler.sendMessage(message); }finally{
long end=SystemClock.currentThreadTimeMillis();
long et=end-start;
if(et>2000){
}else{
SystemClock.sleep(2000-et);
} }
} }.start();
}
/**
* 更新UI
*/
private void loadUI() {
Intent intent=new Intent(SplashActivities.this, HomeActivities.class);
startActivity(intent);
finish();
};
//提示用户升级
private void builderLoading() {
AlertDialog.Builder alert=new Builder(SplashActivities.this);
alert.setTitle("版本升级提示");
alert.setCancelable(false);//设置锁定其他界面点击事件
alert.setMessage(descritoin);
// alert.setIcon(R.drawable.);
alert.setPositiveButton("立刻升级", new OnClickListener() { private ProgressDialog pd; @Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(SplashActivities.this, "升级吧", 0).show();
pd = new ProgressDialog(SplashActivities.this);
pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
pd.show(); HttpUtils utils=new HttpUtils();
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
//获取SD卡的对象
File sd=Environment.getExternalStorageDirectory();
File file=new File(sd, SystemClock.currentThreadTimeMillis()+".apk");
utils.download(apkpath, file.getAbsolutePath(),new RequestCallBack<File>(){ @Override
public void onFailure(HttpException arg0, String arg1) {
pd.dismiss();
} @Override
public void onSuccess(ResponseInfo<File> arg0) {
pd.dismiss();
//安装APP
Intent intent=new Intent();
intent.setAction("android.intent.action.VIEW");
intent.addCategory("android.intent.category.DEFAULT");
intent.setDataAndType(
Uri.fromFile(arg0.result),
"application/vnd.android.package-archive");
startActivity(intent);
finish();
} @Override
public void onLoading(long total, long current,
boolean isUploading) {
pd.setMax((int)total);
pd.setProgress((int)current);
super.onLoading(total, current, isUploading);
}
}); }
}
});
alert.setNegativeButton("下次再说", new OnClickListener() { @Override
public void onClick(DialogInterface dialog, int which) {
loadUI();
}
});
alert.show(); } }

布局文件:

<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" />

Android项目实战_手机安全卫士splash界面的更多相关文章

  1. Android项目实战_手机安全卫士home界面

    # 安全卫士主页面# ###1.GridView控件 1.与ListView的使用方式差不多,也要使用数据适配器,通过设置android:numColumns控制显示几列 2.通过指定android: ...

  2. Android项目实战_手机安全卫士手机防盗界面

    #安全卫士手机防盗# ###1.Activity的任务栈 1.类似一个木桶,每层只能放一个木块,我们放入木块和取出木块的时候只能从最上面开始操作 ###2.Android中的坐标系![](http:/ ...

  3. Android项目实战_手机安全卫士程序锁

    ###1.两个页面切换的实现1. 可以使用Fragment,调用FragmentTransaction的hide和show方法2. 可以使用两个布局,设置visibility的VISIABLE和INV ...

  4. Android项目实战_手机安全卫士系统加速

    ## 1.本地数据库自动更新的工作机制1. 开启一个服务,定时访问服务器2. 进行版本对比,如果最新版本比较高,获取需要更新的内容3. 将新内容插入到本地数据库中 ## 2.如何处理横竖屏切换1. 指 ...

  5. Android项目实战_手机安全卫士软件管家

    ###1.应用程序信息的flags 1. int flags = packageInfo.applicationInfo.flags2. 0000 0000 0000 0000 0000 0000 0 ...

  6. Android项目实战_手机安全卫士拦截骚扰

    ###1.骚扰拦截需求分析1.界面1.1 黑名单列表界面1.2 添加黑名单界面2.功能2.1 黑名单的添加.删除2.2 拦截电话2.3 拦截短信 ###2.黑名单数据库的创建1.分析需要的字段id 主 ...

  7. Android项目实战_手机安全卫士流量统计

    ## 1.抽屉控件SlidingDrawer:一定要配置android:handle(把手)和android:content(内容),并在子View中添加把手和内容的布局```java <Sli ...

  8. Android项目实战_手机安全卫士进程管理

    ###1.设备进程信息获取获取设备运行进程 ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVI ...

  9. Android项目实战--手机卫士开发系列教程

    <ignore_js_op> banner131010.jpg (71.4 KB, 下载次数: 0) 下载附件  保存到相册 2 分钟前 上传   Android项目实战--手机卫士01- ...

随机推荐

  1. 55. spring boot 服务配置和部署【从零开始学Spring Boot】

    Spring Boot 其默认是集成web容器的,启动方式由像普通Java程序一样,main函数入口启动.其内置Tomcat容器或Jetty容器,具体由配置来决定(默认Tomcat).当然你也可以将项 ...

  2. hdu 1527威佐夫博弈

    //http://www.cnblogs.com/bo-tao/archive/2012/04/16/2452633.html #include<stdio.h> #include< ...

  3. Drools介绍与使用

    Drools 是用 Java 语言编写的开放源码规则引擎,使用 Rete 算法对所编写的规则求值.Drools 允许使用声明方式表达业务逻辑.可以使用非 XML 的本地语言编写规则,从而便于学习和理解 ...

  4. 后台获得集合,变成json字符串,放到EL表达式,js进行获取遍历

    //把集合编程json字符串,放到el表达式 JSONArray array = new JSONArray(); JSONArray fromObject = array.fromObject(ar ...

  5. spring boot jpa 事务管理

    spring boot 对jpa的支持极为方便,基本上不需要作太多配置,只需要加上注解就能支持事务: @Controller @Transactional(rollbackOn = Exception ...

  6. org.apache.maven.archiver.MavenArchiver.getManifest(org.apache.maven.project.MavenProject, org.apach

    https://www.cnblogs.com/wxymg/p/8630471.html

  7. 奇妙的滚动css+html

    <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title> ...

  8. Linux内核project导论——前言

    想要研究linux内核.使用linux内核,首先要知道linux内核能做到什么,提供了什么.我看过非常多刚開始学习的人一进入公司就開始使用linux内核开发内核模块.使用的不管是通信方式.内存接口还是 ...

  9. python练习-跳出多层循环和购物车

    跳出多层循环:三层循环,最里层直接跳出3层 在Python中,函数运行到return这一句就会停止,因此可以利用这一特性,将功能写成函数,终止多重循环 def work(): for i in ran ...

  10. C#使用oledb连接excel运行Insert Into语句出现“操作必须使用一个可更新的查询”的解决的方法

    我错误发生时的环境:Windows 7,Framework 4.0,Microsoft Office 2007,VS2010,c# WinForm. 部分代码: string strConn = &q ...