这阵子网上各种查代码写了一个监听短信的服务,然后返回一个带有gps地址的短信,并解析gps地址在地图上显示出来的一个小程序,但是返回来的短信在地图显示的时候出了问题,大家讨论下我的方法,欢迎拍砖,小弟正在学习中
首先是服务代码:
package android.org;
import android.app.Service;
import android.content.ContentResolver;
import android.content.Intent;
import android.database.ContentObserver;
import android.os.Handler;
import android.os.IBinder;
import android.os.Process;
import android.util.Log;
import android.org.SMS;
import android.org.SMSHandler;
import android.org.SMSObserver;
public class BootService extends Service
{
public static final String TAG = "BootService";
private ContentObserver mObserver;
private Handler mHandler = new Handler();
@Override
public void onCreate()
{
Log.i(TAG, "onCreate().");
super.onCreate();
addSMSObserver();
}
public void addSMSObserver()
{
Log.i(TAG, "add a SMS observer. ");
ContentResolver resolver = getContentResolver();
Handler handler = new SMSHandler(this);
mObserver = new SMSObserver(resolver, handler);
resolver.registerContentObserver(SMS.CONTENT_URI, true, mObserver);
}
@Override
public IBinder onBind(Intent intent)
{
return null;
}
@Override
public void onDestroy()
{
Log.i(TAG, "onDestroy().");
this.getContentResolver().unregisterContentObserver(mObserver);
super.onDestroy();
Process.killProcess(Process.myPid());
System.exit(0);
}
}
然后是ContentObserver类,用来自定义监听短信数据库,我这里将以“gps”开头的短信截获,然后传给mHandler.sendMessage(message);去处理
Handler的代码如下:也是我的问题来了,解析的短信不能显示到地图上,location获取到的也不是null。(尽管这个问题也纠结了很久)难道说是数据解析的问题?没什么难的逻辑啊,主要流程就是,我给我的服务发送一条内容是“gps01”的短信,然后截获后传给handler的handleMessage方法处理,并且最终解析到地图上显示出来位置。
package android.org;
import android.app.AlertDialog;
import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.telephony.SmsManager;
import android.util.Log;
public class SMSHandler extends Handler
{
public static final String TAG = "SMSHandler";
private Context mContext;
private LocationManager locationManager;
private Location location;
private AlertDialog.Builder myDialog;
private final LocationListener locationListener = new LocationListener() {
public void onLocationChanged(Location location) { //当坐标改变时触发此函数,如果Provider传进相同的坐标,它就不会被触发
// log it when the location changes
if (location != null) {
Log.i("SuperMap", "Location changed : Lat: "
+ location.getLatitude() + " Lng: "
+ location.getLongitude());
}
}
public void onProviderDisabled(String provider) {
// Provider被disable时触发此函数,比如GPS被关闭
}
public void onProviderEnabled(String provider) {
// Provider被enable时触发此函数,比如GPS被打开
}
public void onStatusChanged(String provider, int status, Bundle extras) {
// Provider的转态在可用、暂时不可用和无服务三个状态直接切换时触发此函数
}
};
public SMSHandler(Context context)
{
super();
this.mContext = context;
}
@Override
public void handleMessage(Message message)
{
Log.i(TAG, "handleMessage: " + message);
MessageItem item = (MessageItem) message.obj;
//delete the sms
Uri uri = ContentUris.withAppendedId(SMS.CONTENT_URI, item.getId());
String l,r,body;
body=item.getBody().substring(3, item.getBody().length());
//
mContext.getContentResolver().delete(uri, null, null);
Log.i(TAG, "delete sms item: " + item);
// AlertDialog.Builder myDialog = new AlertDialog.Builder(this.mContext);
// myDialog.setTitle("短信状态");
// myDialog.setMessage("delete sms item:");
// myDialog.show();
if(body.substring(0, 2).equals("01")){
//获取本地gps地址
// LocationManager locationManager = (LocationManager)this.mContext.getSystemService(this.mContext.LOCATION_SERVICE);
//// locationManager.setTestProviderEnabled("gps", true);
// locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 0, locationListener);
//
// Location location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
//
// while(location == null)
// {
// locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 100, 1, locationListener);
// }
//
//
//
getLocation();
String latitude = Double.toString(location.getLatitude());//经度
String longitude = Double.toString(location.getLongitude());//纬度
String altitude = Double.toString(location.getAltitude());//海拔
String result = "gps02"+latitude+":"+longitude;
SmsManager sms = SmsManager.getDefault();
sms.sendTextMessage("13426294680", null, result, null, null);
}
else if(body.substring(0, 2).equals("02")){
Intent intents = new Intent();
intents.setClass(this.mContext, CityMap.class);
Bundle bun = new Bundle();
String gps[] = body.substring(2, body.length()).split(":");
l=gps[0];
r=gps[1];
bun.putString("gps_l", l);
bun.putString("gps_r",r);
intents.putExtras(bun);
myDialog = new AlertDialog.Builder(this.mContext);
myDialog.setTitle("发送状态");
myDialog.setMessage(body);
myDialog.show();
intents.setFlags( Intent.FLAG_ACTIVITY_NEW_TASK );
this.mContext.startActivity(intents);
}
// else{
//
// Intent intents = new Intent();
// intents.setClass(this.mContext, CityMap.class);
// Bundle bun = new Bundle();
// bun.putString("gps_l", "55555");
// bun.putString("gps_r","55555");
// intents.putExtras(bun);
// intents.setFlags( Intent.FLAG_ACTIVITY_NEW_TASK );
// this.mContext.startActivity(intents);
// }
}
private void getLocation() {
// 获取位置管理服务 LocationManager locationManager;
String serviceName = this.mContext.LOCATION_SERVICE;
locationManager = (LocationManager) this.mContext.getSystemService(serviceName);
// 查找到服务信息
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE); // 高精度
criteria.setAltitudeRequired(false);
criteria.setBearingRequired(false);
criteria.setCostAllowed(true);
criteria.setPowerRequirement(Criteria.POWER_LOW); // 低功耗
String provider = locationManager.getBestProvider(criteria, true); // 获取GPS信息
this.location = locationManager.getLastKnownLocation(provider); // 通过GPS获取位置
// updateToNewLocation(location); // 设置监听器,自动更新的最小时间为间隔N秒(1秒为1*1000,这样写主要为了方便)或最小位移变化超过N米
locationManager.requestLocationUpdates(provider, 100 * 1000, 500,locationListener);
}
}
下面是地图显示的代码:
package android.org;
import java.util.List;
import android.org.R;
import android.org.CityMap.MyLocationOverlay;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import android.app.Activity;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.app.*;
import android.content.pm.ApplicationInfo;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Point;
public class CityMap extends MapActivity{
private MapView myMapView;
private Button button;
private EditText weidu;
private EditText jingdu;
private MapView mapView;
private int level = 8;
GeoPoint point;
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
Bundle extras = getIntent().getExtras();
// get the geopoint by city
// String city = extras.getString(MapConstants.CITY_NAME);
GeoPoint gp = new GeoPoint(111,11);
setContentView(R.layout.earth);
Bundle bun=this.getIntent().getExtras();
final String l=bun.getString("gps_l");
final String r=bun.getString("gps_r");
button = (Button) findViewById(R.id.bu);
mapView = ((MapView) findViewById(R.id.mv));
mapView.setClickable(true);
mapView.setEnabled(true);
// 切换到卫星地图
mapView.setSatellite(true);
mapView.setTraffic(false); // 交通模式
mapView.getController().setZoom(level++);// 设置地图放大的级别
List<Overlay> laies = mapView.getOverlays();
button.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
point = new GeoPoint((int) (Double.parseDouble(l)* 1E6), (int) (Double.parseDouble(r)* 1E6));
mapView.getController().animateTo(point); // 把地图移动到指定的经纬度
// 注意在我们使用Android的map时如果没有得到google的授权那么我们将不会取得任何数据
List<Overlay> laies = mapView.getOverlays();
laies.clear();
MyLocationOverlay myLocationOverlay;
// myLocationOverlay.bitmap = new Bitmap("icon.bmp");
laies.add(new MyLocationOverlay());
}
});
}
@Override
protected boolean isRouteDisplayed() {
// TODO Auto-generated method stub
return false;
}
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_I) {
// zoom in
myMapView.getController().setZoom(myMapView.getZoomLevel() + 1);
return true;
} else if (keyCode == KeyEvent.KEYCODE_O) {
// zoom out
myMapView.getController().setZoom(myMapView.getZoomLevel() - 1);
// 定位到指定的经纬度:
// mc.animateTo(pointFuZhou);
return true;
} else if (keyCode == KeyEvent.KEYCODE_S) {
// 卫星地图
// myMapView.setSatellite(true); // 卫星模式
// myMapView.setTraffic(false); // 交通模式
myMapView.setSatellite(true);
myMapView.setTraffic(false); // 交通模式
return true;
} else if (keyCode == KeyEvent.KEYCODE_T) {
// traffic,路况
myMapView.setSatellite(false);
myMapView.setTraffic(true); // 交通模式;
return true;
}
return false;
}
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
menu.add(0,1,1, R.string.exit_citymap);
return true;
}
@Override
public boolean onMenuItemSelected(int featureId, MenuItem item) {
super.onMenuItemSelected(featureId, item);
switch(item.getItemId()) {
case 1:
finish();
break;
}
return true;
}
class MyLocationOverlay extends Overlay {
Bitmap bitmap;
@Override
public boolean draw(Canvas canvas, MapView mapView, boolean shadow,
long when) {
super.draw(canvas, mapView, shadow, when);
Paint paint = new Paint();
Point p = new Point();
paint.setStrokeWidth(2);
paint.setARGB(255, 0, 0, 0);
mapView.getProjection().toPixels(point, p);
// canvas.drawText("不死鹰", p.x, p.y, paint);
bitmap = getRes("icon1");
canvas.drawBitmap(bitmap, p.x, p.y, paint);
return true;
}
public Bitmap getRes(String name) {
ApplicationInfo appInfo = getApplicationInfo();
int resID = getResources().getIdentifier(name, "drawable", appInfo.packageName);
return BitmapFactory.decodeResource(getResources(), resID);
}
}
}
xml权限代码:
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_SMS"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" />
现在需要讨论的问题就是:
1、获取gps的位置的时候,一开始总是为空,然后换了现在这种方法后才能获取到具体地址,是什么原因
2、手机上测试的时候(我的手机是魅族M9),并没有开gps开关,是如何定位gps位置的
3、显示的时候,google地图和电脑版的不一样,没有大楼说明,也没有街道说明,我并不是没有试过打开街道显示,总之地图上的具体描述不多,光秃秃的卫星地图或者交通图。
4、我的短信解析是否有问题,例如我发送一条地址短信“gps0235.3333222222:135.2322342222”为什么程序异常终止
5、我在activity里设置了一个按钮,启动我的服务,但如果我多次点击这个按钮会不会实例化多个服务?从而占用手机内存?如何解决这个问题
欢迎各位android大侠前来讨论指导,移动论坛里向来不乏高手,但最近表示大侠们太低调了,技术贴好久都没有更新,lordhong也不前来光顾了