14_自定义对话框_40

 1、画图两个对话框的样子;

 2、写大体逻辑代码;

showLostFindDialog();//进入手机防盗的对话框;

 

isSetupPwd();//判断是否设置过密码,用到共享偏好。

     private boolean isSetupPW(){

String password = sp.getString("password"null);

return !TextUtils.isEmpty(password);

}

 

showSetupPwdDialog();

 

showEnterDialog();

 

布局文件(dialog_setup.password.xml)

  <?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="300dip"

    android:layout_height="wrap_content"

    android:orientation="vertical" >

 

    <TextView

        android:layout_width="300dip"

        android:layout_height="40dip"

        android:background="#66ff6600"

        android:gravity="center"

        android:text="设置密码"

        android:textColor="#000000"

        android:textSize="20sp" />

 

    <EditText

        android:id="@+id/et_setup_pwd"

        android:layout_width="280dip"

        android:layout_height="wrap_content"

        android:hint="请输入密码" />

 

    <EditText

        android:id="@+id/et_setup_pwd_confirm"

        android:layout_width="280dip"

        android:layout_height="wrap_content"

        android:hint="请再输入密码" />

 

    <LinearLayout

        android:layout_width="280dip"

        android:layout_height="wrap_content"

        android:gravity="center"

        android:orientation="horizontal" >

 

        <Button

            android:id="@+id/ok"

            android:layout_width="140dip"

            android:layout_height="wrap_content"

            android:text="确定" >

        </Button>

 

        <Button

            android:id="@+id/cancel"

            android:layout_width="140dip"

            android:layout_height="wrap_content"

            android:text="取消" >

        </Button>

    </LinearLayout>

 

</LinearLayout>

 

showSetupPwdDialog();对话框的代码: 

 

  确定按钮:

          String password= et_setup_pwd.getText().toString().trim();

String password_confirm = et_setup_pwd_confirm.getText().toString().trim();

if(TextUtils.isEmpty(password)||TextUtils.isEmpty(password_confirm)){

Toast.makeText(getApplicationContext(), "密码为空", 0).show();

return ;

}

if(password.equals(password_confirm)){

//密码相同-保存并且进入手机防盗页面

Editor editor = sp.edit();

editor.putString("password", password);

editor.commit();

dialog.dismiss();

//进入手机防盗页面

Log.i(TAG, "密码已经保存,进入手机防盗页面");

}else{

Toast.makeText(getApplicationContext(), "密码不一致", 0).show();

return ;

}

取消按钮

前提dialog = builder.show();

   dialog.dismiss();

 

 

 

 

3、设置密码对话框部署并找出不好看的原因,并且修改;

       修改大小小于父控件;

4、设置密码对话框变得好看。加ID,并实现点击代码逻辑;

  初始化ID

  取消事件--dialog抽取出去:

  确定事件:

   

5、拷贝进入密码对话框布局文件,并命名为:dialog_enter_password.xml

6、拷贝进入密码对话框的代码并修改

 

 

7、总结:不同的布局文件里面各自的ID是可以重名的

   但是同一个布局文件里,相同的ID不允许重名的;

15_自定义对话框的细节_10

 

1、创建2.3模拟器展示对话框(有黑背景),4.122.3的区别,并说明原因

 

 

2、解决在2.3对话框有黑背景的问题

       设置背景为白:android:background="#ffffff"

 

   alertDialog = builder.create();

alertDialog.setView(view, 0, 0, 0, 0);

alertDialog.show();

 

 

16_密码的MD5加密_24

本知识点需要:手机能共享网络

 

1、为什么要加密--不加密的不安全

知识拓展:

root权限

买过来的手机是没有root权限的;

Root权限是linux系统的超级管理员权限;

 

如果你的手机刷机了,那就有root权限

 

模拟器能看到data/data里的数据,是为了方便开发者

没有root权限的手机是看不到data/data

 

root权限的符号:#

没有root权限的符号:$

 

 

查看config.xml命令

cat config.xml

 

 

 

2md5算法

不可逆的:原文--》密文、用系统的API可以实现;

123456 ---密文

1987 ----密文;

 算法步骤:

1、用每个byte去和11111111做与运算并且得到的是int类型的值:  

          byte & 11111111;

2、把int 类型转成 16进制并返回String类型;

3、不满八个二进制位就补全;

 

public static void main(String[] args) throws NoSuchAlgorithmException {

MessageDigest digest = MessageDigest.getInstance("md5");

String password = "123456";

byte [] result = digest.digest(password.getBytes());

StringBuffer buffer  = new StringBuffer();

for(byte b : result){

             //0xff是十六进制十进制为255

 

int nuber =  b & 0xff;

String str = Integer.toHexString(nuber);

if(str.length()==1){

buffer.append("0");

}

buffer.append(str);

}

//这就是MD5加密得到的值

System.out.println(buffer);

}

 

 没有事先准备的算法异常;

4、网站验证算法是否正确(www.cmd5.com)、加密再加密再演示

5、密码加盐

6、合并代码进入工程(MD5Utils)方法名:encode

7、删除config.xml (rm *),并演示;

 

 

17_手机防盗设置向导的第一个界面_34

准备:需要谷歌文档

1、演示百度输入法设置向导

2、创建LostFindActivity,HomeActivity激活并可以进入;

  confied判断是否用户设置向导,如果没有就进入设置向导;

3、创建Setup1Activity

4、自定义标题样式命名:text_title_style

5、自定义文本样式text_content_style(图片名star_big_on)。

6、小点图片(presence_onlinepresence_invisible

18_自定义按钮状态背景_15

1、在android-16\data\res\values\styles.xml看一下系统定义的Button样式,看一下低版本和版本的区别

2、看一下帮助文档(Develog/App Resources/Resource Types/drawbale/Button如何自定义;

   创建drawble目录 ,拷贝文档中定义的案例;

3、用美图秀秀自定义按钮背景(50*50),命名:button.xml

4、用别人的图片:button_bg.xml

5、用自己准备好的图片;

6、把做好的背景设置到设置密码对话框和输入密码对话框;

7、进模拟器设置里设置显示边框。

 

 

19_4个设置向导的UI完成和跳转事件_30

1、讲出几个布局文件的共性;

2、自定义下一个、上一个按钮样式;

3、创建多个Setup2AcitvitySetup3AcitvitySetup4Acitvity;并在功能清单注册;

4、定义点击事件在样式里:

5、代码里实现;

6、从手机防盗页面到第一个设置页面Intent

7、拷贝手机防盗页面,并完成跳转;

 

20_手机防盗页面的完成_15

 

 

21_shape形状资源_13

1、前提:重新进入设置向导控件没点击效果reEnterSetup

2、看文档Develop/API Guides/App Resources/Drawable/Shape Drawable

 

   单词:corners : 角  ;  gradient :梯度; solid:固定的; stroke: 边框--可以做下划线

       Rectangle : 矩形;dash :破折号 gap:间隙;

 

3、拷贝实例代码,文件命名(gradient_box.xml

<?xml version="1.0" encoding="utf-8"?>

<shape xmlns:android="http://schemas.android.com/apk/res/android"

    android:shape="rectangle">

    <corners android:radius="5dip"/>

    

    <gradient android:startColor="#ff0000"

        android:endColor="#00ff0000"/>

    

    <solid android:color="#ffffff" />

    

    <stroke android:width="3dip" android:color="#000000" android:dashGap="5dip"

        android:dashWidth="5dip"/>

    

</shape>

 

4、默认状态gradient_box.xml

 

 

<?xml version="1.0" encoding="utf-8"?>

<shape xmlns:android="http://schemas.android.com/apk/res/android"

    android:shape="rectangle">

    <corners android:radius="5dip"/>

    

    <solid android:color="#ffffff" />

    

    

</shape>

5、按下去状态状态gradient_box_press.xml

 

 

<?xml version="1.0" encoding="utf-8"?>

<shape xmlns:android="http://schemas.android.com/apk/res/android"

    android:shape="rectangle">

    <corners android:radius="5dip"/>

    

    <solid android:color="#22000000" />

    

    

</shape>

 

6、把两个状态整合在shape_bg.xml

7、并使用

 

 

 

 

22_设置向导页面的切换动画_12

1anim

2、下一步动画 位移动画

解释-100%p p:代表父窗体,100%:代表整个窗体,-:代码向左移动;

tran_out.xml

 

<?xml version="1.0" encoding="utf-8"?>

<translate  xmlns:android="http://schemas.android.com/apk/res/android"

    android:fromXDelta="0"

    android:toXDelta="-100%p"

    android:fromYDelta="0"

    android:toYDelta="0"

    android:duration="500"

    >

    

 

</translate>

 

Tran_in.xml

<?xml version="1.0" encoding="utf-8"?>

<translate  xmlns:android="http://schemas.android.com/apk/res/android"

    android:fromXDelta="100%p"

    android:toXDelta="0"

    android:fromYDelta="0"

    android:toYDelta="0"

    android:duration="500"

    >

 

</translate>

 

3、使用动画:

overridePendingTransition(R.anim.tran_in, R.anim.tran_out);

 

 

上一步动画

Tran_pre_out.xm;

 

<?xml version="1.0" encoding="utf-8"?>

<translate  xmlns:android="http://schemas.android.com/apk/res/android"

    android:fromXDelta="0"

    android:toXDelta="100%p"

    android:fromYDelta="0"

    android:toYDelta="0"

    android:duration="500"

    >

 

</translate>

 

 

Tran_pre_in.xm

 

<?xml version="1.0" encoding="utf-8"?>

<translate  xmlns:android="http://schemas.android.com/apk/res/android"

    android:fromXDelta="-100%p"

    android:toXDelta="0"

    android:fromYDelta="0"

    android:toYDelta="0"

    android:duration="500"

    >

 

</translate>

 

4、使用动画:

overridePendingTransition(R.anim.tran_pre_in, R.anim.tran_pre_out);

 

 

 

知识拓展:

有些手机上无法出现动画:是因为把播放动画的功能关闭了,为什么关闭呢,是为什么省点;

 

Android手机省电的几个技巧:

1.不要用动态的壁纸;

2.屏幕亮度调低一些;

3.3G网络关闭使用,2G网络,当然是不需要上网的情况下;

4.关闭手机执行动画;

5.经常杀一下后台的应用;

 

 

 

23_屏幕的滑动切换&s抽取父类_39

1、在Setup1Activity定义一个手势识别器;GestureDetector 

2、并画图分析

 

3、抽取next()--->shownext();代码

public class Setup1Activity extends Activity {

//1、声明一个手势识别器

private GestureDetector gestureDetector;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_setup1);

//2、初始化一个手势识别器

gestureDetector = new GestureDetector(thisnew GestureDetector.SimpleOnGestureListener(){

    //当时手指在屏幕上滑动时调用的方法

@Override

public boolean onFling(MotionEvent e1, MotionEvent e2,

float velocityX, float velocityY) {

if((e2.getRawX() - e1.getRawX()) > 200){

//显示上一个页面:从左向右滑动

System.out.println("显示上一个页面");

return true;

}

if((e1.getRawX() - e2.getRawX()) > 200){

//显示下一个页面:从右向左滑动

shownext();

System.out.println("显示下一个页面");

return true;

}

return super.onFling(e1, e2, velocityX, velocityY);

}

});

}

//3、用手势识别器,检查屏幕上的手势识别器

@Override

public boolean onTouchEvent(MotionEvent event) {

gestureDetector.onTouchEvent(event);

return super.onTouchEvent(event);

}

public void next(View view){

shownext();

}

 

private void shownext() {

Intent  intent = new Intent(this,Setup2Activity.class);

startActivity(intent);

finish();//关闭当前的页面

overridePendingTransition(R.anim.tran_in, R.anim.tran_out);

}

 

}

 

4、使用注册

5、抽取到基类BaseSetupActivity

6、屏蔽竖值方向的滑动;

 

 

 

 

if(Math.abs((e2.getRawY() - e1.getRawY())) >100){

Toast.makeText(getBaseContext(), "不能这样滑动", 0).show();

return true;

}

 

 

7、屏蔽滑动慢

 

if(Math.abs(velocityX)< 200){

Toast.makeText(getBaseContext(), "滑动有些慢哥们", 0).show();

return true;

}

24_绑定sim_23

手机防盗最核心的就是绑定sim卡;

为什么不绑定手机号码呢?

因为有些SIM卡里没有写入手机号码,比如移动的卡和联通的卡等等。

1、读取SiM卡的串口号代码:

  siv_setup2_bindsim.setOnClickListener(new OnClickListener() {

@Override

public void onClick(View v) {

if(siv_setup2_bindsim.isChecked()){

Editor editor =  sp.edit();

editor.putString("sim"null);

editor.commit();

siv_setup2_bindsim.setChecked(false);

}else{

//得到SiM卡的串口号

String sim = tm.getSimSerialNumber();

Editor editor =  sp.edit();

editor.putString("sim", sim);

editor.commit();

siv_setup2_bindsim.setChecked(true);

}

}

});

TelephonyManager 加权限

<uses-permission android:name="android.permission.READ_PHONE_STATE"/>

 

2、记录串口号;

3、在基类BaseSetupActivtiy 初始化共享偏好;

4、用命令查看数据是否设置成功;

5、Setup2Activity演示super.onCreate()的作用

 

 

 

 

25_检查手机是否更换sim_23

原理:1sim插入一般会拔掉电源,会导致开启重启;2、侧面卡槽也会导致手机重启--重启通讯模块;

 

1、创建新包com.itheima.mobilesafe.receiver 和新类(BootCompleteReceiver)

功能清单文件:

 

 

<receiver android:name="com.itheima.mobilesafe.receiver.BootCompleteReceiver" >

    <intent-filter>

            <action android:name="android.intent.action.BOOT_COMPLETED" />

     </intent-filter>

 </receiver>

 

2、权限

  <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>

 

 

 

  接收信息

 

public class BootCompleteReceiver extends BroadcastReceiver {

private SharedPreferences sp;

private TelephonyManager tm;

 

@Override

public void onReceive(Context context, Intent intent) {

//检查当前的手机sim,读取原来绑定的sim卡,如果发现两个卡不一样,说明手机可能被盗。需要偷偷的发短信报警;

sp = context.getSharedPreferences("config", context.MODE_PRIVATE);

String bindsim = sp.getString("sim""")+"a";

tm = (TelephonyManager) context.getSystemService(context.TELEPHONY_SERVICE);

String realsim = tm.getSimSerialNumber();

if(bindsim.equals(realsim)){

//手机卡没有变更,就是你的手机和你的卡;

}else{

//sim卡变更了,发送报警信息;

System.out.println("sim卡变更了,发送报警信息");

}

}

 

}

3、关闭模拟器,重启演示;

 

26_读取手机联系人_40

authorities :当局

1、到开发环境data/data/目录下 com.android.providers.contacts/databases/导出到左面contacts2.db

2、用工具打开数据库关心三张表:raw_contactsdatamimetypes

3、创建一个新的工程去读取联系人SelectContact

4、创建一个得到所有联系人的方法 getContactInfos();----表的路径

 

 

List<Map<String, String>> data = new ArrayList<Map<String, String>>();

ContentResolver resolver = getContentResolver();

Uri uri = Uri.parse("content://com.android.contacts/raw_contacts");

Uri datauri = Uri.parse("content://com.android.contacts/data");

 

5、查询raw_contact表 取联系人id

 

 

 Cursor cursor = resolver.query(uri, new String[] { "contact_id" },

nullnullnull);

 

6、得到联系人的ID

 

 while (cursor.moveToNext()) {

String id = cursor.getString(0);

System.out.println("联系人的id为:" + id);

   }

 

 

7、查表data表到联系人的姓名和电话号码

 Map<String, String> map = new HashMap<String, String>();

// 查询data表 把当前联系人的姓名和电话new String[]{"data1","mimetype"}数据给取出来.

Cursor dataCursor = 

resolver.query(datauri, new String[]{"data1","mimetype"},

 

"raw_contact_id=?"new String[] { id }, null);

 

 

 

8、添加数据到map集合

  

 

   String data1 = dataCursor.getString(0);

   String mimetype = dataCursor.getString(1);

 

if ("vnd.android.cursor.item/phone_v2".equals(mimetype)) {

  System.out.println("电话:" + data1);

  map.put("phone", data1);

else if ("vnd.android.cursor.item/name".equals(mimetype)) {

  System.out.println("姓名:" + data1);

  map.put("name", data1);

 

}

 

 

 

9、读取联系人需要加权限

  <uses-permission android:name="android.permission.READ_CONTACTS"/>

 

 

知识回顾

URI(统一资源标识符)的使用方法

为系统的每一个资源给其一个名字,比方说通话记录。

1、每一个ContentProvider都拥有一个公共的URI,这个URI用于表示这个ContentProvider所提供的数据。 

2、Android所提供的ContentProvider都存放在android.provider包中。 将其分为A,B,C,D 4个部分:

A:标准前缀,用来说明一个Content Provider控制这些数据,无法改变的;"content://"

 B:URI 的标识,它定义了是哪个Content Provider提供这些数据。对于第三方应用程序,为了保证URI标识的唯一性,它必须是一个完整的、小写的 类名。这个标识在 元素的 authorities属性中说明:一般是定义该ContentProvider的包.类的名称;"content://hx.android.text.myprovider"

C:路径,不知道是不是路径,通俗的讲就是你要操作的数据库中表的名字,或者你也可以自己定义,记得在使用的时候保持一致就ok了;"content://hx.android.text.myprovider/tablename"

D:如果URI中包含表示需要获取的记录的ID;则就返回该id对应的数据,如果没有ID,就表示返回全部; "content://hx.android.text.myprovider/tablename/#" #表示数据id

 

 

 

 







----------------------------------------------------------------------------------------------------------------------------------------------------------

自定义组合控件

  1. 自定义一个View, 继承ViewGroup,比如RelativeLayout
  2. 编写组合控件的布局文件,在自定义的View中加载

        // 将自定义好的布局文件设置给当前的SettingItemView
    View.inflate(getContext(), R.layout.view_setting_item, this);
    
  3. 自定义属性

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,可以直接获取管理员权限)

MD5

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

数据库: 123456->e10adc3949ba59abbe56e057f20f883e 654321->e10adc3949ba59abbe56e057f20f883e

在线破解网站: http://www.cmd5.com/

对MD5进行"加盐"处理, 增强安全性 MD5(password)->MD5(password + 用户昵称 + 用户id...)

.9.png(9-Patch)

通过黑色边线来描述图片的拉伸情况和填充文字的方式 上边线表示图片水平拉伸, 左边线表示垂直拉伸 右边线表示垂直填充区域, 下边线表示水平填充区域

状态选择器(selector)

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:drawable="@drawable/function_greenbutton_pressed" android:state_pressed="true"/>//按下的图片
    <!-- pressed -->
    <item android:drawable="@drawable/function_greenbutton_pressed" android:state_focused="true"/>//获取焦点的图片
    <!-- focused -->
    <item android:drawable="@drawable/function_greenbutton_normal"/>
    <!-- default -->//默认图片

</selector>

 <Button
        android:background="@drawable/btn_green_selector"
   />//将选择器设置给Button

状态选择器(selector)

md5密码加盐

http://www.blogjava.net/heyang/archive/2010/11/28/339233.html 按:以下还是炒冷饭,如果您对加盐了解就不用往下看了,以免浪费宝贵时间。 如果不了解下文部分细节的话,您可以参考这篇文章:使用MD5对存放在数据库中用户密码进行保护 直接对重要数据进行MD5处理后,反向解密确实难度很大,但还是可以找出破绽的,请看下图: (图片不能显示就文字说明一下) 例如:两个人或多个人的密码相同,通过md5加密后保存会得到相同的结果。破一个就可以破一片的密码。 如果名为李自成的用户可以查看数据库,那么他可以观察到自己的密码和别人的密码加密后的结果都是一样,那么,别人用的和自己就是同一个密码,这样,就可以利用别人的身份登录了。 那么我们以前的加密方法是否对这种行为失效了呢?其实只要稍微混淆一下就能防范住了,这在加密术语中称为“加盐”。具体来说就是在原有材料(用户自定义密码)中加入其它成分(一般是用户自有且不变的因素),以此来增加系统复杂度。当这种盐和用户密码相结合后,再通过摘要处理,就能得到隐蔽性更强的摘要值。下面请见代码: // 对密码进行加盐后加密,加密后再通过Hibernate往数据库里存        String changedPswd=DigestUtils.md5Hex(name+pswd); 就是这样简单,上面代码中盐就是用户名,可以的话还可以用用户注册时的邮件,注册时间等非空信息(如果是空信息这个加盐处理会失效)。 下面是数据库中两个用户的记录,他们的实际登录密码都是123456,但光看用户记录是完全看不出来的。这下别有用心的人打开数据库看到的密码都完全不一样,他以前的手段就失效了。 因为密码是md5处理的密码加用户名,因为用户名都不相同,所以即使密码相同的用户,保存到数据库中密码也是不同的。
Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐