好,今天天我們在完成我們這個項目裡面的一個自定義對話框的功能啦,它是在我們的第一個功能,手機防盜裡面的,我們在給手機防盜那裡加一個登陸的操作,這樣會更安全一些,是以我們就用到了一個對話框,為了讓它更好看一些,而且也學習一下怎樣自定義對話框,是以我們就開始學習一下啦
首先,我們先給我們的手機防盜的啟動界面,加一個快捷啟動的方式,就是在撥打電話的時候,輸入一個特定的号碼,然後就會啟動手機防盜那個界面,聽起來,是不是很酷呢,其實很簡單的,就是用一個廣播接收都,來接收打電話時發出來的廣播,然後捕獲它,然後就可以進行我們想要的操作啦,好,直接上代碼
先建立一個類com.xiaobin.security.receiver.callphonereceiver
<font color="#333333"><font face="arial">package com.xiaobin.security.receiver;
import android.content.broadcastreceiver;
import android.content.context;
import android.content.intent;
import com.xiaobin.security.ui.lostprotectedactivity;
public class callphonereceiver extends broadcastreceiver
{
@override
public void onreceive(context context, intent intent)
{
string outphonenumber = this.getresultdata();
if(outphonenumber.equals("1314")) //當監聽到使用者撥打的是1314的時候,就進行下面的操作,你可以把撥打的号碼做成參數的形式,讓使用者可配置
{
intent i = new intent(context, lostprotectedactivity.class);
//這個很重要,如果沒有這一句,那就會報錯,這一句是因為我們是在一個receiver裡面啟動一個activity的,但activity的啟動,都是放到一個棧裡面的,
//但receiver裡面沒有那個棧,是以我們要在這裡啟動一個activity,那就必須要指定這行代碼啦
i.setflags(intent.flag_activity_new_task);
context.startactivity(i);
setresultdata(null); //這行代碼是把廣播的資料設定為null,這樣就不會把剛剛那個号碼撥打出去啦,隻會啟動我們的activity
}
}
}
</font></font>
複制代碼
現在還不行的,我們還要在androidmainfest檔案裡面注冊這個廣播接收者
<font color="#333333"><font face="arial"><receiver
android:name="com.xiaobin.security.receiver.callphonereceiver">
<intent-filter android:priority="1000"><!-- 把優先級設定高一些,以便第一個拿到廣播 -->
<action android:name="android.intent.action.new_outgoing_call"/>
</intent-filter>
</receiver></font></font>
當然,我們還要加上相應的權限呢
<font color="#333333"><font face="arial"><uses-permission android:name="android.permission.process_outgoing_calls"/></font></font>
好啦,到現在為止,我們通過撥打電話,來啟動手機防盜這個功能就完成的啦,各位可以去試試 現在進入我們今天的重點,那就是自定義對話框啦,先上圖,看看我們的效果

下載下傳完之後,直接它兩個解壓出來,然後把apktool1.5.2.tar裡面的那個jar包,放到apktool-install-windows-r05-ibot.tar這個目錄下面,如圖
這樣子就會有3個檔案的啦,現在我們把android.jar出拷貝到這個目錄下面,然後在dos下面進行這個目錄,然後就運作apktool
d android.jar
就這樣,我們就會在剛剛那個目錄下面看到有一個解析出來的資源檔案夾的啦,而我們系統自己寫的ui資源全在裡面啦,我們有空的話,可以去看看,系統是怎樣自己寫的,然後自己就可以相應的進行修改啦好啦,說回我們今天的對話框,系統自己寫的對話框,其實就是一個主題,要用的時候,就使用那個主題,那麼,它就是在res/value/styles.xml裡面的,我們把那個檔案打開,然後搜尋theme.dialog,然後就可以看到系統自己寫的對話框啦
好啦,知道這些之後,我們有空就可以參考一下怎樣寫啦現在我們自己來寫,我們在我們的項目裡面的styles.xml檔案裡面寫上我們自己的對話框的樣式啦
<style name="mydialog" parent="@android:style/theme.dialog"><!-- 要繼承系統原來的對話框 -->
<item name="android:windowbackground">@drawable/title_background</item><!-- 指定背景顔色 -->
<item name="android:windownotitle">true</item><!-- 隐藏系統原來的标題欄 -->
</style>
因為我是教大家怎樣自定義對話框,是以為了簡單,我隻是寫了這兩個屬性而已,有興趣的,你們可以參考一下系統自己的,然後寫多一點,寫好我們的樣式之後,怎樣用呢其實很簡單,隻要在new一個dialog的時候,指定一下它的樣式就行的啦
dialog = new dialog(this, r.style.mydialog);
好啦,我們現在就結合我們今天的邏輯來看一下,我們的對話框的效果,我們今天要做的是,當使用者第一次啟動這個手機防盜這個功能的時候,要求使用者輸入一個登入密碼,然後以後進入這個功能的時候,都要輸入以前設定的密碼,而且我們的密碼是以md5加密後,存放到sharedpreferences裡面的既然是加密,那麼我們現在就先來寫一個加密的工具類啦com.xiaobin.security.utils.md5encoder
package com.xiaobin.security.utils;
import java.security.messagedigest;
import java.security.nosuchalgorithmexception;
public class md5encoder
public static string encode(string pwd)
try
messagedigest messagedigest = messagedigest.getinstance("md5");//拿到md5加密的對象
byte[] bytes = messagedigest.digest(pwd.getbytes());//傳回一個加密後的位元組數組
stringbuffer sb = new stringbuffer();
string tmp;
for(int i = 0; i < bytes.length; i++)
{
tmp = integer.tohexstring(0xff & bytes[i]);//把位元組轉換為16進制的字元串
if(tmp.length() == 1) //如果這個字元串,隻有一個字元,就要補0
{
sb.append("0" + tmp);
}
else
sb.append(tmp);
}
return sb.tostring();
catch (nosuchalgorithmexception e)
throw new runtimeexception("沒有這個加密算法" + e);
好啦,接下來,都是一些很簡單的邏輯處理而已,我們直接上代碼com.xiaobin.security.ui.lostprotectedactivity
package com.xiaobin.security.ui;
import android.app.activity;
import android.app.dialog;
import android.content.sharedpreferences;
import android.content.sharedpreferences.editor;
import android.os.bundle;
import android.view.view;
import android.view.view.onclicklistener;
import android.widget.button;
import android.widget.edittext;
import android.widget.toast;
import com.xiaobin.security.r;
import com.xiaobin.security.utils.md5encoder;
public class lostprotectedactivity extends activity implements onclicklistener
private sharedpreferences sp;
private dialog dialog;
private edittext password;
private edittext confirmpassword;
protected void oncreate(bundle savedinstancestate)
super.oncreate(savedinstancestate);
sp = getsharedpreferences("cofig", context.mode_private);
if(issetpassword())
showlogindialog();
else
showfirstdialog();
private void showlogindialog()
dialog = new dialog(this, r.style.mydialog);
view view = view.inflate(this, r.layout.login_dialog, null);
password = (edittext) view.findviewbyid(r.id.et_protected_password);
button yes = (button) view.findviewbyid(r.id.bt_protected_login_yes);
button cancel = (button) view.findviewbyid(r.id.bt_protected_login_no);
yes.setonclicklistener(this);
cancel.setonclicklistener(this);
dialog.setcontentview(view);
dialog.show();
private void showfirstdialog()
//dialog.setcontentview(r.layout.first_dialog);
view view = view.inflate(this, r.layout.first_dialog, null); //這樣來填充一個而已檔案,比較友善
password = (edittext) view.findviewbyid(r.id.et_protected_first_password);
confirmpassword = (edittext) view.findviewbyid(r.id.et_protected_confirm_password);
button yes = (button) view.findviewbyid(r.id.bt_protected_first_yes);
button cancel = (button) view.findviewbyid(r.id.bt_protected_first_no);
private boolean issetpassword()
string pwd = sp.getstring("password", "");
if(pwd.equals("") || pwd == null)
return false;
return true;
public void onclick(view v)
switch(v.getid())
case r.id.bt_protected_first_yes :
string fp = password.gettext().tostring().trim();
string cp = confirmpassword.gettext().tostring().trim();
if(fp.equals("") || cp.equals(""))
toast.maketext(this, "密碼不能為空", toast.length_short).show();
return;
if(fp.equals(cp))
{
editor editor = sp.edit();
editor.putstring("password", md5encoder.encode(fp));
editor.commit();
}
else
toast.maketext(this, "兩次密碼不相同", toast.length_short).show();
return;
dialog.dismiss();
break;
case r.id.bt_protected_first_no :
finish();
case r.id.bt_protected_login_yes :
string pwd = password.gettext().tostring().tostring();
if(pwd.equals(""))
toast.maketext(this, "請輸入密碼", toast.length_short).show();
string str = sp.getstring("password", "");
if(md5encoder.encode(pwd).equals(str))
dialog.dismiss();
toast.maketext(this, "密碼錯誤", toast.length_short).show();
case r.id.bt_protected_login_no :
default :
另外,還有兩個布局檔案,一個是第一次登入時,設定密碼的,一個是以後登入時,輸入密碼的first_dialog
<?xml version="1.0" encoding="utf-8"?>
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="300dip"
android:layout_height="280dip"
android:gravity="center_horizontal"
android:orientation="vertical" >
<textview
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textcolor="@android:color/white"
android:textsize="24sp"
android:text="@string/setpassword"/>
<linearlayout
android:layout_width="300dip"
android:layout_height="180dip"
android:background="#ffc8c8c8"
android:orientation="vertical">
<textview
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/setpassworddescription"/>
<edittext
android:id="@+id/et_protected_first_password"
android:layout_width="match_parent"
android:inputtype="textpassword"/>
android:text="@string/againpassword"/>
android:id="@+id/et_protected_confirm_password"
<linearlayout
android:layout_width="300dip"
android:layout_height="50dip"
android:gravity="center"
android:orientation="horizontal">
<button
android:id="@+id/bt_protected_first_yes"
android:layout_width="140dip"
android:layout_height="40dip"
android:text="@string/protectedyes"/>
android:id="@+id/bt_protected_first_no"
android:layout_marginleft="10dip"
android:text="@string/protectedno"/>
</linearlayout>
</linearlayout>
</linearlayout>
login_dialog.xml
android:layout_height="180dip"
android:text="@string/login"/>
android:layout_height="120dip"
android:text="@string/inputpassword"/>
android:id="@+id/et_protected_password"
android:id="@+id/bt_protected_login_yes"
android:id="@+id/bt_protected_login_no"
好啦,今天的代碼就到這裡啦,代碼有點多,有什麼不明白的,歡迎留言,有什麼要指導的,也歡迎留言!!!
kb, 下載下傳次數: 173)