手机安全卫士第二天上
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命令窗口查看:
相关文章推荐
- java.util.concurrent介绍
- 2016 1月1日-1月1日python 学习总结
- php浮点数精确运算
- 注册界面的优化之ActionBar组件的应用之(一)ActionBar组件的布局实现
- 1.10-PCB库的管理应用
- COS-7设备管理
- Exchange2003/2010共存模式环境迁移
- iOS单例 单例宏
- Openstack环境下配置MHA+LVS的注意事项
- 【Bug笔记】The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Path
- Linux常用命令
- 群管理之公告
- 自动获取外网ip
- POJ 3267-The Cow Lexicon(DP)
- 格式化时间
- 13.grep和正则表达式
- tomcat 多系统部署
- bzoj 2324 [ZJOI2011]营救皮卡丘(floyd,费用流)
- Yii2用Gii自动生成Module+Model+CRUD
- 基于用例点来度量软件规模并管理进度 之三