admin管理员组文章数量:1666604
一、应用程序的主界面
1、画九宫格和列表:
activity_home.xml:<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android/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/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.drawablemanager,
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/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/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/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)mit();
}else{
mSiv.setChecked(true);
mSiv.setDesc("自动更新已经开启");
sPre.edit().putBoolean("checked", true)mit();
}
}
});
}
}
运行效果:
在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/apk/res/android"
xmlns:xbmu="http://schemas.android/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/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)mit();
} else {
mSiv.setChecked(true);
sPre.edit().putBoolean("checked", true)mit();
}
}
});
}
}
5、总结自定义组合控件的过程
1、声明一个View对象 继承相对布局,或者线性布局 或者其他的ViewGroup。
2、在自定义的View对象里面重写它的构造方法。在构造方法里面就把布局都初始化完毕。
3、根据业务需求 添加一些api方法,扩展自定义的组合控件;
4、希望在布局文件里面 可以自定义一些属性。
5、声明自定义属性的命名空间。
xmlns:xbmu="http://schemas.android/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/apk/res/android"
xmlns:tools="http://schemas.android/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/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.drawablemanager,
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)mit();// 保存密码在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))mit();// 保存密码在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命令窗口查看:
版权声明:本文标题:手机安全卫士第二天上 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://m.elefans.com/dianzi/1730069301a1221471.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论