### 修改主界面的titleBar
可以在系統的AndroidManifest.xml文件中修改相應的配置來改變主界面的theme(設置為無titleBar樣式)
### 當前主界面的樣式為:

~~~
<activity android:name="com.liuhao.mobilesafe.ui.MainActivity"
android:theme="@android:style/Theme.NoTitleBar"
android:label="@string/main_screen">
</activity>
~~~
### 設置后樣式為:

### 添加自定義的title,直接在主界面布局的最上方添加一個,其中添加相應的文字,如下:
~~~
<LinearLayout
android:layout_width="match_parent"
android:layout_height="40dip"
android:background="@drawable/title_background"
android:gravity="center_horizontal|center_vertical"
android:orientation="vertical"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/textcolor"
android:textSize="22sp"
android:text="山寨手機衛士"
/>
</LinearLayout>
~~~
### 其中又添加了一個title_background的背景:
~~~
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle"
>
<!-- 邊框 -->
<stroke
android:width="0.5dip"
android:color="#ff505050"
/>
<!-- 指定邊角 -->
<corners
android:radius="2dip"
/>
<!-- 漸變色 -->
<gradient
android:startColor="#ff505050"
android:centerColor="#ff383030"
android:endColor="#ff282828"/>
</shape>
~~~
### 添加之后效果:

### 從主界面點擊激活圖切換到活手機防盜界面
~~~
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
Log.i(TAG, "點擊的位置" + position);
switch(position){
case 0 :
Log.i(TAG, "進入手機防盜");
Intent lostIntent = new Intent(MainActivity.this, LostProtectedActivity.class);
startActivity(lostIntent);
break;
}
}
~~~
### 圖標隱藏后,用戶可以通過在撥號界面撥打某個號碼進入手機防盜界面(知識點:broadcast)
### 要獲取系統發送的廣播
-
CallPhoneReceiver:廣播接收者中,接收后進行相應的處理
-
配置系統receiver AndroidManifest.xml:
~~~
<receiver android:name="com.liuhao.mobilesafe.receiver.CallPhoneReceiver" >
<intent-filter android:priority="1000">
<action android:name="android.intent.action.NEW_OUTGOING_CALL"/>
</intent-filter>
</receiver>
~~~
- 配置權限:android.permission.PROCESS_OUTGOING_CALLS,重新設置外撥電話的路徑
~~~
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>
~~~
### 異常處理:
未能激活目標Activity,程序異常終止。
> Unable to start receiver com.liuhao.mobilesafe.receiver.CallPhoneReceiver: android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?
在一個Activity棧外調用startActivity()操作,必須為Intent顯示的指定FLAG_ACTIVITY_NEW_TASK標志。
分析:我們是在一個廣播接收者中激活一個Activity,Activity是運行在任務棧中的,而廣播接收者則不在任務棧中。因此,若在一個廣播接收者或者一個service中激活一個Activity必須指定FLAG_ACTIVITY_NEW_TASK標志,指定要激活的Activity在自己的任務棧中運行。
~~~
<pre name="code" class="java">lostIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
~~~
- CallPhoneReceiver.java 完整的
~~~
package com.liuhao.mobilesafe.receiver;
import com.liuhao.mobilesafe.ui.LostProtectedActivity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class CallPhoneReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String number = getResultData();
if("20122012".equals(number)){
Intent lostIntent = new Intent(context, LostProtectedActivity.class);
// 指定要激活的Activity在自己的任務棧中運行
lostIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(lostIntent);
// 終止這個撥號
// 不能通過abortBroadcast()終止
setResultData(null);
}
}
}
~~~
### 手機防盜界面
1. 第一次進入時彈出對話框,讓用戶設置密碼
1. 設置完畢再次進入時彈出對話框,輸入密碼才能進入
### 實現自定義對話框
- style.xml 其中實現了一個自定義對話框框架
~~~
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="MyDialog" parent="@android:style/Theme.Dialog">
<item name="android:windowBackground">@drawable/title_background</item>
<item name="android:windowNoTitle">true</item>
</style>
</resources>
~~~
- first_entry_dialog.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="280dip"
android:gravity="center_horizontal"
android:orientation="vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="設置密碼"
android:textSize="24sp" />
<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="設置手機防盜的密碼"
android:textColor="#ff000000" />
<EditText
android:id="@+id/et_first_entry_pwd"
android:layout_width="300dip"
android:layout_height="wrap_content" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="再次輸入密碼"
android:textColor="#ff000000" />
<EditText
android:id="@+id/et_first_entry_pwd_confirm"
android:layout_width="300dip"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
android:layout_width="300dip"
android:layout_height="50dip"
android:gravity="center"
android:orientation="horizontal" >
<Button
android:layout_width="140dip"
android:layout_height="40dip"
android:background="@drawable/button_background"
android:text="確定"
android:textColor="#ffffffff" />
<Button
android:layout_width="140dip"
android:layout_height="40dip"
android:layout_marginLeft="3dip"
android:background="@drawable/button_background"
android:text="取消" />
</LinearLayout>
</LinearLayout>
~~~
- button_background.xml 按鈕的背景
~~~
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<!-- 邊框 -->
<stroke
android:width="0.5dip"
android:color="#ff107048" />
<!-- 指定邊角 -->
<corners android:radius="2dip" />
<!-- 漸變色 -->
<gradient
android:centerColor="#ff107048"
android:endColor="#ff085830"
android:startColor="#ff109860" />
</shape>
~~~
- LostProtectedActivity.java
~~~
package com.liuhao.mobilesafe.ui;
import com.liuhao.mobilesafe.R;
import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.util.Log;
public class LostProtectedActivity extends Activity {
private static final String TAG = "LostProtectedActivity";
private SharedPreferences sp;
private Dialog dialog;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
sp = getSharedPreferences("config", Context.MODE_PRIVATE);
// 判讀用戶是否已經設置了密碼
if (isPwdSetup()) {
Log.i(TAG, "設置了密碼,彈出輸入密碼的對話框");
} else {
Log.i(TAG, "未設置密碼,彈出設置密碼對話框");
showFirstEntryDialog();
}
}
/**
* 第一次進入程序時彈出的設置密碼的對話框 自定義對話框樣式
*/
private void showFirstEntryDialog() {
dialog = new Dialog(this, R.style.MyDialog);
dialog.setContentView(R.layout.first_entry_dialog);// 設置要顯示的內容
dialog.show();
}
/**
* 檢查sharedpreference中是否有密碼的設置
*
* @return
*/
private boolean isPwdSetup() {
String password = sp.getString("password", null);
if (password == null) {
return false;
} else {
if ("".equals(password)) {
return false;
} else {
return true;
}
}
}
}
~~~
### 最終效果:

- 前言
- Appcompat_V7問題
- This Android SDK requires Android Developer Toolkit version 23.0.0 or above
- 創建Android項目不自動生成Activity,layout目錄為空
- 新建android項目gen目錄下未生成R文件
- 手機安全衛士02:splash界面ui
- 知識點:Android控件系列之Toast
- 手機安全衛士03:獲取更新的服務器配置,顯示更新對話框
- 異常處理:android.os.NetworkOnMainThreadException--多線程問題
- 知識點:Android控件系列之對話框AlertDialog.Builder
- 手機安全衛士04_01:界面(Activity)之間的切換,Activity和任務棧
- 知識點:Android控件系列之ProgressDialog與ProgressBar
- 手機安全衛士04_02:從服務器下載并安裝新版本安裝包
- 知識點:Intent
- 知識點:Adapter適配器
- 手機安全衛士05_1:程序主界面
- 手機安全衛士05_2:程序主界面,為每個條目添加事件
- 知識點:動態設置布局LayoutInflater
- 知識點:SharedPreferences
- 手機安全衛士06-手機防盜之自定義對話框
- 手機安全衛士07-手機防盜之進入限制
- 手機安全衛士08-一些布局和顯示的細節:State List
- 手機安全衛士09-手機防盜界面設置向導1
- 手機安全衛士10-設置向導之綁定SIM卡