您的位置:首页 > 其它

手机安全卫士第二天上

2016-01-03 08:55 357 查看

一、应用程序的主界面

1、画九宫格和列表:

activity_home.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<TextView
android:layout_width="match_parent"
android:layout_height="55dp"
android:background="#8866ff00"
android:gravity="center"
android:text="功能列表"
android:textColor="@color/black"
android:textSize="22sp" />

<GridView
android:id="@+id/gv_home"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:numColumns="3" />

</LinearLayout>
home_list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical" >

<ImageView
android:id="@+id/iv_item"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/app" />

<TextView
android:id="@+id/tv_item"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:text="手机防盗"
android:textColor="#000"
android:textSize="16sp" />

</LinearLayout>
res/vales/colors.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="black">#000</color>
</resources>
HomeActivity.java
package com.xbmu.mobilesafe;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.TextView;

public class HomeActivity extends Activity {
private GridView mGvHome;
private String[] names = { "手机防盗", "通讯卫士", "软件管理", "进程管理", "流量统计", "手机杀毒",
"缓存清理", "高级工具", "设置中心" };

private int[] icons = { R.drawable.safe, R.drawable.callmsgsafe,
R.drawable.app, R.drawable.taskmanager, R.drawable.netmanager,
R.drawable.trojan, R.drawable.sysoptimize, R.drawable.atools,
R.drawable.settings };

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
mGvHome = (GridView) findViewById(R.id.gv_home);
mGvHome.setAdapter(new HomeAdapter());
}

private class HomeAdapter extends BaseAdapter {

@Override
public int getCount() {
return names.length;
}

@Override
public Object getItem(int position) {
return names[position];
}

@Override
public long getItemId(int position) {
return position;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = View.inflate(HomeActivity.this, R.layout.home_list_item, null);
ImageView ivItem = (ImageView) view.findViewById(R.id.iv_item);
TextView tvItem = (TextView) view.findViewById(R.id.tv_item);

tvItem.setText(names[position]);
ivItem.setImageResource(icons[position]);
return view;
}

}
}
运行效果图:



2、自定义可以滚动的TextView(跑马灯效果)

activity_home.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<TextView
android:layout_width="match_parent"
android:layout_height="55dp"
android:background="#8866ff00"
android:gravity="center"
android:text="功能列表"
android:textColor="@color/black"
android:textSize="22sp" />
<!-- android:ellipsize="marquee"设置TextView具有跑马灯效果 -->

<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:layout_marginTop="5dp"
android:ellipsize="marquee"
android:singleLine="true"
android:text="手机卫士,有最新版本了,小伙伴们感觉来下载,先下载有优先大礼包"
android:textColor="@color/black"
android:textSize="16sp" />

<GridView
android:id="@+id/gv_home"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:verticalSpacing="20dp"
android:numColumns="3" />

</LinearLayout>

添加了具有跑马灯效果的TextView,但是遗憾的是运行起来后,TextView中的文本并没有跑起来,效果没有实现。
这是因为TextView没有获取到焦点,HomeActivity的焦点被GridView占有了,因此我们可以通过以下两种方式解决。
自定义具有跑马灯效果的TextView

FocusedTextView.java

package com.xbmu.mobilesafe.view;

import android.content.Context;
import android.util.AttributeSet;
import android.widget.TextView;
/**
* 获取焦点的TextView
* @author Administrator
*
*/
public class FocusedTextView extends TextView{
/**有style样式的话 会走此方法*/
public FocusedTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
/**有属性时走此方法*/
public FocusedTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
/**用代码new对象时,走此方法*/
public FocusedTextView(Context context) {
super(context);
}
/**
* 表示有没有获取焦点
* 跑马灯要运行,首先要调用此函数判断是否有焦点,是true的话,跑马灯才会有效果。
* 所以我们不管实际上TextView有没有焦点,我们都强制返回true,让跑马灯有焦点。
*/
@Override
public boolean isFocused() {
return true;
}
}
activity_home.xml
<!--android:ellipsize="marquee"设置TextView具有跑马灯效果  -->
<com.xbmu.mobilesafe.view.FocusedTextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="手机卫士,有最新版本了,小伙伴们感觉来下载,先下载有优先大礼包"
android:singleLine="true"
android:ellipsize="marquee"
android:textColor="@color/black"
android:textSize="16sp" />
运行起程序,跑马灯效果实现了。
使用TextView中的属性,让其获取焦点,实现跑马灯效果:



运行效果图:



3、完成GridView中item的点击事件 & 设置中心页面 & 自定义View

setting_list_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="65dp"
android:padding="5dp" >

<TextView
android:id="@+id/tv_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="自动更新设置"
android:textColor="@color/black"
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:text="自动更新已经开启"
android:textColor="#a000"
android:textSize="15sp" />

<CheckBox
android:id="@+id/cb_state"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true" />

<View
android:layout_width="match_parent"
android:layout_height="0.5dp"
android:layout_alignParentBottom="true"
android:background="#6000" />
</RelativeLayout>

</LinearLayout>
SettingItemView.java
package com.xbmu.mobilesafe.view;

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.CheckBox;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.xbmu.mobilesafe.R;

public class SettingItemView extends RelativeLayout {

private TextView tvTitle;
private TextView tvDesc;
private CheckBox cbState;
public SettingItemView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initView();
}

public SettingItemView(Context context, AttributeSet attrs) {
super(context, attrs);
initView();
}

public SettingItemView(Context context) {
super(context);
initView();
}
/**初始化布局*/
private void initView() {
//将自定义好的布局文件设置给当前的SettingItemView
View.inflate(getContext(), R.layout.setting_list_item, this);
tvTitle = (TextView) findViewById(R.id.tv_title);
tvDesc = (TextView) findViewById(R.id.tv_desc);
cbState = (CheckBox) findViewById(R.id.cb_state);
}
/**设置标题*/
public void setTitle(String title){
tvTitle.setText(title);
}
/**设置描述*/
public void setDesc(String desc){
tvDesc.setText(desc);
}
/**判断当前状态是否勾选*/
public boolean isChecked(){
return cbState.isChecked();
}
/**设置当前的勾选状态*/
public void setChecked(boolean checked){
cbState.setChecked(checked);
}
}
activity_setting.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<TextView
style="@style/TitleStyle"
android:text="设置中心" />
<com.xbmu.mobilesafe.view.SettingItemView
android:id="@+id/siv"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>

</LinearLayout>
res/values/styles.xml
因为每个Activity都有个标题,它是使用了TextView控件实现的。为了不让代码显得臃肿,提高代码的复用性,我们给这样的TextView设置一个样式TtileStyle,
如果需要这样效果的TextView的时候,就直接引用该样式文件,即可。
<style name="TitleStyle">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">55dp</item>
<item name="android:background">#8866ff00</item>
<item name="android:gravity">center</item>
<item name="android:textColor">@color/black</item>
<item name="android:textSize">22sp</item>
</style>
SettingActivity.java
package com.xbmu.mobilesafe;

import com.xbmu.mobilesafe.view.SettingItemView;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;

public class SettingActivity extends Activity {
private SettingItemView mSiv;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_setting);
mSiv = (SettingItemView) findViewById(R.id.siv);
mSiv.setTitle("设置自动更新");
mSiv.setDesc("自动更新已经开启");

//设置监听事件
mSiv.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
//判断当前的勾选状态
if(mSiv.isChecked()){
mSiv.setChecked(false);
mSiv.setTitle("设置自动更新");
mSiv.setDesc("自动更新已经关闭");
}else{
mSiv.setChecked(true);
mSiv.setTitle("设置自动更新");
mSiv.setDesc("自动更新已经开启");
}

}
});
}
}
运行效果:



我们可以通过观察运行效果发现:当地设置页面中的条目时,可以根据复选框的选中状态,设置的描述信息也改变了。
但是当我们点击复选框的时候,描述信息并没有改变。这就是一个很小的bug,影响用户的体验效果。
解决思路:禁止掉复选框checkbox的点击事件



然后运行起来,就解决了上面的小bug。
使用SharedPreferences保存选中的状态:
SettingActivity.java

package com.xbmu.mobilesafe;

import android.app.Activity;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import com.xbmu.mobilesafe.view.SettingItemView;

public class SettingActivity extends Activity {
private SettingItemView mSiv;//设置升级
private SharedPreferences sPre;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_setting);
mSiv = (SettingItemView) findViewById(R.id.siv);
mSiv.setTitle("设置自动更新");

sPre = getSharedPreferences("config", MODE_PRIVATE);
boolean isChecked = sPre.getBoolean("checked", true);
if(isChecked){
mSiv.setDesc("自动更新已经开启");
mSiv.setChecked(true);
}else{
mSiv.setDesc("自动更新已经关闭");
mSiv.setChecked(false);
}

//设置监听事件
mSiv.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
//判断当前的勾选状态
if(mSiv.isChecked()){
mSiv.setChecked(false);
mSiv.setDesc("自动更新已经关闭");
sPre.edit().putBoolean("checked", false).commit();
}else{
mSiv.setChecked(true);
mSiv.setDesc("自动更新已经开启");
sPre.edit().putBoolean("checked", true).commit();
}

}
});
}
}
运行效果:



在SplashActivity中获取是否升级的配置信息,让设置中心中的选中状态判断是否升级更新
SplashActivity.java
private SharedPreferences sPre;

@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("版本号:" + getVersionName());

sPre = getSharedPreferences("config", MODE_PRIVATE);
boolean isChecked = sPre.getBoolean("checked", true);
if(isChecked){
//从服务器获取最新版本号并进行校验
checkVersion();
}else{
handler.sendEmptyMessageDelayed(CODE_ENTER_HOME, 2000);//延迟2秒后发送消息
}

}
运行效果:



4、自定义属性

通过上面代码的编写,发现写一个设置页面的item,要在SettingActivity里面写那么多代码,而且有些代码还要重复写,这样显得代码很臃肿。
因此,我们在这里还可以优化代码:
res/vales/attrs.xml
<?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>
activity_setting.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xbmu="http://schemas.android.com/apk/res/com.xbmu.mobilesafe"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<TextView
style="@style/TitleStyle"
android:text="设置中心" />

<com.xbmu.mobilesafe.view.SettingItemView
android:id="@+id/siv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xbmu:desc_off="自动更新已经关闭"
xbmu:desc_on="自动更新已经开启"
xbmu:title="设置自动更新" />

</LinearLayout>
SettingItemView.java
package com.xbmu.mobilesafe.view;

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.CheckBox;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.xbmu.mobilesafe.R;

public class SettingItemView extends RelativeLayout {

private static final String NAMESPACE = "http://schemas.android.com/apk/res/com.xbmu.mobilesafe";
private TextView tvTitle;
private TextView tvDesc;
private CheckBox cbState;
private String title;
private String descOn;
private String descOff;
public SettingItemView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initView();
}

public SettingItemView(Context context, AttributeSet attrs) {
super(context, attrs);

//		int count = attrs.getAttributeCount();
//		for (int i = 0; i < count; i++) {
//			String attrName = attrs.getAttributeName(i);
//			String attrValue = attrs.getAttributeValue(i);
//			System.out.println(attrName+"="+attrValue);
//		}

//根据属性名,获取属性值
title = attrs.getAttributeValue(NAMESPACE, "title");
descOn = attrs.getAttributeValue(NAMESPACE, "desc_on");
descOff = attrs.getAttributeValue(NAMESPACE, "desc_off");
initView();
}

public SettingItemView(Context context) {
super(context);
initView();
}
/**初始化布局*/
private void initView() {
//将自定义好的布局文件设置给当前的SettingItemView
View.inflate(getContext(), R.layout.setting_list_item, this);
tvTitle = (TextView) findViewById(R.id.tv_title);
tvDesc = (TextView) findViewById(R.id.tv_desc);
cbState = (CheckBox) findViewById(R.id.cb_state);

setTitle(title);//设置标题
}
/**设置标题*/
public void setTitle(String title){
tvTitle.setText(title);
}
/**设置描述*/
public void setDesc(String desc){
tvDesc.setText(desc);
}
/**判断当前状态是否勾选*/
public boolean isChecked(){
return cbState.isChecked();
}
/**设置当前的勾选状态*/
public void setChecked(boolean checked){
cbState.setChecked(checked);

//根据选择的状态,更新文本描述
if(checked){
setDesc(descOn);
}else{
setDesc(descOff);
}
}
}
SettingActivity.java
package com.xbmu.mobilesafe;

import android.app.Activity;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;

import com.xbmu.mobilesafe.view.SettingItemView;

public class SettingActivity extends Activity {
private SettingItemView mSiv;// 设置升级
private SharedPreferences sPre;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_setting);
mSiv = (SettingItemView) findViewById(R.id.siv);

sPre = getSharedPreferences("config", MODE_PRIVATE);
boolean isChecked = sPre.getBoolean("checked", true);
if (isChecked) {
mSiv.setChecked(true);
} else {
mSiv.setChecked(false);
}

// 设置监听事件
mSiv.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
// 判断当前的勾选状态
if (mSiv.isChecked()) {
// 设置不勾选
mSiv.setChecked(false);

// 更新SharedPreferences
sPre.edit().putBoolean("checked", false).commit();
} else {
mSiv.setChecked(true);
sPre.edit().putBoolean("checked", true).commit();
}

}
});
}
}

5、总结自定义组合控件的过程

1、声明一个View对象 继承相对布局,或者线性布局 或者其他的ViewGroup。
2、在自定义的View对象里面重写它的构造方法。在构造方法里面就把布局都初始化完毕。
3、根据业务需求 添加一些api方法,扩展自定义的组合控件;
4、希望在布局文件里面 可以自定义一些属性。
5、声明自定义属性的命名空间。
xmlns:xbmu="http://schemas.android.com/apk/res/com.xbmu.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
获取那些定义的属性。

6、闪屏页面的渐变动画

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:id="@+id/rl_root"
    
    android:background="@drawable/launcher_bg" >

SplashActivity.java
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);// 默认是隐藏的

rlRoot = (RelativeLayout) findViewById(R.id.rl_root);

tvVersion.setText("版本号:" + getVersionName());

sPre = getSharedPreferences("config", MODE_PRIVATE);
boolean isChecked = sPre.getBoolean("checked", true);
if(isChecked){
//从服务器获取最新版本号并进行校验
checkVersion();
}else{
handler.sendEmptyMessageDelayed(CODE_ENTER_HOME, 2000);//延迟2秒后发送消息
}

//渐变的动画效果
AlphaAnimation aa = new AlphaAnimation(0.3f, 1.0f);
aa.setDuration(3000);
rlRoot.setAnimation(aa);
}

7、手机防盗登录密码校验

password_set_dialog.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<TextView
android:id="@+id/textView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#66ff6600"
android:gravity="center"
android:padding="10dp"
android:text="设置密码"
android:textColor="@color/black"
android:textSize="20sp" />

<EditText
android:id="@+id/et_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="请输入密码"
android:inputType="textPassword" />

<EditText
android:id="@+id/et_password_confrim"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="请再次输入密码"
android:inputType="textPassword" />

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >

<Button
android:id="@+id/btn_ok"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="确定" />

<Button
android:id="@+id/btn_cancel"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="取消" />
</LinearLayout>

</LinearLayout>
HomeActivity.java
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
mGvHome = (GridView) findViewById(R.id.gv_home);
mGvHome.setAdapter(new HomeAdapter());
//设置GridView的监听事件
mGvHome.setOnItemClickListener(new OnItemClickListener() {

@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
switch (position) {
case 0://手机防盗页面
showPasswordSetDialog();
break;
case 8://设置中心页面
startActivity(new Intent(HomeActivity.this, SettingActivity.class));

break;

default:
break;
}
}
});
}
/**设置密码对话框*/
protected void showPasswordSetDialog() {
//判断是否设置过密码
//没有设置过,弹出设置密码的对话框
AlertDialog.Builder builder = new AlertDialog.Builder(this);
AlertDialog dialog = builder.create();
View view = View.inflate(this, R.layout.password_set_dialog, null);
dialog.setView(view);//将自定义的布局文件设置给对话框
dialog.show();

}
运行效果:



但是,运行在2.*版本的模拟器上的时候,会出现这种效果,特别难看。



为了解决这个问题,我们首先将对话框的背景颜色设置为白色。



运行后的效果,稍微有点改变,但是边框还是有黑色的,我们再次修改:



HomeActivity.java
/**设置密码对话框*/
protected void showPasswordSetDialog() {
//判断是否设置过密码
//没有设置过,弹出设置密码的对话框
AlertDialog.Builder builder = new AlertDialog.Builder(this);
AlertDialog dialog = builder.create();
View view = View.inflate(this, R.layout.password_set_dialog, null);
//		dialog.setView(view);//将自定义的布局文件设置给对话框

dialog.setView(view, 0, 0, 0, 0);//将自定义的布局文件设置给对话框,并将边距都设置为0,保证在2.*版本的模拟器上运行没问题

dialog.show();

}
运行效果:



在高版本的模拟器上效果也是很好的。
处理确定和取消按钮:
HomeActivity.java
/**设置密码对话框*/
protected void showPasswordSetDialog() {
//判断是否设置过密码
//没有设置过,弹出设置密码的对话框
AlertDialog.Builder builder = new AlertDialog.Builder(this);
final AlertDialog dialog = builder.create();
View view = View.inflate(this, R.layout.password_set_dialog, null);
//		dialog.setView(view);//将自定义的布局文件设置给对话框
dialog.setView(view, 0, 0, 0, 0);//将自定义的布局文件设置给对话框,并将边距都设置为0,保证在2.*上的模拟器上运行没问题

final EditText etPassword = (EditText) view.findViewById(R.id.et_password);
final EditText etPasswordConfrim = (EditText) view.findViewById(R.id.et_password_confrim);

Button btnOk = (Button) view.findViewById(R.id.btn_ok);
Button btnCancel = (Button) view.findViewById(R.id.btn_cancel);
//点击了确认按钮
btnOk.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
//获取用户输入的密码
String password = etPassword.getText().toString().trim();
String passwordConfrim = etPasswordConfrim.getText().toString().trim();
//判断用户是否输入了密码
if(!TextUtils.isEmpty(password) && !TextUtils.isEmpty(passwordConfrim)){
//判断两次输入的是否一致
if(password.equals(passwordConfrim)){
Toast.makeText(HomeActivity.this, "登录成功", 0).show();
}else{
Toast.makeText(HomeActivity.this, "两次输入的密码不一致", 0).show();
}
}else{
Toast.makeText(HomeActivity.this, "输入框不能为空", 0).show();
}
}
});
//点击了取消按钮,对话框消失
btnCancel.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
dialog.dismiss();

}
});

dialog.show();

}
运行效果:



将是否设置过密码记录在SharedPreferences中,并将设置的密码保存在SharedPreferences中。
HomeActivity.java
package com.xbmu.mobilesafe;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

public class HomeActivity extends Activity {
private GridView mGvHome;
private String[] names = { "手机防盗", "通讯卫士", "软件管理", "进程管理", "流量统计", "手机杀毒",
"缓存清理", "高级工具", "设置中心" };

private int[] icons = { R.drawable.safe, R.drawable.callmsgsafe,
R.drawable.app, R.drawable.taskmanager, R.drawable.netmanager,
R.drawable.trojan, R.drawable.sysoptimize, R.drawable.atools,
R.drawable.settings };

private SharedPreferences sPre;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);

sPre = getSharedPreferences("config", MODE_PRIVATE);

mGvHome = (GridView) findViewById(R.id.gv_home);
mGvHome.setAdapter(new HomeAdapter());
// 设置GridView的监听事件
mGvHome.setOnItemClickListener(new OnItemClickListener() {

@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
switch (position) {
case 0:// 手机防盗页面
showPasswordDialog();// 显示密码对话框
break;
case 8:// 设置中心页面
startActivity(new Intent(HomeActivity.this,
SettingActivity.class));

break;

default:
break;
}
}
});
}

/** 显示密码弹窗 */
<span style="white-space:pre">	</span>protected void showPasswordDialog() {
<span style="white-space:pre">		</span>// 判断是否设置过密码
<span style="white-space:pre">		</span>String password = sPre.getString("password", null);
<span style="white-space:pre">		</span>if (!TextUtils.isEmpty(password)) {
<span style="white-space:pre">			</span>// 设置过密码,弹出输入密码对话框
<span style="white-space:pre">			</span>showPasswordInputDialog();
<span style="white-space:pre">		</span>} else {
<span style="white-space:pre">			</span>//没有设置过,弹出设置密码对话框
<span style="white-space:pre">			</span>showPasswordSetDialog();
<span style="white-space:pre">		</span>}
<span style="white-space:pre">	</span>}

/** 设置密码对话框 */
protected void showPasswordSetDialog() {

// 没有设置过,弹出设置密码的对话框
AlertDialog.Builder builder = new AlertDialog.Builder(this);
final AlertDialog dialog = builder.create();
View view = View.inflate(this, R.layout.password_set_dialog, null);
// dialog.setView(view);//将自定义的布局文件设置给对话框
dialog.setView(view, 0, 0, 0, 0);// 将自定义的布局文件设置给对话框,并将边距都设置为0,保证在2.*上的模拟器上运行没问题

final EditText etPassword = (EditText) view
.findViewById(R.id.et_password);
final EditText etPasswordConfrim = (EditText) view
.findViewById(R.id.et_password_confrim);

Button btnOk = (Button) view.findViewById(R.id.btn_ok);
Button btnCancel = (Button) view.findViewById(R.id.btn_cancel);
// 点击了确认按钮
btnOk.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
// 获取用户输入的密码
String password = etPassword.getText().toString().trim();
String passwordConfrim = etPasswordConfrim.getText().toString()
.trim();
// 判断用户是否输入了密码
if (!TextUtils.isEmpty(password)
&& !TextUtils.isEmpty(passwordConfrim)) {
// 判断两次输入的是否一致
if (password.equals(passwordConfrim)) {

// 设置密码成功了,将信息保存在SharedPreferences中
sPre.edit().putString("password", password).commit();// 保存密码在SharedPreferences中

Toast.makeText(HomeActivity.this, "登录成功", 0).show();
dialog.dismiss();
} else {
Toast.makeText(HomeActivity.this, "两次输入的密码不一致", 0)
.show();
}
} else {
Toast.makeText(HomeActivity.this, "输入框不能为空", 0).show();
}
}
});
// 点击了取消按钮,对话框消失
btnCancel.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
dialog.dismiss();

}
});
dialog.show();
}

/** 输入密码对话框 */
private void showPasswordInputDialog() {
// 没有设置过,弹出设置密码的对话框
AlertDialog.Builder builder = new AlertDialog.Builder(this);
final AlertDialog dialog = builder.create();
View view = View.inflate(this, R.layout.password_input_dialog, null);
dialog.setView(view, 0, 0, 0, 0);// 将自定义的布局文件设置给对话框,并将边距都设置为0,保证在2.*上的模拟器上运行没问题

final EditText etPassword = (EditText) view
.findViewById(R.id.et_password);

Button btnOk = (Button) view.findViewById(R.id.btn_ok);
Button btnCancel = (Button) view.findViewById(R.id.btn_cancel);
// 点击了确认按钮
btnOk.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
// 获取用户输入的密码
String password = etPassword.getText().toString().trim();
// 判断用户是否输入了密码
if (!TextUtils.isEmpty(password)) {
// 判断输入的密码和设置过的密码(保存在SharedPreferences中)是否一样
String savePassword = sPre.getString("password", null);
if (password.equals(savePassword)) {
Toast.makeText(HomeActivity.this, "登录成功", 0).show();
dialog.dismiss();
} else {
Toast.makeText(HomeActivity.this, "密码不正确", 0).show();
}
} else {
Toast.makeText(HomeActivity.this, "输入框不能为空", 0).show();
}
}
});
// 点击了取消按钮,对话框消失
btnCancel.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
dialog.dismiss();

}
});
dialog.show();

}
//...
}

运行效果:



通过DO命令窗口查看config.xml文件里面的信息




8、root权限介绍:

什么是Root权限? Root权限相当于系统管理员权限, 有了root权限,就可以随意修改和删除手机内部的文件.

一般手机购买之后, 都没有root权限. 厂商考虑到安全性因素,不允许用户或者第三方app删除和修改手机的内部文件(当然,sdcard的内容可以随意修改,不需要root权限)

如何获取root权限?

可以用第三方软件,比如刷机大师等. 一键root

有了Root后可以干嘛?

1. 刷机

2. 删除手机内置的app

3. 访问data/data目录的文件,并进行修改

怎么才能知道手机有么有root?

1. 刷机大师(小白用户用此方法)

2. 查看是否可以访问data/data目录,如果可以,就说明已经root了

3. cmd命令行,运行adb shell, 如果显示#,表示已经root, 如果显示$,表示没有root(如果用真机运行,即使root了,也显示$,这时候,运行命令su,可以直接获取管理员权限)

9、md5加密

计算字符串或文件的特征码(数字指纹), 不可逆, 因为任何文件或字符串算出来的md5都是32位!

MD5Util.java

package com.xbmu.mobilesafe.tools;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class MD5Util {
/**
* MD5加密
* @param password
* @return
*/
public static String encode(String password){

try {
MessageDigest instance = MessageDigest.getInstance("MD5");//获取md5算法对象
byte[]  digest = instance.digest(password.getBytes());//对字符串加密,返回字节数组
StringBuffer sb = new StringBuffer();
for (byte b : digest) {
int i = b & 0xff;//获取字节的低八位有效值
String hexString = Integer.toHexString(i);//将整数转换成十六进制
if(hexString.length() < 2){
hexString = "0"+hexString;
}
sb.append(hexString);
}
return sb.toString();
} catch (NoSuchAlgorithmException e) {
//没有该算法时抛出异常
e.printStackTrace();
}
return null;
}
}

修改HomeActivity|.java

在showPasswordSetDialog()方法中

sPre.edit().putString("password", MD5Util.encode(password)).commit();// 保存密码在SharedPreferences中

在showPasswordInputDialog()方法中

// 点击了确认按钮
btnOk.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
// 获取用户输入的密码
String password = etPassword.getText().toString().trim();
// 判断用户是否输入了密码
if (!TextUtils.isEmpty(password)) {
// 判断输入的密码和设置过的密码(保存在SharedPreferences中)是否一样
String savePassword = sPre.getString("password", "");
if (MD5Util.encode(password).equals(savePassword)) {
Toast.makeText(HomeActivity.this, "登录成功", 0).show();
dialog.dismiss();
} else {
Toast.makeText(HomeActivity.this, "密码不正确", 0).show();
}
} else {
Toast.makeText(HomeActivity.this, "输入框不能为空", 0).show();
}
}
});

通过DOS命令窗口查看:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: