Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .idea/.name

This file was deleted.

9 changes: 1 addition & 8 deletions .idea/gradle.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 0 additions & 12 deletions .idea/runConfigurations.xml

This file was deleted.

4 changes: 2 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ android {
applicationId "name.caiyao.fakegps"
minSdkVersion 9
targetSdkVersion 22
versionCode 3
versionName "1.2.0 beta"
versionCode 6
versionName "1.2.2"
}
buildTypes {
release {
Expand Down
4 changes: 4 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@
android:value="e34a748230a8123b72fd71a6f1604946" />

<service android:name=".MockGpsService"/>
<provider
android:authorities="name.caiyao.fakegps.SettingProvider"
android:exported="true"
android:name=".SettingProvider"/>
</application>

</manifest>
27 changes: 27 additions & 0 deletions app/src/main/java/name/caiyao/fakegps/DbHelper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package name.caiyao.fakegps;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

/**
* Created by 蔡小木 on 2016/5/11 0011.
*/
public class DbHelper extends SQLiteOpenHelper {

private static final String DB_NAME = "fake.db";
public static final String TABLE_NAME = "fake";
public DbHelper(Context context) {
super(context, DB_NAME, null, 1);
}

@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE IF NOT EXISTS "+TABLE_NAME + "(key TEXT PRIMARY KEY,value TEXT)");
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

}
}
89 changes: 89 additions & 0 deletions app/src/main/java/name/caiyao/fakegps/GpsUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package name.caiyao.fakegps;

/**
* Created by 蔡小木 on 2016/5/24 0024.
*/

public class GpsUtils {

static double x_pi = 3.14159265358979324 * 3000.0 / 180.0;
// π
static double pi = 3.1415926535897932384626;
// 长半轴
static double a = 6378245.0;
// 扁率
static double ee = 0.00669342162296594323;

private GpsUtils(){
}

/**
* GCJ02(火星坐标系)转GPS84
*
* @param lng 火星坐标系的经度
* @param lat 火星坐标系纬度
* @return WGS84坐标数组
*/
public static double[] gcj02towgs84(double lng, double lat) {
if (out_of_china(lng, lat)) {
return new double[] { lng, lat };
}
double dlat = transformlat(lng - 105.0, lat - 35.0);
double dlng = transformlng(lng - 105.0, lat - 35.0);
double radlat = lat / 180.0 * pi;
double magic = Math.sin(radlat);
magic = 1 - ee * magic * magic;
double sqrtmagic = Math.sqrt(magic);
dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * pi);
dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * pi);
double mglat = lat + dlat;
double mglng = lng + dlng;
return new double[] { lng * 2 - mglng, lat * 2 - mglat };
}

/**
* 纬度转换
*
* @param lng
* @param lat
* @return
*/
public static double transformlat(double lng, double lat) {
double ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.sqrt(Math.abs(lng));
ret += (20.0 * Math.sin(6.0 * lng * pi) + 20.0 * Math.sin(2.0 * lng * pi)) * 2.0 / 3.0;
ret += (20.0 * Math.sin(lat * pi) + 40.0 * Math.sin(lat / 3.0 * pi)) * 2.0 / 3.0;
ret += (160.0 * Math.sin(lat / 12.0 * pi) + 320 * Math.sin(lat * pi / 30.0)) * 2.0 / 3.0;
return ret;
}

/**
* 经度转换
*
* @param lng
* @param lat
* @return
*/
public static double transformlng(double lng, double lat) {
double ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng));
ret += (20.0 * Math.sin(6.0 * lng * pi) + 20.0 * Math.sin(2.0 * lng * pi)) * 2.0 / 3.0;
ret += (20.0 * Math.sin(lng * pi) + 40.0 * Math.sin(lng / 3.0 * pi)) * 2.0 / 3.0;
ret += (150.0 * Math.sin(lng / 12.0 * pi) + 300.0 * Math.sin(lng / 30.0 * pi)) * 2.0 / 3.0;
return ret;
}

/**
* 判断是否在国内,不在国内不做偏移
*
* @param lng
* @param lat
* @return
*/
public static boolean out_of_china(double lng, double lat) {
if (lng < 72.004 || lng > 137.8347) {
return true;
} else if (lat < 0.8293 || lat > 55.8271) {
return true;
}
return false;
}
}
55 changes: 50 additions & 5 deletions app/src/main/java/name/caiyao/fakegps/MainActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@
import android.location.LocationManager;
import android.net.Uri;
import android.os.Bundle;
import android.provider.Settings;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
Expand All @@ -37,12 +39,14 @@ public class MainActivity extends AppCompatActivity implements AMap.OnMapClickLi
private AMap aMap;
private LatLng latLng;
private SharedPreferences sharedPreferences;
private long mExitTime = 0;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sharedPreferences = getSharedPreferences("locationHistory", Context.MODE_PRIVATE);

Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);

Expand All @@ -52,7 +56,14 @@ protected void onCreate(Bundle savedInstanceState) {
aMap = mv.getMap();
double lat = Double.parseDouble(sharedPreferences.getString("lat", "0.0"));
double lon = Double.parseDouble(sharedPreferences.getString("lon", "0.0"));
if (lat != 0.0 && lon != 0.0){
if (lat != 0.0 && lon != 0.0) {
latLng = new LatLng(lat, lon);
aMap.clear();
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(latLng);
markerOptions.draggable(true);
markerOptions.title("经度:" + latLng.longitude + ",纬度:" + latLng.latitude);
aMap.addMarker(markerOptions);
aMap.moveCamera(CameraUpdateFactory.changeLatLng(new LatLng(lat, lon)));
aMap.moveCamera(CameraUpdateFactory.zoomTo(aMap.getMaxZoomLevel()));
}
Expand All @@ -79,11 +90,26 @@ protected void onResume() {
locationManager.requestLocationUpdates(mockProviderName, 0, 0, this);
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(this, "请打开模拟位置权限!", Toast.LENGTH_SHORT).show();
showDialog();
}
mv.onResume();
}

private void showDialog() {
new AlertDialog.Builder(this).setTitle("需要打开模拟位置").setMessage("是否跳转到开发者选项打开模拟位置").setPositiveButton("确认", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS);
startActivity(intent);
}
}).setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
}).show();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
Expand Down Expand Up @@ -113,20 +139,24 @@ public boolean onOptionsItemSelected(MenuItem item) {
android.location.Criteria.ACCURACY_FINE);
locationManager.setTestProviderEnabled(mockProviderName, true);
locationManager.requestLocationUpdates(mockProviderName, 0, 0, this);
startService(new Intent(MainActivity.this, MockGpsService.class).putExtra("action", MockGpsService.ACTION_START).putExtra("location", latLng.latitude + ":" + latLng.longitude));
double[] gpsLocation = GpsUtils.gcj02towgs84(latLng.longitude, latLng.latitude);
startService(new Intent(MainActivity.this, MockGpsService.class).putExtra("action", MockGpsService.ACTION_START).putExtra("location", gpsLocation[1] + ":" + gpsLocation[0]));
Toast.makeText(this, "位置模拟成功,重启需定位的应用以生效!", Toast.LENGTH_LONG).show();
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(this, "请打开模拟位置权限!", Toast.LENGTH_SHORT).show();
showDialog();
}
break;
case R.id.stop:
Toast.makeText(this, "位置模拟关闭,重启需定位的应用以生效!", Toast.LENGTH_LONG).show();
startService(new Intent(MainActivity.this, MockGpsService.class).putExtra("action", MockGpsService.ACTION_STOP));
break;
case R.id.search:
View view = LayoutInflater.from(this).inflate(R.layout.dialog_search, null, false);
final EditText et_key = (EditText) view.findViewById(R.id.key);
new AlertDialog.Builder(this).setView(view)
.setTitle("搜索位置")
.setMessage("只能搜索国内地点,如需定位国外请拖拽地图选取!定位到国外使用Google地图的需要翻墙!")
.setPositiveButton("搜索", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Expand Down Expand Up @@ -156,6 +186,22 @@ protected void onPause() {
mv.onPause();
}

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
if ((System.currentTimeMillis() - mExitTime) > 2000) {//
// 如果两次按键时间间隔大于2000毫秒,则不退出
Toast.makeText(this, "再按一次退出程序,停止模拟位置!", Toast.LENGTH_SHORT).show();
mExitTime = System.currentTimeMillis();// 更新mExitTime
} else {
System.exit(0);// 否则退出程序
}
return true;
}
return super.onKeyDown(keyCode, event);

}

private void search(final String key) {
PoiSearch.Query query = new PoiSearch.Query(key, null, null);
query.setPageSize(10);
Expand Down Expand Up @@ -215,7 +261,6 @@ public void onMapClick(LatLng latLng) {
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(latLng);
markerOptions.draggable(true);
Log.i("TAG", "经度:" + latLng.longitude + ",纬度:" + latLng.latitude);
markerOptions.title("经度:" + latLng.longitude + ",纬度:" + latLng.latitude);
aMap.addMarker(markerOptions);
this.latLng = latLng;
Expand Down
Loading