本代码实现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 milliseconds
private static final long minTime = 30000;
// 最小变更距离 10m --minimum distance between location updates, in meters
private 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;
@Override
public 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.");
}
@Override
public 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.");
}
@Override
public IBinder onBind(Intent intent) {
  // TODO Auto-generated method stub
  return mBinder;
}
@Override
public 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;
@Override
public 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;
  }
}
@Override
public 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);
   }
  }
}
@Override
protected void onStart() {
  // TODO Auto-generated method stub
  super.onStart();
}
@Override
protected 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等信息。界面很简单。不多说了,上图。
对了,真机才能定位成功。

任何事情在开始的时候,我们都应该像“光头强”、“灰太狼”一样,败不馁,不怕输...愈战愈勇!