android 修改gps坐标,[原创] 改机 - 从源码着手任意修改GPS地理位置
改机 - 从源码着手任意修改GPS地理位置
需求:随意修改定位
android在改机过程中,经常会遇到随意修改位置GPS的需求。
修改GPS的方式有很多种:
xposed hook
MockLocation
修改源码
以上三种方式都能修改gps随意修改gps坐标,各有优缺点:xposed隐藏不好,容易被发现;MockLocation容易在开发者模式和gps provider被识别;改源码,编译麻烦,而且不一定有源码;前两种方式具有普适性,改源码费时费力,局限性比较强;
秉承明知山有虎,偏向虎上行的心态,尝试阅读以下android的源码,并且修改gps部分的代码;
具体原理:切断hal层和framework之间的通讯,模仿硬件向framework通知硬件信息
样例:android 8.0
1. gps jni callbackstruct GnssCallback : public IGnssCallback {
Return gnssLocationCb(
const android::hardware::gnss::V1_0::GnssLocation& location) override; // gps位置变化回调函数
Return gnssStatusCb(const IGnssCallback::GnssStatusValue status) override; // gps状态变化回调函数
Return gnssSvStatusCb(const IGnssCallback::GnssSvStatus& svStatus) override; // 卫星状态变化回调函数
Return gnssNmeaCb(int64_t timestamp, const android::hardware::hidl_string& nmea) override;
Return gnssSetCapabilitesCb(uint32_t capabilities) override;
Return gnssAcquireWakelockCb() override;
Return gnssReleaseWakelockCb() override;
Return gnssRequestTimeCb() override;
Return gnssSetSystemInfoCb(const IGnssCallback::GnssSystemInfo& info) override;
static GnssSvInfo sGnssSvList[static_cast(
android::hardware::gnss::V1_0::GnssMax::SVS_COUNT)];
static size_t sGnssSvListSize;
static const char* sNmeaString;
static size_t sNmeaStringLength;
};
// 省略......
Return GnssCallback::gnssLocationCbImpl(const T& location) {
JNIEnv* env = getJniEnv();
jobject jLocation = translateGnssLocation(env, location);
env->CallVoidMethod(mCallbacksObj,
method_reportLocation, // frameworks
boolToJbool(hasLatLong(location)),
jLocation);
checkAndClearExceptionFromCallback(env, __FUNCTION__);
env->DeleteLocalRef(jLocation);
return Void();
}
// 省略......
method_reportLocation = env->GetMethodID(clazz, "reportLocation",
"(ZLandroid/location/Location;)V");
GnssCallback的作用就是在gps模块位置、状态、精度等信息变化后,通知上层应用的回调函数类。
2. framework
可以发现,在gps硬件模块拿到新的位置时,通知framework调用java的函数是reportLocation, 源码如下:
/*
* @hasLatLong: 地理位置是否合法
* @loction: 地理位置
*/
private void reportLocation(boolean hasLatLong, Location location) {
if (location.hasSpeed()) {
mItarSpeedLimitExceeded = location.getSpeed() > ITAR_SPEED_LIMIT_METERS_PER_SECOND;
}
if (mItarSpeedLimitExceeded) {
Log.i(TAG, "Hal reported a speed in excess of ITAR limit." +
" GPS/GNSS Navigation output blocked.");
mGnssMetrics.logReceivedLocationStatus(false);
return;
}
if (VERBOSE) Log.v(TAG, "reportLocation " + location.toString());
synchronized (mLocation) {
mLocation = location;
// It would be nice to push the elapsed real-time timestamp
// further down the stack, but this is still useful
mLocation.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
mLocation.setExtras(mLocationExtras);
try {
mILocationManager.reportLocation(mLocation, false);
} catch (RemoteException e) {
Log.e(TAG, "RemoteException calling reportLocation");
}
}
mGnssMetrics.logReceivedLocationStatus(hasLatLong);
if (hasLatLong) {
if (location.hasAccuracy()) {
mGnssMetrics.logPositionAccuracyMeters(location.getAccuracy());
}
if (mTimeToFirstFix > 0) {
int timeBetweenFixes = (int) (SystemClock.elapsedRealtime() - mLastFixTime);
mGnssMetrics.logMissedReports(mFixInterval, timeBetweenFixes);
}
}
mLastFixTime = SystemClock.elapsedRealtime();
// report time to first fix
if (mTimeToFirstFix == 0 && hasLatLong) {
mTimeToFirstFix = (int)(mLastFixTime - mFixRequestTime);
if (DEBUG) Log.d(TAG, "TTFF: " + mTimeToFirstFix);
mGnssMetrics.logTimeToFirstFixMilliSecs(mTimeToFirstFix);
// notify status listeners
mListenerHelper.onFirstFix(mTimeToFirstFix);
}
if (mSingleShot) {
stopNavigating();
}
if (mStarted && mStatus != LocationProvider.AVAILABLE) {
// we want to time out if we do not receive a fix
// within the time out and we are requesting infrequent fixes
if (!hasCapability(GPS_CAPABILITY_SCHEDULING) && mFixInterval < NO_FIX_TIMEOUT) {
mAlarmManager.cancel(mTimeoutIntent);
}
// send an intent to notify that the GPS is receiving fixes.
Intent intent = new Intent(LocationManager.GPS_FIX_CHANGE_ACTION);
intent.putExtra(LocationManager.EXTRA_GPS_ENABLED, true);
mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
updateStatus(LocationProvider.AVAILABLE, mSvCount, mMeanCn0, mMaxCn0);
}
if (!hasCapability(GPS_CAPABILITY_SCHEDULING) && mStarted &&
mFixInterval > GPS_POLLING_THRESHOLD_INTERVAL) {
if (DEBUG) Log.d(TAG, "got fix, hibernating");
hibernate();
}
}
自此,刨除hal层,android系统就获取到了一个地理位置。原理了解后,就可以动手修改源码了。
3. 切断hal层调用
GnssLocationProvider.cpp
#include
// ....... 省略
Return GnssCallback::gnssLocationCbImpl(const T& location) {
// 定义一个系统开关,可以自由控制
char property[PROP_VALUE_MAX];
int len = __system_property_get("gps.location.custom", property);
if(len > 0) {
if(strcmp(property, "1") == 0) return Void();
}
// ...... 省略
}
4. 在framework中添加一个public函数
LocationManager.java
// ...... 省略
public void reportCustomLocation(Location location) {
mService.reportLocation(true, location);
}
5. 编译rommake update-api # 在LocationManager中添加了新的接口
make -j32 # 炫耀一下我32核的的机器
5. 在APK中使用
MainActivity.java
// ...... 省略
Button btn = findViewById(R.id.test_btn);
btn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
try {
Location l = new Location("gps");
l.setLatitude(41.055962);
l.setLongitude(110.307711);
l.setAccuracy(2.0f);
l.setTime(System.currentTimeMillis());
l.setElapsedRealtimeNanos(System.currentTimeMillis());
l.setAccuracy(1.0f);
locationManager.reportCustomLocation(l);
Location lo = locationManager.getLastKnownLocation(provider);
Log.d(TAG, lo.toString());
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
最后于 2020-6-29 11:04
被neocanable编辑
,原因: markdown 好像不太好用
android 修改gps坐标,[原创] 改机 - 从源码着手任意修改GPS地理位置相关推荐
- java 修改gps,改机 - 从源码着手任意修改GPS地理位置
改机 - 从源码着手任意修改GPS地理位置 需求:随意修改定位 android在改机过程中,经常会遇到随意修改位置GPS的需求. 修改GPS的方式有很多种: xposed hook MockLocat ...
- 不翻qiang搞定Android Studio Google库加载不下来的问题 打包生成apk android studio 3.2打灰机程序源码带详细注释
1.Google库加载不下来的问题 其实我们可以给dl.google.com设置个代理,然后库都能正常加载下来了.步骤如下: 打开站长工具网站,http://ping.chinaz.com/dl.go ...
- 【Android 安装包优化】WebP 应用 ( libwebp 源码下载 | Android.mk 和 Application.mk 构建脚本修改 | libwebp 函数库编译 )
文章目录 一. libwebp 源码下载 二. libwebp 源码编译脚本修改 三. libwebp 函数库编译 四.参考资料 一. libwebp 源码下载 Google 提供了一系列的 WebP ...
- Android源码中添加 修改应用
第一部分:添加一个新的应用 1. 在和系统相同版本的SDK目录下开发自己的android应用 2. 把开发的android工程放到源码的packages/apps/目录下 3. 在工程目录下添加And ...
- android 随手记 170多个示例demo源码
下载地址:http://pan.baidu.com/s/101PEN 2012-10-1513:03 2,098,836 AdXmpp(Openfire+asmack+spark) .zi ...
- 戴眼镜检测和识别3:Android实现戴眼镜检测和识别(含源码,可实时检测)
Android实现戴眼镜检测和识别(含源码,可实时检测) 目录 Android实现戴眼镜检测和识别(含源码,可实时检测) 1.戴眼镜检测和识别方法 2.戴眼镜人脸检测 3.戴眼镜识别模型训练 4.戴眼 ...
- Android图片爬虫,看妹纸神器项目源码,ListView单张图片查看
Android图片爬虫,看妹纸神器项目源码 刚自学完安卓,国庆7七天花了6天纯手写入门级app,从集成图片爬虫到整个项目结束真是一步一个坑. 整个项目没有用框架,都是手写纯属练手,项目中主要用到的技术 ...
- (仿微信Android)IM聊天+抢红包+直播+朋友圈源码发布了
(仿微信Android)IM聊天+抢红包+直播+朋友圈源码发布了 功能概览: IM聊天 单聊/群聊/聊天室--基于环信sdk 红包功能: 1.一对一红包 2.群红包(抢红包.答题红包.专属红包) 3. ...
- 神器如 dnSpy,无需源码也能修改 .NET 程序
dnSpy 是 0xd4d 开发的 .NET 程序调试神器. 说它是神器真的毫不为过!它能在完全没有源码的情况下即时调试程序,甚至还能修改程序!本文讲向大家介绍如何使用 dnSpy 修改 .NET 程 ...
- 【Android项目】本地FM收音机开发及源码简析
[Android项目]本地FM收音机开发及源码简析 目录 1.概述 2.收音机的基本原理 3.收音机其他信息 RDS功能 4.Android开发FM收音机源码解析 5.App层如何设计本地FM应用 6 ...
最新文章
- 阿里商业白皮书:每个企业都要变成一个数据公司
- VSFTP之不能登录
- 3.4 matlab用for语句实现循环结构
- android o 小米note 3,小米 Note 3 MIUI 10 安卓 8.0 内测开启
- C++实现AOE网中的关键路径算法(邻接表存储)
- 程序设计与算法----分治之归并排序
- javaScripct入门教程
- Silverlight3.0教程下载
- iphone上开发即时聊天工具
- 半部秘籍--分类、回归、集成与无监督
- 秀米排版 × ModStart,提升富文本排版效率
- swing 绝对布局 窗口事件 鼠标事件 键盘事件 上传头像流程
- 什么是软件维护?在软件已经交付使用后,为了改正错误或满足新需求而修改软件的过程。它有哪几种类型?
- npm(了解)+Babel转码器+模块化+webpack打包
- AGV调度:路径规划
- 情感识别相关数据集总结
- 前端知识总结之基础知识
- OS-实现一个RR调度算法
- Unity使用AssetDatabase.CreateAsset报错:Couldn't create asset file!
- IT类电子图书下载站点合集