android 自带location除了可以输出gps的经纬度信息,还可以进行传入location数据,进行模拟输出。输出模拟的位置信息可以在同一个应用程序,也可以给其他应用app使用。
本文的源码下载:http://download.csdn.net/detail/qq_16064871/9857036
1,开启传入location信息
先打开系统本机的gps,然后去开发者选项里打开模拟位置服务
//打开GPS设置
public void OpenGpsSettingEvent() {
Intent callGPSSettingIntent = new Intent(
android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
mContext.startActivity(callGPSSettingIntent);
}
//打开开发者模式
public void openTestProviderLocationException() {
Intent intent = new Intent("//");
ComponentName cm = new ComponentName("com.android.settings", "com.android.settings.DevelopmentSettings");
intent.setComponent(cm);
intent.setAction("android.intent.action.VIEW");
mContext.startActivity(intent);
}
添加模拟数据 mLocationManager.setTestProviderStatus(LocationManager.GPS_PROVIDER, 100, bundle, System.currentTimeMillis());其中100是自定义的标志位,也可以携带自定义的bundle数据。
//启动模拟位置服务
public boolean initLocation() {
mLocationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
if (!mLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
return false;
}
try {
//如果未开启模拟位置服务,则添加模拟位置服务
mLocationManager.addTestProvider(LocationManager.GPS_PROVIDER, false, false, false, false, true, true, true, 0, 5);
mLocationManager.setTestProviderEnabled(LocationManager.GPS_PROVIDER, true);
} catch (Exception e) {
return false;
}
return true;
}
//停止模拟位置服务
public void stopMockLocation() {
mbUpdate = false;
if (mLocationManager != null) {
try {
mLocationManager.clearTestProviderEnabled(LocationManager.GPS_PROVIDER);
mLocationManager.removeTestProvider(LocationManager.GPS_PROVIDER);
} catch (Exception e) {
Log.e("GPS", e.toString());
}
}
}
private Bundle bundle = new Bundle();
double testData = 0.0;
public void asynTaskUpdateCallBack() {
new Thread(new Runnable() {
@Override
public void run() {
while (mbUpdate) {
//测试的location数据
mlocation.setLongitude(testData++);
mlocation.setLatitude(testData++);
mlocation.setAltitude(testData++);
mlocation.setTime(System.currentTimeMillis());
mlocation.setBearing((float) 1.2);
mlocation.setSpeed((float) 1.2);
mlocation.setAccuracy((float) 1.2);
//额外的自定义数据,使用bundle来传递
bundle.putString("test1", "666");
bundle.putString("test2", "66666");
mlocation.setExtras(bundle);
try {
if (android.os.Build.VERSION.SDK_INT >= 17)
mlocation.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
mLocationManager.setTestProviderStatus(LocationManager.GPS_PROVIDER, 100, bundle, System.currentTimeMillis());
mLocationManager.setTestProviderLocation(LocationManager.GPS_PROVIDER, mlocation);
Thread.sleep(1000);
} catch (Exception e) {
return;
}
}
}
}).start();
}
2,获取模拟location数据
模拟location数据跟一般的location数据获取,以及初始化时一样的。唯一不同的是 onStatusChanged("gps", 100, mlocal.getExtras());这个方法使用。
package com.example.gpslocationdemo;
import android.annotation.TargetApi;
import android.content.Context;
import android.location.GpsStatus;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Build;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
public class LocationTestActivity extends AppCompatActivity {
LocationManager mLocationManager;
Location mlocation;
TextView mTextView;
TextView mTextView2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_location_test);
mTextView = (TextView) findViewById(R.id.textView1);
mTextView2 = (TextView) findViewById(R.id.textView2);
getLocation();
}
public Location getLocation() {
mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
if (mLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, mLocationListener);
mLocationManager.addNmeaListener(mNmeaListener);
}
return mlocation;
}
//这里获取的数据就是在之前一个activity写进去的数据
LocationListener mLocationListener = new LocationListener() {
//这个数据是经过LocationManager
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
@Override
public void onLocationChanged(Location mlocal) {
if (mlocal == null) return;
String strResult = "getAccuracy:" + mlocal.getAccuracy() + "\r\n"
+ "getAltitude:" + mlocal.getAltitude() + "\r\n"
+ "getBearing:" + mlocal.getBearing() + "\r\n"
+ "getElapsedRealtimeNanos:" + String.valueOf(mlocal.getElapsedRealtimeNanos()) + "\r\n"
+ "getLatitude:" + mlocal.getLatitude() + "\r\n"
+ "getLongitude:" + mlocal.getLongitude() + "\r\n"
+ "getProvider:" + mlocal.getProvider() + "\r\n"
+ "getSpeed:" + mlocal.getSpeed() + "\r\n"
+ "getTime:" + mlocal.getTime() + "\r\n";
Log.i("Show", strResult);
if (mTextView != null) {
mTextView.setText(strResult);
}
onStatusChanged("gps", 100, mlocal.getExtras());
}
@Override
public void onProviderDisabled(String arg0) {
}
@Override
public void onProviderEnabled(String arg0) {
}
@Override
public void onStatusChanged(String provider, int event, Bundle extras) {
if (event ==100){
String strResult = extras.getString("test1","") +"\n" +
extras.getString("test2","");
if (mTextView2 != null) {
mTextView2.setText(strResult);
}
}
}
};
//原始数据监听
GpsStatus.NmeaListener mNmeaListener = new GpsStatus.NmeaListener() {
@Override
public void onNmeaReceived(long arg0, String arg1) {
byte[] bytes = arg1.getBytes();
}
};
@Override
protected void onDestroy() {
super.onDestroy();
if (mLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
mLocationManager.removeNmeaListener(mNmeaListener);
mLocationManager.removeUpdates(mLocationListener);
}
}
}
正常获取location数据可参考:android 自带gps定位Location相关知识
3,权限
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"/>
4,附上部分location的sdk源码
// --- Mock provider support ---
// TODO: It would be fantastic to deprecate mock providers entirely, and replace
// with something closer to LocationProviderBase.java
/**
* Creates a mock location provider and adds it to the set of active providers.
*
* @param name the provider name
*
* @throws SecurityException if {@link android.app.AppOpsManager#OPSTR_MOCK_LOCATION
* mock location app op} is not set to {@link android.app.AppOpsManager#MODE_ALLOWED
* allowed} for your app.
* @throws IllegalArgumentException if a provider with the given name already exists
*/
public void addTestProvider(String name, boolean requiresNetwork, boolean requiresSatellite,
boolean requiresCell, boolean hasMonetaryCost, boolean supportsAltitude,
boolean supportsSpeed, boolean supportsBearing, int powerRequirement, int accuracy) {
ProviderProperties properties = new ProviderProperties(requiresNetwork,
requiresSatellite, requiresCell, hasMonetaryCost, supportsAltitude, supportsSpeed,
supportsBearing, powerRequirement, accuracy);
if (name.matches(LocationProvider.BAD_CHARS_REGEX)) {
throw new IllegalArgumentException("provider name contains illegal character: " + name);
}
try {
mService.addTestProvider(name, properties, mContext.getOpPackageName());
} catch (RemoteException e) {
Log.e(TAG, "RemoteException", e);
}
}