首页 > 代码库 > GPS定位源代码
GPS定位源代码
本代码实现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 = http://www.mamicode.com/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等信息。界面很简单。不多说了,上图。
对了,真机才能定位成功。
GPS定位源代码