当手机被偷后,由于sim卡换掉会向安全号码发送通知信息。
这个时候安全号码就可以发送带有远程控制命令的短信到手机上,实现:获取手机位置、远程锁屏、播放报警音乐、清除数据等操作。
编写短信广播接受者,创建SmsReceiver:
package com.example.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.SmsManager;
import android.telephony.SmsMessage;
import android.util.Log;
import com.example.mobilesafe.R;
import com.example.mobilesafe.engine.GPSInfoProvider;
import java.util.Objects;
/**
* Created by sing on 14-1-3.
* desc:
*/
public class SmsReceiver extends BroadcastReceiver {
public static final String TAG = "SmsReceiver";
private SharedPreferences sp;
public void onReceive(Context context, Intent intent) {
Log.i(TAG, "收到短信");
sp = context.getSharedPreferences("config", Context.MODE_PRIVATE);
String safenumber = sp.getString("safenumber", "");
Object[] objs = (Object[]) intent.getExtras().get("pdus");
DevicePolicyManager dm = (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);
//创建一个与MyAdmin相关的组件
ComponentName componentName = new ComponentName(context, MyAdmin.class);
for (Object obj : objs) {
SmsMessage smsMessage = SmsMessage.createFromPdu((byte[]) obj);
//获取发件人的地址
String sender = smsMessage.getOriginatingAddress();
//获取短信内容
String body = smsMessage.getMessageBody();
if (body.equals("#*location*#")) {
Log.i(TAG, "发送当前位置");
String lastLocation= GPSInfoProvider.getInstance(context).getLocation();
if (lastLocation.isEmpty() == false) {
SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage(safenumber, null, lastLocation, null, null);
}
abortBroadcast();
} else if (body.equals("#*alarm*#")) {
Log.i(TAG, "播放报警音乐");
//得到音乐播放器
MediaPlayer player = MediaPlayer.create(context, R.raw.ylzs);
//设置音量,静音下也有声音
player.setVolume(1.0f, 1.0f);
//开始播放
player.start();
abortBroadcast();
} else if (body.equals("#*wipedata*#")) {
Log.i(TAG, "清除数据");
//判断设备的管理员权限是否被激活,只有被激活才可以执行锁屏、清除数据、恢复出厂设置(模拟器不支持该操作)等操作
if (dm.isAdminActive(componentName)) {
//清除设备中的数据,手机会自动重启
dm.wipeData(0);
}
abortBroadcast();
} else if (body.equals("#*lockscreen*#")) {
Log.i(TAG, "远程锁屏");
if (dm.isAdminActive(componentName)) {
dm.resetPassword("123", 0);
dm.lockNow();
}
abortBroadcast();
}
}//endfor
}
}
清单文件:
<receiver android:name=".receiver.SmsReceiver">
<intent-filter android:priority="1000">
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
</receiver>
添加权限:
<uses-permission android:name="android.permission.RECEIVE_SMS" />
获取地理位置的类GPSInfoProvider:
package com.example.mobilesafe.engine;
import android.content.Context;
import android.content.SharedPreferences;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
/**
* Created by sing on 14-1-3.
* desc:
*/
public class GPSInfoProvider {
private static GPSInfoProvider mGPSInfoProvider;
private static LocationManager lm;
private static MyListener listener;
private static SharedPreferences sp;
private GPSInfoProvider() {
}
public synchronized static GPSInfoProvider getInstance(Context context) {
if (mGPSInfoProvider == null) {
mGPSInfoProvider=new GPSInfoProvider();
//获取位置管理器
lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
//获取查询地理位置的查询条件对象(内部是map集合)
Criteria criteria = new Criteria();
//设置精准度:最精准
criteria.setAccuracy(Criteria.ACCURACY_FINE);
//gps定位是否允许产生开销
criteria.setCostAllowed(true);
//手机的功耗消耗情况(实时定位时,设置为最高)
criteria.setPowerRequirement(Criteria.POWER_HIGH);
//获取海拔高度
criteria.setAltitudeRequired(true);
//对手机的移动速度是否敏感
criteria.setSpeedRequired(true);
//获取当前手机最好用的位置提供者,参数一:查询选择条件,参数二:传递true表示只有可用的位置提供者时才会返回
String provider = lm.getBestProvider(criteria, true);
listener=new GPSInfoProvider().new MyListener();
//调用位置更新方法。参数一:位置提供者,参数二:最短的更新位置信息时间(最好大于60000即一分钟)
//参数三:最短通知距离,参数四:位置改变时的监听对象
lm.requestLocationUpdates(provider, 60000, 100, listener);
sp = context.getSharedPreferences("config", Context.MODE_PRIVATE);
}
return mGPSInfoProvider;
}
/**
* 取消位置监听
*/
public void stopListen() {
lm.removeUpdates(listener);
listener = null;
}
/**
* 位置监听对象
*/
protected class MyListener implements LocationListener {
/**
* 当手机位置发生改变时调用
* @param location
*/
@Override
public void onLocationChanged(Location location) {
String latitude = "latitude:" + location.getLatitude();
String longitude = "longitude:" + location.getLongitude();
String meter = "accuracy:" + location.getAccuracy();
System.out.println(latitude + "-" + longitude + "-" + meter);
SharedPreferences.Editor editor = sp.edit();
editor.putString("last_location", latitude + "-" + longitude + "-" + meter);
editor.commit();
}
/**
* 当位置提供者状态发生变化时调用
* @param s
* @param i
* @param bundle
*/
@Override
public void onStatusChanged(String s, int i, Bundle bundle) {
}
/**
* 当位置提供者不可用时
* @param s
*/
@Override
public void onProviderDisabled(String s) {
}
/**
* 当位置提供者可用时
* @param s
*/
@Override
public void onProviderEnabled(String s) {
}
}
/**
* 读取手机位置
* @return
*/
public String getLocation() {
return sp.getString("last_location", "");
}
}
需要添加权限:
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
清除数据和远程锁屏都需要管理员权限,在向导界面四中有一个TextView显示“点击激活deviceadmin”,为其添加点击事件,首先xml布局文件修改:
<TextView style="@style/content_text"
android:text="点击激活deviceadmin\n(激活后可以远程锁屏,清除数据)"
android:clickable="true"
android:onClick="activeDeviceAdmin"/>
并在LostProtectStep4Activity中实现activeDeviceAdmin:
/**
* 单击“激活deviceadmin”时的处理事件
* @param view
*/
public void activeDeviceAdmin(android.view.View view) {
ComponentName componentName = new ComponentName(this, MyAdmin.class);
DevicePolicyManager dm = (DevicePolicyManager) getSystemService(DEVICE_POLICY_SERVICE);
if (dm.isAdminActive(componentName)==false) {
Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, componentName);
startActivity(intent);
}
}
Admin是一个用于获取超级管理员权限要被激活的组件,该组件一旦被激活,当前的应用程序就获取到了超级管理员权限。
package com.example.mobilesafe.receiver;
import android.app.admin.DeviceAdminReceiver;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
/**
* Created by sing on 14-1-3.
* desc:MyAdmin是一个用于获取超级管理员权限要被激活的组件,该组件一旦被激活,当前的应用程序就获取到了超级管理员权限。
*/
public class MyAdmin extends DeviceAdminReceiver {
public void onReceive(Context context, Intent intent) {
}
}
清单文件:
<receiver android:name=".receiver.MyAdmin" >
<meta-data
android:name="android.app.device_admin"
android:resource="@xml/my_admin"/>
<intent-filter>
<action android:name="android.app.action.DEVICE_ADMIN_ENABLED"/>
</intent-filter>
</receiver>
my_admin.xml配置了申请的权限列表:
<?xml version="1.0" encoding="utf-8"?>
<device-admin xmlns:android="http://schemas.android.com/apk/res/android">
<uses-policies>
<limit-password />
<watch-login />
<reset-password />
<force-lock />
<wipe-data />
<expire-password />
<encrypted-storage />
<disable-camera />
</uses-policies>
</device-admin>
激活管理员权限的界面: