本代码实现GPS定位,并定时在界面上呈现定位的精度以及在用卫星数量。
布局代码如下:<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:id="@+id/showtv" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="GPS经纬度获取服务,每60秒界面更新一次数据,而后台GPS更新服务是每30秒更新一次GPS数据" /> <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginTop="8dp" android:gravity="center" android:orientation="horizontal" > <Button android:id="@+id/Startbtn" android:layout_width="96dp" android:layout_height="48dp" android:text="@string/startbtn" /> <Button android:id="@+id/Stopbtn" android:layout_width="96dp" android:layout_height="48dp" android:text="@string/stopbtn" /> </LinearLayout> <TextView android:id="@+id/tv" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginLeft="4dp" android:layout_marginTop="10dp" android:text="@string/defaultshow" android:textSize="18sp" /></LinearLayout>首先写后台的LBSServiceListener 实现LocationListener接口,在这个LBSServiceListener 中可以重写方法,代码如下:package com.exams.demo10_lbs;import java.text.DateFormat;import java.text.SimpleDateFormat;import java.util.Calendar;import java.util.GregorianCalendar;import java.util.TimeZone;import android.location.Location;import android.location.LocationListener;import android.os.Bundle;import android.util.Log;public class LBSServiceListener implements LocationListener { public int GPSCurrentStatus;public Location currentLocation;public void onLocationChanged(Location location) { // TODO Auto-generated method stub //------- // Called when a new location is found by the location provider. if (currentLocation != null) { if (isBetterLocation(location, currentLocation)) { // Log.v("GPSTEST", "It's a better location"); currentLocation = location; } else { // Log.v("GPSTEST", "Not very good!"); } } else { // Log.v("GPSTEST", "It's first location"); currentLocation = location; }}// 将数据通过get的方式发送到服务器,服务器可以根据这个数据进行跟踪用户的行走状态private void doGet(String string) { // TODO Auto-generated method stub //}public void onProviderDisabled(String provider) { // TODO Auto-generated method stub // if ((LocationManager.NETWORK_PROVIDER).equals(provider)) { // locationManager.removeUpdates(this); // } else if ((LocationManager.GPS_PROVIDER).equals(provider)) { // locationManager.removeUpdates(this); // }}public void onProviderEnabled(String provider) { // TODO Auto-generated method stub}public void onStatusChanged(String provider, int status, Bundle extras) { // TODO Auto-generated method stub GPSCurrentStatus = status;}private static final int CHECK_INTERVAL = 1000 * 30;protected boolean isBetterLocation(Location location, Location currentBestLocation) { if (currentBestLocation == null) { // A new location is always better than no location return true; } // Check whether the new location fix is newer or older long timeDelta = location.getTime() - currentBestLocation.getTime(); boolean isSignificantlyNewer = timeDelta > CHECK_INTERVAL; boolean isSignificantlyOlder = timeDelta < -CHECK_INTERVAL; boolean isNewer = timeDelta > 0; // If it's been more than two minutes since the current location, // use the new location // because the user has likely moved if (isSignificantlyNewer) { return true; // If the new location is more than two minutes older, it must // be worse } else if (isSignificantlyOlder) { return false; } // Check whether the new location fix is more or less accurate int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation .getAccuracy()); boolean isLessAccurate = accuracyDelta > 0; boolean isMoreAccurate = accuracyDelta < 0; boolean isSignificantlyLessAccurate = accuracyDelta > 200; // Check if the old and new location are from the same provider boolean isFromSameProvider = isSameProvider(location.getProvider(), currentBestLocation.getProvider()); // Determine location quality using a combination of timeliness and // accuracy if (isMoreAccurate) { return true; } else if (isNewer && !isLessAccurate) { return true; } else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) { return true; } return false;}/** Checks whether two providers are the same */private boolean isSameProvider(String provider1, String provider2) { if (provider1 == null) { return provider2 == null; } return provider1.equals(provider2);}}
这样这个LBSServiceListener已经实现,其中我使用isBetterLocation()方法对Location做判断。
下面代码是GpsSatelliteListener 实现GpsStatus.Listener:package com.exams.demo10_lbs;import android.location.GpsStatus;import android.location.GpsStatus.Listener;public class GpsSatelliteListener implements Listener { public void onGpsStatusChanged(int event) { // TODO Auto-generated method stub switch (event) { // 第一次定位 case GpsStatus.GPS_EVENT_FIRST_FIX: break; // 卫星状态改变 case GpsStatus.GPS_EVENT_SATELLITE_STATUS: break; // 定位启动 case GpsStatus.GPS_EVENT_STARTED: break; // 定位结束 case GpsStatus.GPS_EVENT_STOPPED: break; }}}重点是LBSService 它是继承了Service.在这个类中,重点通过onStartCommand方法和ACTIVITY沟通,实现将定位的经纬度等信息返回给activity的textview文本呈现出来。package com.exams.demo10_lbs;import java.text.SimpleDateFormat;import java.util.Date;import java.util.Iterator;import android.app.Notification;import android.app.NotificationManager;import android.app.PendingIntent;import android.app.Service;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.content.IntentFilter;import android.location.GpsSatellite;import android.location.GpsStatus;import android.location.Location;import android.location.LocationListener;import android.location.LocationManager;import android.os.Binder;import android.os.Bundle;import android.os.IBinder;import android.util.Log;public class LBSService extends Service { public static final String TAG = "LBSService";// 30000ms --minimum time interval between location updates, in millisecondsprivate static final long minTime = 30000;// 最小变更距离 10m --minimum distance between location updates, in metersprivate static final float minDistance = 10;String tag = this.toString();private LocationManager locationManager;private LocationListener locationListener;private Location location;private GpsStatus gStatus;private GpsSatelliteListener gpsSatelliteListener;private final IBinder mBinder = new LBSServiceBinder();private NotificationManager mNM;boolean flag;CommandReceiver cmdReceiver;@Overridepublic void onCreate() { // TODO Auto-generated method stub flag = true; cmdReceiver = new CommandReceiver(); super.onCreate(); mNM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); showNotification(); startService(); Log.i(TAG, "in onCreate method.");}@Overridepublic void onDestroy() { // TODO Auto-generated method stub this.unregisterReceiver(cmdReceiver);// 取消注册的CommandReceiver super.onDestroy(); stopService(); mNM.cancel(R.string.lbsservice); Log.i(TAG, "in onDestroy method.");}@Overridepublic IBinder onBind(Intent intent) { // TODO Auto-generated method stub return mBinder;}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) { // TODO Auto-generated method stub IntentFilter filter = new IntentFilter();// 创建IntentFilter对象 filter.addAction("com.exams.demo10_lbs.LBSService"); registerReceiver(cmdReceiver, filter);// 注册Broadcast // Receiver,后续会接收相关广播intent doJob();// 调用方法启动线程 return super.onStartCommand(intent, flags, startId);}public class LBSServiceBinder extends Binder { LBSService getService() { return LBSService.this; }}public void startService() { locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); locationListener = new LBSServiceListener(); locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, minTime, minDistance, locationListener); gpsSatelliteListener = new GpsSatelliteListener(); locationManager.addGpsStatusListener(gpsSatelliteListener); Log.i(TAG, "in startService method.");}public void stopService() { if (locationManager != null && locationListener != null && gpsSatelliteListener != null) { locationManager.removeUpdates(locationListener); locationManager.removeGpsStatusListener(gpsSatelliteListener); } Log.i(TAG, "in stopService method.");}private class CommandReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { // TODO Auto-generated method stub int cmd = intent.getIntExtra("cmd", -1);// 获取Extra信息 if (cmd == MainActivity.CMD_STOP_SERVICE) {// 如果发来的消息是停止服务 flag = false;// 停止线程 stopSelf();// 停止服务 } }// 继承自BroadcastReceiver的子类}/** * Show a notification while this service is running. */@SuppressWarnings("deprecation")private void showNotification() { // In this sample, we'll use the same text // for the ticker and the expanded // notification CharSequence text = getText(R.string.lbsservice); // Set the icon, scrolling text and timestamp Notification notification = new Notification(R.drawable.ic_launcher, text, System.currentTimeMillis()); // The PendingIntent to launch our activity if the user selects this Intent intent = new Intent(this, MainActivity.class); // notification PendingIntent contentIntent = PendingIntent.getActivity(this, 0, intent, 0); // Set the info for the views that show in the notification panel. notification.setLatestEventInfo(this, "LBSService", "LBS Service started", contentIntent); // Send the notification. // We use a layout id because it is a unique number. We use it later to // cancel. mNM.notify(R.string.lbsservice, notification);}// 方法:public void doJob() { new Thread() { public void run() { while (flag) { try {// 睡眠一段时间 Thread.sleep(60000); } catch (Exception e) { e.printStackTrace(); } Intent intent = new Intent();// 创建Intent对象 intent.setAction("com.exams.demo10_lbs"); location = locationManager .getLastKnownLocation(LocationManager.GPS_PROVIDER); gStatus = locationManager.getGpsStatus(null); // 获取默认最大卫星数 int maxSatellites = gStatus.getMaxSatellites(); Iterable<GpsSatellite> iterable = gStatus.getSatellites(); Iterator<GpsSatellite> iterator = iterable.iterator(); int x = 0; while (iterator != null && iterator.hasNext() && x <= maxSatellites) { GpsSatellite gpsSatellite = (GpsSatellite) iterator .next(); if (gpsSatellite.usedInFix()) x++; } String latitude, longitude, accuracy, speed; if (location != null) { latitude = location.getLatitude() + ""; longitude = location.getLongitude() + ""; accuracy = location.getAccuracy() + ""; speed = location.getSpeed() + ""; } else { latitude = "0.0"; longitude = "0.0"; accuracy = "未知 "; speed = "0.0"; } Bundle bundle = new Bundle(); bundle.putString("latitude", latitude); bundle.putString("longitude", longitude); bundle.putString("accuracy", accuracy + "m"); bundle.putString("speed", speed + "m/s"); bundle.putString("Satenum", x + "个"); SimpleDateFormat sDateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date nowDate=new Date(); String dateString=sDateFormat.format(nowDate); bundle.putString("date", dateString+ ""); intent.putExtras(bundle); sendBroadcast(intent);// 发送广播 } } }.start();}} 最后是Activity部分:package com.exams.demo10_lbs;import android.app.Activity;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.content.IntentFilter;import android.location.LocationManager;import android.os.Bundle;import android.provider.Settings;import android.util.Log;import android.view.Menu;import android.view.View;import android.widget.Button;import android.widget.TextView;import android.widget.Toast;public class MainActivity extends Activity { public static final int CMD_STOP_SERVICE = 0;public static final String TAG = "MainActivity";public Button startbtnButton, stopButton;public TextView tView;DataReceiver dataReceiver;// BroadcastReceiver对象public LocationManager lManager;@Overridepublic void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); startbtnButton = (Button) findViewById(R.id.Startbtn); stopButton = (Button) findViewById(R.id.Stopbtn); tView = (TextView) findViewById(R.id.tv); lManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); // 判断GPS是否正常启动 if (!lManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) { Toast.makeText(this, "请开启GPS导航...", Toast.LENGTH_SHORT).show(); // 返回开启GPS导航设置界面 Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS); startActivityForResult(intent, 0); return; } startbtnButton.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { // TODO Auto-generated method stub startService(); } }); stopButton.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { // TODO Auto-generated method stub stopService(); } });}private void startService() { startbtnButton.setEnabled(false); stopButton.setEnabled(true); Intent i = new Intent(this, LBSService.class); this.startService(i); Log.i(TAG, "in startService method."); if (dataReceiver == null) { dataReceiver = new DataReceiver(); IntentFilter filter = new IntentFilter();// 创建IntentFilter对象 filter.addAction("com.exams.demo10_lbs"); registerReceiver(dataReceiver, filter);// 注册Broadcast Receiver }}private void stopService() { startbtnButton.setEnabled(true); stopButton.setEnabled(false); Intent i = new Intent(this, LBSService.class); this.stopService(i); Log.i(TAG, "in stopService method."); if (dataReceiver != null) { unregisterReceiver(dataReceiver);// 取消注册Broadcast Receiver dataReceiver = null; }}@Overridepublic boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.activity_main, menu); return true;}private class DataReceiver extends BroadcastReceiver {// 继承自BroadcastReceiver的子类 @Override public void onReceive(Context context, Intent intent) {// 重写onReceive方法 Bundle bundledata = intent.getExtras(); if (bundledata != null) { String latitude = bundledata.getString("latitude"); String longitude = bundledata.getString("longitude"); String accuracy = bundledata.getString("accuracy"); String speed=bundledata.getString("speed"); String Satenum = bundledata.getString("Satenum"); String dateString = bundledata.getString("date"); tView.setText("\t卫星在用数量:" + Satenum + "\n\t纬度:" + latitude + "\t经度:" + longitude + "\n\t精度:" + accuracy +"\n\t速度:"+speed+ "\n\t更新时间:" + dateString); } }}@Overrideprotected void onStart() { // TODO Auto-generated method stub super.onStart();}@Overrideprotected void onStop() { // TODO Auto-generated method stub super.onStop();}}其中AndroidManifest.xml文件内容如下:<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.exams.demo10_lbs" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="15" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <application android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".MainActivity" android:label="@string/title_activity_main" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <service android:name=".LBSService" android:process=":remote" > <intent-filter> <action android:name="com.exams.demo10_lbs.LBSService" /> </intent-filter> </service> </application></manifest>这个是根据网上学习相关service及activity等写的,有不足的地方,希望大家指正。代码有点乱,有些欠考虑的地方,还在完善中。现在共享出来,期望一起学习~~~
执行步骤,启动后,点击“启动”按钮,后台会启动一个service服务,然后一分钟的时间,会在界面上呈现出最后一次定位的GPS等信息。界面很简单。不多说了,上图。对了,真机才能定位成功。