牛骨文教育服务平台(让学习变的简单)

修改主界面的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. 第一次进入时弹出对话框,让用户设置密码
  2. 设置完毕再次进入时弹出对话框,输入密码才能进入

实现自定义对话框

  • 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;
            }
        }
    }

}

最终效果: