手机安全卫士第二天上

一、应用程序的主界面

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命令窗口查看:



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

上善若水

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值