手机安全卫士06-手机防盗之自定义对话框
最后更新于:2022-04-01 16:16:26
### 修改主界面的titleBar
可以在系统的AndroidManifest.xml文件中修改相应的配置来改变主界面的theme(设置为无titleBar样式)
### 当前主界面的样式为:
![](image/d41d8cd98f00b204e9800998ecf8427e.png)
~~~
<activity android:name="com.liuhao.mobilesafe.ui.MainActivity"
android:theme="@android:style/Theme.NoTitleBar"
android:label="@string/main_screen">
</activity>
~~~
### 设置后样式为:
![](image/d41d8cd98f00b204e9800998ecf8427e.png)
### 添加自定义的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>
~~~
### 添加之后效果:
![](image/d41d8cd98f00b204e9800998ecf8427e.png)
### 从主界面点击激活图切换到活手机防盗界面
~~~
@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;
}
}
}
}
~~~
### 最终效果:
![](image/d41d8cd98f00b204e9800998ecf8427e.png)