admin管理员组

文章数量:1531258

一、设置向导页面手势滑动处理

Android为手势检测提供了一个GestureDetector类,GestureDetector实例代表了一个手势检测器,创建GestureDetector时需要传入一个GestureDetector.OnGestureListener实例,GestureDetector.OnGestureListener就是一个监听器、负责对用户的手势行为提供响应。 GestureDetector.OnGestureListener里包含的事件处理方法如下。
  • boolean onDown(MotionEvent   e):当触碰事件按下时触发该方法。
  • boolean onFling(MotionEvent e1,MotionEvent e2,float velocityX,float velocityY):当用户在触摸屏上“拖过”时触发该方法。其中velocityX,velocityY代表“拖过”动作在横向、纵向上的速度。
  • abstract void onLongPress(MotionEvent e):当用户在屏幕上长按时触发该方法。
  • boolean onScroll(MotionEvent e1,MotionEvent e2,float distanceX,floatdistanceY):当用户在屏幕上“滚动”时触发该方法。
  • void onShowPress(MotionEvent e):当用户在触摸屏上按下,而且还未移动和松开时触发该方法。
  • boolean onSingleTagUp(MotionEvent e):用户在触摸屏上的轻击事件将会触发该方法。
使用Android的手势检测只需两个步骤:
  1. 创建一个GestureDetector对象。创建该对象时必须实现一个GestureDetector.OnGestureListener监听器实例。
  2. 为应用程序的Activity(偶尔也可为特定的组件)的TouchEvent事件绑定监听器,在事件处理中制定把Activity(或 特定组件)上的TouchEvent事件就会交给 GestureDetector处理。
画图分析滑动手势的原理:
现在只在第二个引导页面实现手势滑动。 Setup2Activity.java
package com.xbmu.mobilesafe;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;

public class Setup2Activity extends Activity {
	private GestureDetector detector;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_setup2);
		detector = new GestureDetector(this,
				new GestureDetector.SimpleOnGestureListener() {
					/**
					 * 监听手势滑动事件 
					 * MotionEvent e1:表示滑动的起点
					 * MotionEvent e2:表示滑动终点
					 * float velocityX:表示水平速度
					 * float velocityY:表示垂直速度
					 */
					@Override
					public boolean onFling(MotionEvent e1, MotionEvent e2,
							float velocityX, float velocityY) {
						// 从左向右滑动,上一步
						if ((e2.getRawX() - e1.getRawX()) > 100) {
							showPreviousPage();
						}
						// 从右向左滑动,下一步
						if ((e1.getRawX() - e2.getRawX()) > 100) {
							showNextPage();
						}
						return super.onFling(e1, e2, velocityX, velocityY);
					}

				});
	}

	// 显示下一个页面
	protected void showNextPage() {
		startActivity(new Intent(this, Setup3Activity.class));
		finish();

		// 两个界面切换的动画
		overridePendingTransition(R.anim.next_enter_anim, R.anim.next_exit_anim);// 进入动画
																					// 退出动画
	}

	// 显示上一个页面
	protected void showPreviousPage() {
		startActivity(new Intent(this, Setup1Activity.class));
		finish();

		// 两个界面切换的动画
		overridePendingTransition(R.anim.previous_enter_anim,
				R.anim.previous_exit_anim);// 进入动画 退出动画
	}

	/** 点击上一步按钮 */
	public void previous(View view) {
		showPreviousPage();
	}

	/** 点击下一步按钮 */
	public void next(View view) {
		showNextPage();
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		detector.onTouchEvent(event);// 委托手势识别器处理触摸事件
		return super.onTouchEvent(event);
	}
}
运行效果:

二、把公共功能抽取到父类(BaseSetupActivity.java)

因为每个防盗设置引导页界面都需要手势滑动,如果每个页面都写手势滑动代码,这样的话,代码的复用性特别差,而且每个页面的代码显得特别臃肿。 因此我们写一个设置应到页面的基类BaseSetupActivity.java BaseSetupActivity.java
package com.xbmu.mobilesafe;

import android.app.Activity;
import android.os.Bundle;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;

/**
 * 设置引导页的基类,不需要在清单文件中注册,因为不需要再界面显示。
 * 
 * @author Administrator
 * 
 */
public abstract class BaseSetupActivity extends Activity {
	public GestureDetector detector;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		detector = new GestureDetector(this,
				new GestureDetector.SimpleOnGestureListener() {
					/**
					 * 监听手势滑动事件 MotionEvent e1:表示滑动的起点 MotionEvent e2:表示滑动终点
					 * float velocityX:表示水平速度 float velocityY:表示垂直速度
					 */
					@Override
					public boolean onFling(MotionEvent e1, MotionEvent e2,
							float velocityX, float velocityY) {
						// 从左向右滑动,上一步
						if ((e2.getRawX() - e1.getRawX()) > 100) {
							showPreviousPage();
						}
						// 从右向左滑动,下一步
						if ((e1.getRawX() - e2.getRawX()) > 100) {
							showNextPage();
						}
						return super.onFling(e1, e2, velocityX, velocityY);
					}

				});
	}

	// 显示下一个页面
	protected abstract void showNextPage();

	// 显示上一个页面
	protected abstract void showPreviousPage();

	/** 点击上一步按钮 */
	public void previous(View view) {
		showPreviousPage();
	}

	/** 点击下一步按钮 */
	public void next(View view) {
		showNextPage();
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		detector.onTouchEvent(event);// 委托手势识别器处理触摸事件
		return super.onTouchEvent(event);
	}
}
然后将手势滑动的功能推广给各个引导界面。 Setup1Activity.java
package com.xbmu.mobilesafe;

import android.content.Intent;
import android.os.Bundle;

public class Setup1Activity extends BaseSetupActivity {
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_setup1);
	}
	@Override
	protected void showNextPage() {
		startActivity(new Intent(this, Setup2Activity.class));
		finish();
		
		overridePendingTransition(R.anim.next_enter_anim, R.anim.next_exit_anim);//进入动画   退出动画
		
	}
	@Override
	protected void showPreviousPage() {
		
		
	}
}
Setup2Activity.java
package com.xbmu.mobilesafe;

import android.content.Intent;
import android.os.Bundle;

public class Setup2Activity extends BaseSetupActivity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_setup2);
	}
	@Override
	protected void showNextPage() {
		startActivity(new Intent(this, Setup3Activity.class));
		finish();

		// 两个界面切换的动画
		overridePendingTransition(R.anim.next_enter_anim, R.anim.next_exit_anim);// 进入动画 退出动画

	}

	@Override
	protected void showPreviousPage() {
		startActivity(new Intent(this, Setup1Activity.class));
		finish();

		// 两个界面切换的动画
		overridePendingTransition(R.anim.previous_enter_anim,
				R.anim.previous_exit_anim);// 进入动画 退出动画

	}

}
Setup3Activity.java
package com.xbmu.mobilesafe;

import android.content.Intent;
import android.os.Bundle;

public class Setup3Activity extends BaseSetupActivity {
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_setup3);
	}
	@Override
	protected void showNextPage() {
		startActivity(new Intent(this, Setup4Activity.class));
		finish();
		overridePendingTransition(R.anim.next_enter_anim, R.anim.next_exit_anim);//进入动画   退出动画
		
	}
	@Override
	protected void showPreviousPage() {
		startActivity(new Intent(this, Setup2Activity.class));
		finish();
		overridePendingTransition(R.anim.previous_enter_anim, R.anim.previous_exit_anim);//进入动画   退出动画
		
	}
}
Setup4Activity.java
package com.xbmu.mobilesafe;

import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;

public class Setup4Activity extends BaseSetupActivity {
	private SharedPreferences sPre;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_setup4);
		sPre = getSharedPreferences("config", MODE_PRIVATE);
	}
	
	@Override
	protected void showNextPage() {
		startActivity(new Intent(this, LostFindActivity.class));
		finish();
		sPre.edit().putBoolean("configed", true)mit();
		overridePendingTransition(R.anim.next_enter_anim, R.anim.next_exit_anim);//进入动画   退出动画
		
	}
	@Override
	protected void showPreviousPage() {
		startActivity(new Intent(this, Setup3Activity.class));
		finish();
		overridePendingTransition(R.anim.previous_enter_anim, R.anim.previous_exit_anim);//进入动画   退出动画
		
	}
}
运行效果:
处理手势滑动的细节: 如果仔细研究,你会发现斜滑也会切换页面,滑动速度很慢的话也会切换页面,这种体验效果,一般不是我们要求的。只有左右滑动才会切换页面。 ToastUtil.java
package com.xbmu.mobilesafe.tools;

import android.content.Context;
import android.widget.Toast;

public class ToastUtil {

	public static void showToast(Context context,String text) {
		Toast.makeText(context, text, 0).show();
		
	}

}
BaseSetupActivity.java
package com.xbmu.mobilesafe;

import android.app.Activity;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;

import com.xbmu.mobilesafe.tools.ToastUtil;

/**
 * 设置引导页的基类,不需要在清单文件中注册,因为不需要再界面显示。
 * 
 * @author Administrator
 * 
 */
public abstract class BaseSetupActivity extends Activity {
	public GestureDetector detector;
	public SharedPreferences sPre;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		
		sPre = getSharedPreferences("config", MODE_PRIVATE);
		
		detector = new GestureDetector(this,
				new GestureDetector.SimpleOnGestureListener() {
					/**
					 * 监听手势滑动事件 MotionEvent e1:表示滑动的起点 MotionEvent e2:表示滑动终点
					 * float velocityX:表示水平速度 float velocityY:表示垂直速度
					 */
					@Override
					public boolean onFling(MotionEvent e1, MotionEvent e2,
							float velocityX, float velocityY) {
						//禁止斜滑 ,判断纵向滑动幅度是否过大,过大的话不允许切换界面
						if(Math.abs(e2.getRawY()-e1.getRawY())>100){
							ToastUtil.showToast(BaseSetupActivity.this, "亲,不要斜滑!!!");
							return true;
						}
						//禁止滑动慢,判断滑动是否过慢
						if(Math.abs(velocityX)<100){
							ToastUtil.showToast(BaseSetupActivity.this, "亲,你滑的太慢了!!!");
							return true;
						}
						// 从左向右滑动,上一步
						if ((e2.getRawX() - e1.getRawX()) > 100) {
							showPreviousPage();
							return true;
						}
						// 从右向左滑动,下一步
						if ((e1.getRawX() - e2.getRawX()) > 100) {
							showNextPage();
							return true;
						}
						return super.onFling(e1, e2, velocityX, velocityY);
					}

				});
	}

	//...
}
运行效果:

三、绑定sim卡

电话管理器(TelephonyManager) TelephonyManager是一个管理手机通话状态,电话网络信息的服务类,该类提供了大量的getXXX()方法来获取电话网络的相关信息。
在程序中获取TelephonyManager十分简单,只要调用如下代码即可:
TelephonyManager telephonyManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
通过TelephonyManager提供的系列方法即可获取手机网络,SIM卡的相关信息。

Setup2Activity.java
package com.xbmu.mobilesafe;

import android.content.Intent;
import android.os.Bundle;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.view.View;
import android.view.View.OnClickListener;

import com.xbmu.mobilesafe.tools.ToastUtil;
import com.xbmu.mobilesafe.view.SettingItemView;

public class Setup2Activity extends BaseSetupActivity {

	private SettingItemView mSiv;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_setup2);
		mSiv = (SettingItemView) findViewById(R.id.siv);
		
		String simSerialNumber = sPre.getString("sim", null);
		if(TextUtils.isEmpty(simSerialNumber)){
			//没有sim序列号
			mSiv.setChecked(false);
		}else{
			//有sim序列号
			mSiv.setChecked(true);
		}
		mSiv.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				if(mSiv.isChecked()){
					//已经勾选了
					mSiv.setChecked(false);
					sPre.edit().remove("sim")mit();//解除已绑定的sim卡
				}else{
					mSiv.setChecked(true);
					//保存sim卡信息
					TelephonyManager telephonyManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
					String simSerialNumber = telephonyManager.getSimSerialNumber();//获取sim卡序列号
					sPre.edit().putString("sim", simSerialNumber)mit();//将sim卡信息保存在SharedPreferences中
				}
				
			}
		});
	}
	@Override
	protected void showNextPage() {
		String sim = sPre.getString("sim", null);
		if(!TextUtils.isEmpty(sim)){
			//sim卡序列号不为空
			startActivity(new Intent(this, Setup3Activity.class));
			finish();

			// 两个界面切换的动画
			overridePendingTransition(R.anim.next_enter_anim, R.anim.next_exit_anim);// 进入动画   退出动画
		}else{
			ToastUtil.showToast(this, "亲,您没有绑定sim卡");
		}

	}

	@Override
	protected void showPreviousPage() {
		startActivity(new Intent(this, Setup1Activity.class));
		finish();

		// 两个界面切换的动画
		overridePendingTransition(R.anim.previous_enter_anim,
				R.anim.previous_exit_anim);// 进入动画 退出动画

	}

}
在清单文件中加入读取手机状态的权限:
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
运行效果:

四、监听手机启动,检查sim卡变化

BootCompleteReceiver.java
package com.xbmu.mobilesafe.receiver;
/**
 * 监听手机启动的广播
 */
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.telephony.TelephonyManager;
import android.text.TextUtils;

public class BootCompleteReceiver extends BroadcastReceiver {

	private SharedPreferences sPre;

	@Override
	public void onReceive(Context context, Intent intent) {
		//从SharedPreferences中获取已经保存sim卡序列号
		sPre = context.getSharedPreferences("config", Context.MODE_PRIVATE);
		String saveSim = sPre.getString("sim", null);
		
		if(!TextUtils.isEmpty(saveSim)){
			//获取当前sim卡序列号
			TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
			String currentSim = telephonyManager.getSimSerialNumber();//拿到当前手机的sim卡序列号
			if(currentSim.equals(saveSim)){
				System.out.println("手机安全");
			}else{
				System.out.println("发送报警信息");
			}
		}
	}

}
在清单文件中加入权限:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
在清单文件中注册广播接受者:
<receiver android:name="com.xbmu.mobilesafe.receiver.BootCompleteReceiver">
      <intent-filter>
           <action android:name="android.intent.action.BOOT_COMPLETED"/>
      </intent-filter>
</receiver>

五、读取联系人&手机防盗页数据展示

activity_setup3.xml
<EditText
        android:id="@+id/et_phone"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />


    <Button
        android:id="@+id/btn_select_number"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/linked_button"
        android:text="选择联系人" />
Setup3Activity.java
package com.xbmu.mobilesafe;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;

import com.xbmu.mobilesafe.tools.ToastUtil;

public class Setup3Activity extends BaseSetupActivity {
	private Button btnSelectNum;
	private EditText etPhone;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_setup3);
		btnSelectNum = (Button) findViewById(R.id.btn_select_number);
		etPhone = (EditText) findViewById(R.id.et_phone);
		String safePhone = sPre.getString("safe_phone", "");
		if(!TextUtils.isEmpty(safePhone)){
			etPhone.setText(safePhone);
		}
		//给选择安全号码的按钮设置监听事件
		btnSelectNum.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				Intent intent = new Intent(Setup3Activity.this, SelectSafeNumActivity.class);
				startActivityForResult(intent, 0);
				
			}
		});
	}
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		
		if (resultCode == Activity.RESULT_OK) {
			String phone = data.getStringExtra("phone");
			phone = phone.replaceAll("-", "").replaceAll(" ", "");//将-和空格替换掉空字符串
			etPhone.setText(phone);//把电话号码设置给输入框
			
		}
	}
	@Override
	protected void showNextPage() {
		String safePhone = etPhone.getText().toString().trim();
		if(!TextUtils.isEmpty(safePhone)){
			//将获取的电话号码保存在
			sPre.edit().putString("safe_phone", safePhone)mit();
			startActivity(new Intent(this, Setup4Activity.class));
			finish();
			overridePendingTransition(R.anim.next_enter_anim, R.anim.next_exit_anim);//进入动画   退出动画			
		}else{
			ToastUtil.showToast(this, "没有设置安全号码,请先设置!!!");
		}
		
	}
	@Override
	protected void showPreviousPage() {
		startActivity(new Intent(this, Setup2Activity.class));
		finish();
		overridePendingTransition(R.anim.previous_enter_anim, R.anim.previous_exit_anim);//进入动画   退出动画
		
	}
}
activity_select_safenum.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    <TextView style="@style/TitleStyle"
	    android:text="选择联系人"/>
    <ListView android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/lv_list"></ListView>

</LinearLayout>
contact_list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="10dp" >
	
    <TextView
        android:id="@+id/tv_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="姓名"
        android:textColor="#00f"
        android:textSize="18sp" />

    <TextView
        android:id="@+id/tv_phone"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="电话"
        android:textColor="#0f0"
        android:textSize="18sp" />

</LinearLayout>
SelectSafeNumActivity.java
package com.xbmu.mobilesafe;

import java.util.ArrayList;
import java.util.HashMap;

import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import android.widget.SimpleAdapter;

public class SelectSafeNumActivity extends Activity {

	private ListView lvList;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_select_safenum);
		//获取ListView控件
		lvList = (ListView) findViewById(R.id.lv_list);
		//填充的数据
		final ArrayList<HashMap<String, String>> readContact = readContact();
		//设置适配器
		lvList.setAdapter(new SimpleAdapter(this, readContact,
				R.layout.contact_list_item, new String[] { "name", "phone" },
				new int[] { R.id.tv_name, R.id.tv_phone }));
		//设置ListView中每个item的监听事件
		lvList.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> parent, View view,
					int position, long id) {
				String phone = readContact.get(position).get("phone");//读取当前ite的电话号码
				Intent intent = new Intent();
				intent.putExtra("phone", phone);
				setResult(Activity.RESULT_OK,intent);//将数据放在intent中返回给上一个页面
				finish();
			}
		});
	}
	/**
	 * 读取联系人
	 * @return
	 */
	public ArrayList<HashMap<String, String>> readContact() {
		/**
		 * 思路:
		 * 首先,从raw_contacts中读取联系人的id("contact_id")
		 * 其次,根据contact_id从data表中查询出相应的电话号码和联系人名称 
		 * 然后,根据mimetype来区分哪个是联系人,哪个是电话号码
		 */
		Uri rawContactsUri = Uri
				.parse("content://com.android.contacts/raw_contacts");
		Uri dataUri = Uri.parse("content://com.android.contacts/data");

		ArrayList<HashMap<String, String>> list = new ArrayList<HashMap<String, String>>();

		// 从raw_contacts中读取联系人的id("contact_id")
		Cursor rawContactsCursor = getContentResolver().query(rawContactsUri,
				new String[] { "contact_id" }, null, null, null);

		if (rawContactsCursor != null) {
			while (rawContactsCursor.moveToNext()) {
				String contactId = rawContactsCursor.getString(0);
				// System.out.println("contactId:" + contactId);

				// 根据contact_id从data表中查询出相应的电话号码和联系人名称, 实际上查询的是视图view_data
				Cursor dataCursor = getContentResolver().query(dataUri,
						new String[] { "data1", "mimetype" }, "contact_id=?",
						new String[] { contactId }, null);
				if (dataCursor != null) {
					HashMap<String, String> contactMap = new HashMap<String, String>();
					while (dataCursor.moveToNext()) {
						String data1 = dataCursor.getString(0);
						String mimetype = dataCursor.getString(1);
						// System.out.println(contactId + ";" + data1 + ";"
						// + mimetype);
						if ("vnd.android.cursor.item/phone_v2".equals(mimetype)) {
							contactMap.put("phone", data1);
						} else if ("vnd.android.cursor.item/name"
								.equals(mimetype)) {
							contactMap.put("name", data1);
						}
					}
					list.add(contactMap);
					dataCursor.close();
				}
			}
			rawContactsCursor.close();
		}
		return list;
	}
}
在清单文件中添加读取联系人的权限:
<uses-permission android:name="android.permission.READ_CONTACTS"/>
运行效果:

六、开启防盗保护以及手机防盗页数据展示

activity_setup4.xml
<CheckBox android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="5dp"
        android:layout_marginTop="5dp"
        android:textSize="18sp"
        android:id="@+id/cb_project"
        android:text="你没有开启防盗保护"/>
Setup4Activity.java
package com.xbmu.mobilesafe;

import android.content.Intent;
import android.os.Bundle;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;

public class Setup4Activity extends BaseSetupActivity {
	private CheckBox cbProject;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_setup4);
		cbProject = (CheckBox) findViewById(R.id.cb_project);
		boolean project = sPre.getBoolean("project", false);
		if(project){
			cbProject.setText("你已经开启防盗保护");
			cbProject.setChecked(true);
		}else{
			cbProject.setText("你没有开启防盗保护");
			cbProject.setChecked(false);
		}
		//当CheckBox发生变化时,回调此方法
		cbProject.setOnCheckedChangeListener(new OnCheckedChangeListener() {
			
			@Override
			public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
				if(isChecked){
					//选中了,开启防盗保护
					cbProject.setText("你已经开启防盗保护");
					cbProject.setChecked(true);
					//将是否开启保护的信息保存到SharedPreferences
					sPre.edit().putBoolean("project", true)mit();
				}else{
					//没有选中,没有开启防盗保护
					cbProject.setText("你没有开启防盗保护");
					cbProject.setChecked(false);
					//将是否开启保护的信息保存到SharedPreferences
					sPre.edit().putBoolean("project", false)mit();
				}
				
			}
		});
		
	}
	
	@Override
	protected void showNextPage() {
		startActivity(new Intent(this, LostFindActivity.class));
		finish();
		sPre.edit().putBoolean("configed", true)mit();
		overridePendingTransition(R.anim.next_enter_anim, R.anim.next_exit_anim);//进入动画   退出动画
		
	}
	@Override
	protected void showPreviousPage() {
		startActivity(new Intent(this, Setup3Activity.class));
		finish();
		overridePendingTransition(R.anim.previous_enter_anim, R.anim.previous_exit_anim);//进入动画   退出动画
		
	}
}
activity_lost_find.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView
        style="@style/TitleStyle"
        android:text="手机防盗" />

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <TextView
            
            style="@style/ContentStyle"
            android:text="安全号码" />

        <TextView
           android:id="@+id/tv_safe_phone"
           style="@style/ContentStyle"
           android:layout_alignParentRight="true"
           android:layout_marginRight="5dp"
           android:text="10086" />
    </RelativeLayout>

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:layout_marginTop="5dp"
        android:background="@drawable/listview_divider" />

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <TextView
            style="@style/ContentStyle"
            android:text="防盗保护是否开启" />

        <ImageView
            android:id="@+id/iv_project_lock"
            android:layout_width="20dp"
            android:layout_height="20dp"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:layout_marginRight="5dp" />
    </RelativeLayout>

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:layout_marginTop="5dp"
        android:background="@drawable/listview_divider" />

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <TextView
            style="@style/ContentStyle"
            android:layout_width="match_parent"
            android:onClick="reEnter"
            android:clickable="true"
            android:layout_marginRight="5dp"
            android:background="@drawable/shape_selector"
            android:text="重新进入设置向导" />
    </RelativeLayout>

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:layout_marginTop="5dp"
        android:background="@drawable/listview_divider" />

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="5dp"
        android:background="#6000"
        android:text="功能简介"
        android:textColor="#000"
        android:textSize="20dp" />

    <TextView
        style="@style/ContentStyle"
        android:drawableLeft="@android:drawable/star_big_on"
        android:text="GPS追踪:#*location*#" />

    <TextView
        style="@style/ContentStyle"
        android:drawableLeft="@android:drawable/star_big_on"
        android:text="播放报警音乐:#*alarm*#" />

    <TextView
        style="@style/ContentStyle"
        android:drawableLeft="@android:drawable/star_big_on"
        android:text="远程删除数据:#*wipedata*#" />

    <TextView
        style="@style/ContentStyle"
        android:drawableLeft="@android:drawable/star_big_on"
        android:text="远程锁屏:#*lockscreen*#" />

</LinearLayout>
LostFindActivity.java
package com.xbmu.mobilesafe;

import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;

public class LostFindActivity extends Activity {
	private SharedPreferences sPre;
	private ImageView ivProjectLock;
	private TextView tvSafePhone;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		
		sPre = getSharedPreferences("config", MODE_PRIVATE);
		boolean configed  = sPre.getBoolean("configed", false);
		if(configed){
			//设置过,进入手机防盗界面
			setContentView(R.layout.activity_lost_find);
			tvSafePhone = (TextView) findViewById(R.id.tv_safe_phone);
			ivProjectLock = (ImageView) findViewById(R.id.iv_project_lock);
			String safePhone = sPre.getString("safe_phone", "");
			tvSafePhone.setText(safePhone);
			boolean project = sPre.getBoolean("project", false);
			if(project){
				ivProjectLock.setImageResource(R.drawable.lock);
			}else{
				ivProjectLock.setImageResource(R.drawable.unlock);
			}
		}else{
			//没有设置过,进入设置向导
			startActivity(new Intent(this, Setup1Activity.class));
			finish();
		}
	}
	public void reEnter(View view){
		startActivity(new Intent(this, Setup1Activity.class));
		finish();
	}
}
运行效果:

七、发送sim卡变更信息给安全号码 &完成手机防盗指令功能

BootCompleteReceiver.java
package com.xbmu.mobilesafe.receiver;
/**
 * 监听手机启动的广播
 */
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.telephony.SmsManager;
import android.telephony.TelephonyManager;
import android.text.TextUtils;

public class BootCompleteReceiver extends BroadcastReceiver {

	private SharedPreferences sPre;

	@Override
	public void onReceive(Context context, Intent intent) {
		//从SharedPreferences中获取已经保存sim卡序列号
		sPre = context.getSharedPreferences("config", Context.MODE_PRIVATE);
		String saveSim = sPre.getString("sim", null);
		
		if(!TextUtils.isEmpty(saveSim)){
			//获取当前sim卡序列号
			TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
			String currentSim = telephonyManager.getSimSerialNumber();//拿到当前手机的sim卡序列号
			if(currentSim.equals(saveSim)){
				System.out.println("手机安全");
			}else{
				//读取安全号码
				String safePhone = sPre.getString("safe_phone", "");
				
				//发送报警短信
				SmsManager smsManager = SmsManager.getDefault();
				smsManager.sendTextMessage(safePhone, null, "sim card changed!!!", null, null);
			}
		}
	}

}
在清单文件中加入发送短信的权限:
<uses-permission android:name="android.permission.SEND_SMS"/>
运行方法:将手机卫士运行在5554模拟器上,并在手机防盗页面中进行设置,设置绑定sim卡,设置安全号码5556,开启防盗保护。然后开启5556模拟器, 将BootCompleteReceiver.java类中获取当前sim卡序列号语句,String currentSim = telephonyManager.getSimSerialNumber()+"111";//拿到当前手机的sim卡序列号,后面加上字符串“111”,是为了模拟sim卡变更。 关闭5554模拟器,重启开启5554模拟器,看5556模拟器中有没有接收到sim卡变更信息。

7.1:播放报警音乐

SmsReciver.java
package com.xbmu.mobilesafe.receiver;

import com.xbmu.mobilesafe.R;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.media.MediaPlayer;
import android.telephony.SmsMessage;
/**
 * 拦截短信
 * @author Administrator
 *
 */
public class SmsReciver extends BroadcastReceiver {

	private String originatingAddress;
	private String messageBody;

	@Override
	public void onReceive(Context context, Intent intent) {
		//接收短信
		Object[] objects = (Object[]) intent.getExtras().get("pdus");
		for (Object object : objects) {
			SmsMessage message = SmsMessage.createFromPdu((byte[])object);
			originatingAddress = message.getOriginatingAddress();//短信来源号码
			messageBody = message.getMessageBody();//短信内容
			System.out.println(originatingAddress+":"+messageBody);
		}
		//拦截短信(短信内容为这些的短信 拦截下来)
		
		//播放报警音乐
		if("#*alarm*#".equals(messageBody)){
			//播放报警音乐,即使手机调为静音,也能播放音乐,因为使用的是媒体声音的通道,和铃声无关
			MediaPlayer player = MediaPlayer.create(context, R.raw.ylzs);
			player.setVolume(1f, 1f);//设置左右声道
			player.setLooping(true);//设置循环播放
			player.start();//开启播放
			abortBroadcast();//中断短信的传递,从而系统短信app就收不到内容了。
		}
	}

}
音频文件一般存放在res/raw文件夹下:
在清单文件中声明广播接受者组件
<!--android:priority:设置优先级,谷歌要求开发人员最高优先级为100,但是这里我们也可以设置为Integer.MAX_VALUE  -->
        <receiver android:name="com.xbmu.mobilesafe.receiver.SmsReciver">
            <intent-filter android:priority="2147483647">
                <action android:name="android.provider.Telephony.SMS_RECEIVED"/>
            </intent-filter>
        </receiver>
在清单文件中声明接收短信的权限
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
运行方法:在5556模拟器上发送短信给5554模拟器,短信内容为:#*alarm*#

7.2、GPS追踪指令实现

LocationService.java
package com.xbmu.mobilesafe.service;

import android.app.Service;
import android.content.Intent;
import android.content.SharedPreferences;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
/**
 * 获取经纬度坐标的service
 * @author Administrator
 *
 */
public class LocationService extends Service {
	private LocationManager lm;
	private MyLocationListener listener;
	private SharedPreferences sPre;

	@Override
	public IBinder onBind(Intent intent) {
		return null;
	}

	@Override
	public void onCreate() {
		super.onCreate();
		sPre = getSharedPreferences("config", MODE_PRIVATE);

		lm = (LocationManager) getSystemService(LOCATION_SERVICE);
		// List<String> allProviders = lm.getAllProviders();//获取所有位置提供者
		// System.out.println(allProviders);

		Criteria criteria = new Criteria();
		criteria.setCostAllowed(true);// 是否允许付费,比如使用3g网络定位
		criteria.setAccuracy(Criteria.ACCURACY_FINE);
		String bestProvider = lm.getBestProvider(criteria, true);// 获取最佳位置提供者

		listener = new MyLocationListener();
		/**
		 * String provider:位置提供者 long minTime:最短更新时间 float minDistance:最短更新距离
		 * LocationListener listener:
		 */
		// lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0,
		// listener);
		lm.requestLocationUpdates(bestProvider, 0, 0, listener);
	}

	class MyLocationListener implements LocationListener {
		// 位置发生变化
		@Override
		public void onLocationChanged(Location location) {
			//将获取的经纬度保存在SharedPreferences中
			sPre.edit()
					.putString(
							"location",
							"j:" + location.getLongitude() + ";w:"
									+ location.getLatitude())mit();
			stopSelf();//停掉service
		}

		// 位置提供者状态发生变化
		@Override
		public void onStatusChanged(String provider, int status, Bundle extras) {
			System.out.println("onStatusChanged");
		}

		// 用户打开GPS
		@Override
		public void onProviderEnabled(String provider) {
			System.out.println("onProviderEnabled");

		}

		@Override
		// 用户关闭GPS
		public void onProviderDisabled(String provider) {
			System.out.println("onProviderDisabled");

		}

	}
	@Override
	public void onDestroy() {
		super.onDestroy();
		lm.removeUpdates(listener);//当activity销毁时,停止更新位置,节省电量
	}
}
在清单文件注册服务组件:
<service android:name="com.xbmu.mobilesafe.service.LocationService" />
在清单文件中加入权限:
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" />
SmsReceiver.java
@Override
	public void onReceive(Context context, Intent intent) {
		//接收短信
		Object[] objects = (Object[]) intent.getExtras().get("pdus");
		for (Object object : objects) {//短信最多140字节,超出的话,会分为多条短信发送,所以是一个数组,因为我们的短信指令很短,所以for循环只执行一次
			SmsMessage message = SmsMessage.createFromPdu((byte[])object);
			originatingAddress = message.getOriginatingAddress();//短信来源号码
			messageBody = message.getMessageBody();//短信内容
			System.out.println(originatingAddress+":"+messageBody);
			//拦截短信(短信内容为这些的短信 拦截下来)
			
			//播放报警音乐
			if("#*alarm*#".equals(messageBody)){
				//播放报警音乐,即使手机调为静音,也能播放音乐,因为使用的是媒体声音的通道,和铃声无关
				MediaPlayer player = MediaPlayer.create(context, R.raw.ylzs);
				player.setVolume(1f, 1f);//设置左右声道
				player.setLooping(true);//设置循环播放
				player.start();//开启播放
				abortBroadcast();//中断短信的传递,从而系统短信app就收不到内容了。
			}else if("#*location*#".equals(messageBody)){
				//获取经纬度坐标
				context.startService(new Intent(context, LocationService.class));//开启定位服务
				SharedPreferences sp = context.getSharedPreferences("config", Context.MODE_PRIVATE);
				String location  = sp.getString("location", "");
//				System.out.println("location:"+location);
				abortBroadcast();//中断短信的传递,从而系统短信app就收不到内容了。
			}
		}

7.3、远程清除数据 & 远程锁屏

AdminReceiver.java
package com.xbmu.mobilesafe.receiver;

import android.app.admin.DeviceAdminReceiver;

public class AdminReceiver extends DeviceAdminReceiver {

}
OpenAdminActivity.java
package com.xbmu.mobilesafe;

import com.xbmu.mobilesafe.receiver.AdminReceiver;

import android.app.Activity;

import android.app.admin.DevicePolicyManager;
import android.content.ComponentName;
import android.content.Intent;
import android.Uri;
import android.os.Bundle;
import android.view.View;

/**
 * 激活设备管理员
 */
public class OpenAdminActivity extends Activity {

	/**
	 * 设备策略管理员
	 */
	private DevicePolicyManager dpm;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		dpm = (DevicePolicyManager) getSystemService(DEVICE_POLICY_SERVICE);
		// dpm.lockNow();
		openAdmin(null);
		finish();
	}

	// 点击事件-锁屏
	public void lockscreen(View view) {
		ComponentName  mDeviceAdminSample = new ComponentName(this,AdminReceiver.class);
		if(dpm.isAdminActive(mDeviceAdminSample)){
			dpm.lockNow();//锁屏
//			dpm.resetPassword("123", 0);//加上密码
			
//			dpm.wipeData(0);//恢复出厂设置
//			//格式化sdcard
//			dpm.wipeData(DevicePolicyManager.WIPE_EXTERNAL_STORAGE);
		}else{
			openAdmin(null);
		}
		
	}

	// 点击事件-开启设备管理员权限
	public void openAdmin(View view) {
		//创建新的Intent,动作是添加设备管理员
		Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
		//开启那个设备管理员-组件
		ComponentName  mDeviceAdminSample = new ComponentName(this,AdminReceiver.class);
		intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN,
				mDeviceAdminSample);
		
		intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION,
				"开启我后,你可以一键锁屏,可以禁用相机");
		startActivity(intent);

	}
	//点击事件-卸载自身
	public void uninstall(View view){
		//1.把权限取消
		ComponentName  who = new ComponentName(this,AdminReceiver.class);
		dpm.removeActiveAdmin(who);
		//2.普通应用
		//3.卸载
		Intent intent = new Intent();
//		 <intent-filter>
//         <action android:name="android.intent.action.VIEW" />
//         <action android:name="android.intent.action.DELETE" />
//         <category android:name="android.intent.category.DEFAULT" />
//         <data android:scheme="package" />
//     </intent-filter>
		intent.setAction("android.intent.action.DELETE");
		intent.addCategory("android.intent.category.DEFAULT");
		intent.setData(Uri.parse("package:"+getPackageName()));
		startActivity(intent);
	}

}
在清单文件中配置
 <receiver
            android:name="com.xbmu.mobilesafe.receiver.AdminReceiver"
            android:description="@string/sample_device_admin_description"
            android:label="@string/sample_device_admin"
            android:permission="android.permission.BIND_DEVICE_ADMIN" >
            <meta-data
                android:name="android.app.device_admin"
                android:resource="@xml/device_admin_sample" />

            <intent-filter>
                <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
            </intent-filter>
        </receiver>
res/values/strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>

    <string name="app_name">手机卫士</string>
    <string name="action_settings">Settings</string>
    <string name="sample_device_admin_description">设备管理描述</string>
    <string name="sample_device_admin">设备管理</string>

</resources>
SmsReciver.java
package com.xbmu.mobilesafe.receiver;

import android.app.admin.DevicePolicyManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.media.MediaPlayer;
import android.telephony.SmsMessage;

import com.xbmu.mobilesafe.OpenAdminActivity;
import com.xbmu.mobilesafe.R;
import com.xbmu.mobilesafe.service.LocationService;
/**
 * 拦截短信
 * @author Administrator
 *
 */
public class SmsReciver extends BroadcastReceiver {

	private String originatingAddress;
	private String messageBody;
	private DevicePolicyManager mDPM;
	@Override
	public void onReceive(Context context, Intent intent) {
		mDPM = (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);// 获取设备策略服务
		//接收短信
		Object[] objects = (Object[]) intent.getExtras().get("pdus");
		for (Object object : objects) {//短信最多140字节,超出的话,会分为多条短信发送,所以是一个数组,因为我们的短信指令很短,所以for循环只执行一次
			SmsMessage message = SmsMessage.createFromPdu((byte[])object);
			originatingAddress = message.getOriginatingAddress();//短信来源号码
			messageBody = message.getMessageBody();//短信内容
			System.out.println(originatingAddress+":"+messageBody);
			//拦截短信(短信内容为这些的短信 拦截下来)
			
			//播放报警音乐
			if("#*alarm*#".equals(messageBody)){
				//播放报警音乐,即使手机调为静音,也能播放音乐,因为使用的是媒体声音的通道,和铃声无关
				MediaPlayer player = MediaPlayer.create(context, R.raw.ylzs);
				player.setVolume(1f, 1f);//设置左右声道
				player.setLooping(true);//设置循环播放
				player.start();//开启播放
				abortBroadcast();//中断短信的传递,从而系统短信app就收不到内容了。
			}else if("#*location*#".equals(messageBody)){
				//获取经纬度坐标
				context.startService(new Intent(context, LocationService.class));//开启定位服务
				SharedPreferences sp = context.getSharedPreferences("config", Context.MODE_PRIVATE);
				String location  = sp.getString("location", "");
//				System.out.println("location:"+location);
				abortBroadcast();//中断短信的传递,从而系统短信app就收不到内容了。
			}else if("#*wipedata*#".equals(messageBody)){
				System.out.println("远程删除数据..");
//				mDPM.wipeData(0);//删除数据
				abortBroadcast();//终止广播-短信就没有了
			}else if("#*lockscreen*#".equals(messageBody)){
				System.out.println("远程锁屏..");
				ComponentName  who = new ComponentName(context,AdminReceiver.class);
				if(mDPM.isAdminActive(who)){
					mDPM.lockNow();
					mDPM.resetPassword("123", 0);
				}else{
					Intent intent_openAdmin = new Intent(context,OpenAdminActivity.class);
					intent_openAdmin.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
					context.startActivity(intent_openAdmin);
				}
				
				abortBroadcast();//终止广播-短信就没有了
			}
		}
		
	}
	
}
全部代码: http://download.csdn/detail/btt2013/9395522



本文标签: 安全卫士手机