`
923723914
  • 浏览: 634826 次
文章分类
社区版块
存档分类
最新评论

Android项目实战--手机卫士10--GPS定位与发送短信指令

 
阅读更多

由于周末有点事,所以没来得及继续更新我们的这个项目,今天终于有时间写一下啦。

好啦,废话不多说,我们进入主题,今天我们要继续上一次讲的,就是手机被盗之后,获得手机所在的位置。

上一次,我们说到了,如果我们的sim卡被人换掉了,那么就会发送一条短信到我们的原来设定的安全号码那里的,而今天,我们就要获取到手机的位置啦,以便追踪回手机。

我们是这样设计的,我们通过发送一条短信,短信的内容就是一些要执行的操作的指令(比如说#*location*#),我们就在软件里面加入一个短信的广播,拦截到短信,然后分析是什么指令,然后就执行对应的操作,就像#*location*#这条指令一样,我们就可以理解为获取手机的位置。

所以我们要先新建一个类,用来提供手机的位置信息的

com.xiaobin.security.engine.GPSInfoProvider

package com.xiaobin.security.engine;

import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;

/**
 * 这个类,我们要做成了单例模式,因为手机里面只有一个gps所以免得每次都新开一个对象
 * @author Administrator
 *
 */
public class GPSInfoProvider
{
	private static GPSInfoProvider gpsInfoProvider;
	private static Context context;
	private static MyLocationListener listener;
	private LocationManager locationManager;
	
	private GPSInfoProvider()
	{
		
	}
	
	/**
	 * 为了让这个方法一定执行完,所以我们加入了synchronized来修饰
	 * @return
	 */
	public static synchronized GPSInfoProvider getInstance(Context context)
	{
		if(gpsInfoProvider == null)
		{
			gpsInfoProvider = new GPSInfoProvider();
			GPSInfoProvider.context = context;
		}
		return gpsInfoProvider;
	}
	
	public String getLocation()
	{
		locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
		
		String provider = getBestProvider();
		
		//这个方法是位置更新的的操作,有四个参数
		//第一个参数就是使用的定位设备啊,如gps,基站定位啊
		//第二个参数就是多长时间更新一次定位信息,太频繁了会很耗电,根据自己程序的实际需要来进行确定
		//第三个参数就是用户位移了多少米之后,就重新获取一次定位信息,太频繁了会很耗电,根据自己程序的实际需要来进行确定
		//最后一个参数就是在位置发生变化的回调方法
		locationManager.requestLocationUpdates(provider, 60000, 50, getListener());
		//locationManager.getAllProviders();//它会把所以支持的定位方式都打列出来,这样就可以知道手机所支持的定位啦
		
		SharedPreferences sp = context.getSharedPreferences("config", Context.MODE_PRIVATE);
		String location = sp.getString("lostLocation", "");
		return location;
	}
	
	//停止gps
	public void stopGPSListener()
	{
		if(locationManager != null)
		{
			locationManager.removeUpdates(getListener());
		}
	}
	
	private String getBestProvider()
	{
		Criteria criteria = new Criteria();
		//这个是定义它的定位精度的
		//Criteria.ACCURACY_COARSE  这个是一般的定位
		//Criteria.ACCURACY_FINE  这个是精准定位
		criteria.setAccuracy(Criteria.ACCURACY_FINE);
		
		//设置是不是对海拔敏感的
		criteria.setAltitudeRequired(false);
		
		//设置对手机的耗电量,定位要求越高,越耗电
		criteria.setPowerRequirement(Criteria.POWER_MEDIUM);
		
		//设置对速度变化是不是敏感
		criteria.setSpeedRequired(true);
		
		//设置在定位时,是不是允许与运营商交换数据的开销
		criteria.setCostAllowed(true);
		
		//这个方法是用来得到最好的定位方式的,它有两个参数,一个是Criteria(类似于Map集合),就是一些条件,比如说对加速度敏感啊,什么海拔敏感这些的
		//第二个参数就是,如果我们置为false,那么我们得到的也有可能是已经关掉了的设备,如果是true那么,就只会得到已经打开了的设备
		return locationManager.getBestProvider(criteria, true);
	}
	
	//做成单例模式
	private synchronized MyLocationListener getListener()
	{
		if(listener == null)
		{
			listener = new MyLocationListener();
		}
		return listener;
	}
	
	//=========================================================================
	
	private class MyLocationListener implements LocationListener
	{

		@Override
		public void onLocationChanged(Location location)
		{
			//手机位置发生改变时调用的方法
			String latitude = "纬度:" + location.getLatitude();//纬度
			String longitude = "经度:" + location.getLongitude();//经度
			SharedPreferences sp = context.getSharedPreferences("config", Context.MODE_PRIVATE);
			Editor editor = sp.edit();
			editor.putString("lastLocation", latitude + " - " + longitude);
			editor.commit();
		}

		@Override
		public void onStatusChanged(String provider, int status, Bundle extras)
		{
			//定位设备的状态发生改变的时候调用的方法,比如说用户把设备打开,或关闭,第二个参数就是设备的状态啦
		}

		@Override
		public void onProviderEnabled(String provider)
		{
			//设备打开的时候调用的方法
		}

		@Override
		public void onProviderDisabled(String provider)
		{
			//设备关闭的时候调用的方法
		}
		
	}

}

然后呢,我们就要开启一个广播接收者啦,一但拦截到我们发的短信,那么就进行指令的分析还有相应的处理

所以我们新建一个广播接收者

com.xiaobin.security.receiver.SmsReceiver

package com.xiaobin.security.receiver;

import com.xiaobin.security.engine.GPSInfoProvider;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.SmsManager;
import android.telephony.SmsMessage;

public class SmsReceiver extends BroadcastReceiver
{

	@Override
	public void onReceive(Context context, Intent intent)
	{
		Object[] pdus = (Object[]) intent.getExtras().get("pdus");
		for(Object pdu : pdus)
		{
			SmsMessage smsMessage = SmsMessage.createFromPdu((byte[]) pdu);
			//拿到短信内容
			String content = smsMessage.getMessageBody();
			//拿到发送人的电话号码
			String sender = smsMessage.getOriginatingAddress();
			
			//这个是通过短信发送指令,然后进行一些操作的
			if(content.equals("#*location*#"))
			{
				abortBroadcast();//终止广播,免得让小偷看到短信
				GPSInfoProvider gpsInfoProvider = GPSInfoProvider.getInstance(context);
				String location = gpsInfoProvider.getLocation();
				System.out.println(location);
				if(!location.equals(""))
				{
					//发送短信
					SmsManager smsManager = SmsManager.getDefault();
					smsManager.sendTextMessage(sender, null, location, null, null);
				}
			}
		}
	}

}

上面获取短信的代码可能大家有点疑问了,为什么会是pdus,这个的话,我们就可以下载一下Android自己写好了的短信管理器的代码啦,我们可以下载一下它的源码来看一下,Android源码下载的方法我们之前说过的啦!去看一下,就可以知道为什么的啦。大家可以搜一下sms就可以找到的啦,然后下来来看看吧。

好啦,从上面的代码也可以看到,我们拿到了那条指令短信,然后,就获取位置,然后再发回给我们的手机,而且也把广播终止啦,这样,小偷就不会知道我们把短信发送到手机上啦,这样我们就可以瞒过小偷,进行一些操作啦,我们还可以定义多一些指令,比如说,删除东西的指令啦,格式化的指令啦,乱发东西的指令啦,都可以的,我们看一下有没有空,尽量写多一些功能!

好啦,现在广播接收者就写好啦,我们也要在AndroidMainfest里面注册它啦

<receiver 
            android:name="com.xiaobin.security.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"/>
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <!-- 这个是用模拟器进行测试才需要用到的权限,表示是这个模拟的位置 -->
    <uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION"/>


注意,模拟器2.3的Android版本的gps是有问题的,所以如果用模拟器测试的话,那么你就不要用2.3的模拟器啦

好啦,再说一点,我们拿到的是手机的经度可纬度,只要我们在谷歌地图那里查一下,就可以得到在那里的啦,我们明天就会继续完善我们的指令的,加入锁屏还有恢复到出厂模式,和播放报警音乐!




好啦,今天就讲到这里,下一次,我们再继续


今天源码下载









分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics