第二十期 在Android中修改GPS定位数据的完整方案《手机就是开发板》

您所在的位置:网站首页 安卓手机修改软件定位 第二十期 在Android中修改GPS定位数据的完整方案《手机就是开发板》

第二十期 在Android中修改GPS定位数据的完整方案《手机就是开发板》

#第二十期 在Android中修改GPS定位数据的完整方案《手机就是开发板》| 来源: 网络整理| 查看: 265

https://blog.csdn.net/aggresss/article/details/54323034

        现在很多的应用都是基于位置服务的,而且把位置服务作为重要的参考标准,其实这是很不安全的,位置信息的数据未经过任何加密,而且是从我们的手机中发送出去的,所以是可以修改的。这一期我们来探讨一下如何修改手机中的定位信息。太基础的原理我就不多说了,可以参考前几期文章。         先整理一下思路,Android在开发者模式下有一个"允许模拟位置选项",它是location service加载 MOCK location provider 实现的,通过这种线程注入的方式修改GPS信息是hacker们最喜欢的方式,但现在很多应用已经可以检测到这种注入方式而被屏蔽掉,也就是说如果我们只在APP层面上想解决方法总是有被检测出来的可能。那我们就得把问题往深了想,通过修改最底层的GPS数据来欺骗APP,在Framework层面上没有任何修改迹象,这样基于APP层面的检测机制就拿我们没有任何办法。         思路确定后我们来探讨实践路线,首先我们要建立一个管道,让我们想要定位的GPS数据提交到Android操作系统的最底层,也就是Linux Kernel层面;然后我们要修改 GPS的 location report 机制,让它从内核中提取到我们的数据,然后逐层上报到APP层。有点明修栈道暗度陈仓的感觉。         总体来说分成两部实现:1.建立到系统内核的数据管道;2.修改GPS上报机制。         这次实验使用的是闲置的小米3W手机,编译源码采用CyanogenMod-13,具体的编译环境搭建和编译方法请参考前几期文章。         因为Android系统从内核态到APP层要经过很多的层次,所以对于建立数据管道的步骤比较繁琐,我这里分成了5个步骤,对应5个层面来实现,每一步分别对应Android的 Kernel driver,HAL,JNI,Framework,Application。所有的代码我都已上传github中https://github.com/aggresss/PHDemo/  这一期的代码在VirtualPosition 目录下。 下面描述一下实践步骤: =============分割线1============== 第一步,修改Kernel driver 进入 kernel/xiaomi/cancro/drivers 目录下,新建vp.h文件

#ifndef _VP_ANDROID_H_   #define _VP_ANDROID_H_      #include   #include      #define VP_DEVICE_NODE_NAME  "vp"   #define VP_DEVICE_FILE_NAME  "vp"   #define VP_DEVICE_PROC_NAME  "vp"   #define VP_DEVICE_CLASS_NAME "vp"      typedef struct {     int toggle;     double virtual_latitude;     double virtual_longitude; } VirtualPosition;         struct vp_android_dev {       int lamp;     VirtualPosition val;     struct semaphore sem;       struct cdev dev;   };     #endif  

新建vp.c文件

/******************************************* *include file and define functions *******************************************/ #include   #include   #include   #include   #include   #include   #include      #include "vp.h"      /*主设备和从设备号变量*/   static int vp_major = 0;   static int vp_minor = 0;      /*设备类别和设备变量*/   static struct class* vp_class = NULL;   static struct vp_android_dev* vp_dev = NULL;      /*传统的设备文件操作方法*/   static int vp_open(struct inode* inode, struct file* filp);   static int vp_release(struct inode* inode, struct file* filp);   static ssize_t vp_read(struct file* filp, char __user *buf, size_t count, loff_t* f_pos);   static ssize_t vp_write(struct file* filp, const char __user *buf, size_t count, loff_t* f_pos);      /*设备文件操作方法表*/   static struct file_operations vp_fops = {       .owner = THIS_MODULE,       .open = vp_open,       .release = vp_release,       .read = vp_read,       .write = vp_write,    };      /*访问设置属性方法*/   static ssize_t vp_lamp_show(struct device* dev, struct device_attribute* attr,  char* buf);   static ssize_t vp_lamp_store(struct device* dev, struct device_attribute* attr, const char* buf, size_t count);      /*定义设备属性*/   static DEVICE_ATTR(val, S_IRUGO | S_IWUSR, vp_lamp_show, vp_lamp_store);     /******************************************* *define traditional file access  *******************************************/ /*打开设备方法*/   static int vp_open(struct inode* inode, struct file* filp) {       struct vp_android_dev* dev;                      /*将自定义设备结构体保存在文件指针的私有数据域中,以便访问设备时拿来用*/       dev = container_of(inode->i_cdev, struct vp_android_dev, dev);       filp->private_data = dev;              return 0;   }      /*设备文件释放时调用,空实现*/   static int vp_release(struct inode* inode, struct file* filp) {       return 0;   }      /*读取设备的寄存器val的值*/   static ssize_t vp_read(struct file* filp, char __user *buf, size_t count, loff_t* f_pos) {       ssize_t err = 0;       struct vp_android_dev* dev = filp->private_data;                  /*同步访问*/       if(down_interruptible(&(dev->sem))) {           return -ERESTARTSYS;       }          if(count < sizeof(dev->val)) {           goto out;       }                  /*将寄存器val的值拷贝到用户提供的缓冲区*/       if(copy_to_user(buf, &(dev->val), sizeof(dev->val))) {           err = -EFAULT;           goto out;       }          err = sizeof(dev->val);      out:       up(&(dev->sem));       return err;   }      /*写设备的寄存器值val*/   static ssize_t vp_write(struct file* filp, const char __user *buf, size_t count, loff_t* f_pos) {       struct vp_android_dev* dev = filp->private_data;       ssize_t err = 0;                  /*同步访问*/       if(down_interruptible(&(dev->sem))) {           return -ERESTARTSYS;               }                  if(count != sizeof(dev->val)) {           goto out;               }                  /*将用户提供的缓冲区的值写到设备寄存器去*/       if(copy_from_user(&(dev->val), buf, count)) {           err = -EFAULT;           goto out;       }          err = sizeof(dev->val);      out:       up(&(dev->sem));       return err;   }       /******************************************* *define devfs access *******************************************/ /*读取寄存器lamp的值到缓冲区buf中,内部使用*/   static ssize_t __vp_get_lamp(struct vp_android_dev* dev, char* buf) {       int lamp = 0;                  /*同步访问*/       if(down_interruptible(&(dev->sem))) {                           return -ERESTARTSYS;               }                  lamp = dev->lamp;               up(&(dev->sem));                  return snprintf(buf, PAGE_SIZE, "%d\n", lamp);   }      /*把缓冲区buf的值写到设备寄存器lamp中去,内部使用*/   static ssize_t __vp_set_lamp(struct vp_android_dev* dev, const char* buf, size_t count) {       int lamp = 0;                  /*将字符串转换成数字*/               lamp = simple_strtol(buf, NULL, 10);                  /*同步访问*/               if(down_interruptible(&(dev->sem))) {                           return -ERESTARTSYS;               }                  dev->lamp = lamp;               up(&(dev->sem));          return count;   }      /*读取设备属性lamp*/   static ssize_t vp_lamp_show(struct device* dev, struct device_attribute* attr, char* buf) {       struct vp_android_dev* hdev = (struct vp_android_dev*)dev_get_drvdata(dev);                  return __vp_get_lamp(hdev, buf);   }      /*写设备属性lamp*/   static ssize_t vp_lamp_store(struct device* dev, struct device_attribute* attr, const char* buf, size_t count) {        struct vp_android_dev* hdev = (struct vp_android_dev*)dev_get_drvdata(dev);                return __vp_set_lamp(hdev, buf, count);   }       /******************************************* *define proc access *******************************************/ /*读取设备寄存器lamp的值,保存在page缓冲区中*/   static ssize_t vp_proc_read(char* page, char** start, off_t off, int count, int* eof, void* data) {       if(off > 0) {           *eof = 1;           return 0;       }          return __vp_get_lamp(vp_dev, page);   }      /*把缓冲区的值buff保存到设备寄存器lamp中去*/   static ssize_t vp_proc_write(struct file* filp, const char __user *buff, unsigned long len, void* data) {       int err = 0;       char* page = NULL;          if(len > PAGE_SIZE) {           printk(KERN_ALERT"The buff is too large: %lu.\n", len);           return -EFAULT;       }          page = (char*)__get_free_page(GFP_KERNEL);       if(!page) {                           printk(KERN_ALERT"Failed to alloc page.\n");           return -ENOMEM;       }                  /*先把用户提供的缓冲区值拷贝到内核缓冲区中去*/       if(copy_from_user(page, buff, len)) {           printk(KERN_ALERT"Failed to copy buff from user.\n");                           err = -EFAULT;           goto out;       }          err = __vp_set_lamp(vp_dev, page, len);      out:       free_page((unsigned long)page);       return err;   }      /*创建/proc/vp文件*/   static void vp_create_proc(void) { struct proc_dir_entry *entry; entry = create_proc_entry(VP_DEVICE_PROC_NAME, 0, NULL); if(entry) { entry->read_proc = vp_proc_read; entry->write_proc = vp_proc_write; } }      /*删除/proc/vp文件*/   static void vp_remove_proc(void) {       remove_proc_entry(VP_DEVICE_PROC_NAME, NULL);   }       /******************************************* *define load and remove function *******************************************/ /*初始化设备*/   static int  __vp_setup_dev(struct vp_android_dev* dev) {       int err;       dev_t devno = MKDEV(vp_major, vp_minor);          memset(dev, 0, sizeof(struct vp_android_dev));          cdev_init(&(dev->dev), &vp_fops);       dev->dev.owner = THIS_MODULE;       dev->dev.ops = &vp_fops;                  /*注册字符设备*/       err = cdev_add(&(dev->dev),devno, 1);       if(err) {           return err;       }                  /*初始化信号量和寄存器lamp, val的值*/       sema_init(&(dev->sem), 1);       dev->lamp = 7777;       dev->val.toggle = 1;       dev->val.virtual_latitude = 45.104108;      dev->val.virtual_longitude = 130.816878;        return 0;   }      /*模块加载方法*/   static int __init vp_init(void){        int err = -1;       dev_t dev = 0;       struct device* temp = NULL;          printk(KERN_ALERT"Initializing vp device.\n");                  /*动态分配主设备和从设备号*/       err = alloc_chrdev_region(&dev, 0, 1, VP_DEVICE_NODE_NAME);       if(err < 0) {           printk(KERN_ALERT"Failed to alloc char dev region.\n");           goto fail;       }          vp_major = MAJOR(dev);       vp_minor = MINOR(dev);                  /*分配helo设备结构体变量*/       vp_dev = kmalloc(sizeof(struct vp_android_dev), GFP_KERNEL);       if(!vp_dev) {           err = -ENOMEM;           printk(KERN_ALERT"Failed to alloc vp_dev.\n");           goto unregister;       }                  /*初始化设备*/       err = __vp_setup_dev(vp_dev);       if(err) {           printk(KERN_ALERT"Failed to setup dev: %d.\n", err);           goto cleanup;       }                  /*在/sys/class/目录下创建设备类别目录vp*/       vp_class = class_create(THIS_MODULE, VP_DEVICE_CLASS_NAME);       if(IS_ERR(vp_class)) {           err = PTR_ERR(vp_class);           printk(KERN_ALERT"Failed to create vp class.\n");           goto destroy_cdev;       }                  /*在/dev/目录和/sys/class/vp目录下分别创建设备文件vp*/       temp = device_create(vp_class, NULL, dev, "%s", VP_DEVICE_FILE_NAME);       if(IS_ERR(temp)) {           err = PTR_ERR(temp);           printk(KERN_ALERT"Failed to create vp device.");           goto destroy_class;       }                  /*在/sys/class/vp/vp目录下创建属性文件val*/       err = device_create_file(temp, &dev_attr_val);       if(err < 0) {           printk(KERN_ALERT"Failed to create attribute val.");                           goto destroy_device;       }          dev_set_drvdata(temp, vp_dev);                  /*创建/proc/vp文件*/       vp_create_proc();          printk(KERN_ALERT"Succedded to initialize vp device.\n");       return 0;      destroy_device:       device_destroy(vp_class, dev);      destroy_class:       class_destroy(vp_class);      destroy_cdev:       cdev_del(&(vp_dev->dev));      cleanup:       kfree(vp_dev);      unregister:       unregister_chrdev_region(MKDEV(vp_major, vp_minor), 1);      fail:       return err;   }      /*模块卸载方法*/   static void __exit vp_exit(void) {       dev_t devno = MKDEV(vp_major, vp_minor);          printk(KERN_ALERT"Destroy vp device.\n");                  /*删除/proc/vp文件*/       vp_remove_proc();                  /*销毁设备类别和设备*/       if(vp_class) {           device_destroy(vp_class, MKDEV(vp_major, vp_minor));           class_destroy(vp_class);       }                  /*删除字符设备和释放设备内存*/       if(vp_dev) {           cdev_del(&(vp_dev->dev));           kfree(vp_dev);       }                  /*释放设备号*/       unregister_chrdev_region(devno, 1);   }      MODULE_LICENSE("GPL");   MODULE_DESCRIPTION("Virtualposition Driver");      module_init(vp_init);   module_exit(vp_exit);  

添加 Kconfig 文件

config VP            tristate "Virtual Position Driver"            default n            help            This is the virtual position driver.

添加 Makefile 文件

obj-$(CONFIG_VP) += vp.o

修改 drivers/Kconfig 文件 在menu "Device Drivers"和endmenu之间添加一行:

source "drivers/vp/Kconfig"  

修改drivers/Makefile文件,添加一行:

obj-$(CONFIG_HELLO) += vp/  

修改 arch/arm/configs目录下的cyanogen_cancro_defconfig 文件,在文件末尾加入

# CONFIG_VP CONFIG_VP=y

=============分割线2============== 第二步,修改HAL 进入 ./hardware/libhardware/include/hardware 目录,新建 vp.h 文件

#ifndef ANDROID_VP_INTERFACE_H   #define ANDROID_VP_INTERFACE_H   #include   __BEGIN_DECLS      /*定义模块ID*/   #define VP_HARDWARE_MODULE_ID "vp"       //typedef enum{false, true} bool;     /*define virtual position structrue*/ typedef struct {     int toggle;     double virtual_latitude;     double virtual_longitude; } VirtualPosition;     /*硬件模块结构体*/   struct vp_module_t {       struct hw_module_t common;   };      /*硬件接口结构体*/   struct vp_device_t {       struct hw_device_t common;       int fd;       int (*set_val)(struct vp_device_t* dev, VirtualPosition val);       int (*get_val)(struct vp_device_t* dev, VirtualPosition* val);   };      __END_DECLS      #endif  

进入到 hardware/libhardware/modules 目录,新建vp目录,并添加vp.c文件

#define LOG_TAG "VpStub"      #include   #include   #include   #include   #include   #include      #define DEVICE_NAME "/dev/vp"   #define MODULE_NAME "Vp"   #define MODULE_AUTHOR "[email protected]"      /*设备打开和关闭接口*/   static int vp_device_open(const struct hw_module_t* module, const char* name, struct hw_device_t** device);   static int vp_device_close(struct hw_device_t* device);      /*设备访问接口*/   static int vp_set_val(struct vp_device_t* dev, VirtualPosition val);   static int vp_get_val(struct vp_device_t* dev, VirtualPosition* val);      /*模块方法表*/   static struct hw_module_methods_t vp_module_methods = {       open: vp_device_open   };      /*模块实例变量*/   struct vp_module_t HAL_MODULE_INFO_SYM = {       common: {           tag: HARDWARE_MODULE_TAG,           version_major: 1,           version_minor: 0,           id: VP_HARDWARE_MODULE_ID,           name: MODULE_NAME,           author: MODULE_AUTHOR,           methods: &vp_module_methods,       }   };           static int vp_device_open(const struct hw_module_t* module, const char* name, struct hw_device_t** device) {       struct vp_device_t* dev;dev = (struct vp_device_t*)malloc(sizeof(struct vp_device_t));              if(!dev) {           ALOGE("Vp Stub: failed to alloc space");           return -EFAULT;       }          memset(dev, 0, sizeof(struct vp_device_t));       dev->common.tag = HARDWARE_DEVICE_TAG;       dev->common.version = 0;       dev->common.module = (hw_module_t*)module;       dev->common.close = vp_device_close;       dev->set_val = vp_set_val;dev->get_val = vp_get_val;          if((dev->fd = open(DEVICE_NAME, O_RDWR)) == -1) {           ALOGE("Vp Stub: failed to open /dev/vp -- %s.", strerror(errno));free(dev);           return -EFAULT;       }          *device = &(dev->common);       ALOGI("Vp Stub: open /dev/vp successfully.");          return 0;   }       static int vp_device_close(struct hw_device_t* device) {       struct vp_device_t* vp_device = (struct vp_device_t*)device;          if(vp_device) {           close(vp_device->fd);           free(vp_device);       }              return 0;   }      static int vp_set_val(struct vp_device_t* dev, VirtualPosition val) {       ALOGI("Vp Stub: set value %d to device.", val);          write(dev->fd, &val, sizeof(val));          return 0;   }      static int vp_get_val(struct vp_device_t* dev, VirtualPosition* val) {       if(!val) {           ALOGE("Vp Stub: error val pointer");           return -EFAULT;       }          read(dev->fd, val, sizeof(*val));          ALOGI("Vp Stub: get value %d from device", *val);          return 0;   }  

继续在vp目录下新建Android.mk文件:

LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE_TAGS := optional LOCAL_PRELINK_MODULE := false LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw LOCAL_SHARED_LIBRARIES := liblog LOCAL_SRC_FILES := vp.c LOCAL_MODULE := vp.default include $(BUILD_SHARED_LIBRARY)

=============分割线3============== 第三步,修改JNI 进入 frameworks/base/services/core/jni 目录,新建com_android_server_VirtualPositionService.cpp文件

#define LOG_TAG "VirtualPositionService"   #include "jni.h"   #include "JNIHelp.h"   #include "android_runtime/AndroidRuntime.h"   #include   #include   #include   #include   #include       namespace android   {                VirtualPosition virtual_position = {1, 0.0, 0.0};     /*在硬件抽象层中定义的硬件访问结构体,参考*/           struct vp_device_t* vp_device = NULL;       /*通过硬件抽象层定义的硬件访问接口设置硬件寄存器val的值*/           static void vp_setVal() {           ALOGI("VirtualPosition JNI: set value to device.");           if(!vp_device) {               ALOGI("VirtualPosition JNI: device is not open.");               return;           }                      vp_device->set_val(vp_device, virtual_position);       }           /*通过硬件抽象层定义的硬件访问接口读取硬件寄存器val的值*/       static void vp_getVal() {           if(!vp_device) {               ALOGI("VirtualPosition JNI: device is not open.");           }           vp_device->get_val(vp_device, &virtual_position);                      ALOGI("VirtualPosition JNI: get value from device.");       }           /*通过硬件抽象层定义的硬件模块打开接口打开硬件设备*/       static inline int vp_device_open(const hw_module_t* module, struct vp_device_t** device) {           return module->methods->open(module, VP_HARDWARE_MODULE_ID, (struct hw_device_t**)device);       }           /*通过硬件模块ID来加载指定的硬件抽象层模块并打开硬件*/       static jboolean vp_init(JNIEnv* env, jclass clazz) {           vp_module_t* module;                      ALOGI("VirtualPosition JNI: initializing......");           if(hw_get_module(VP_HARDWARE_MODULE_ID, (const struct hw_module_t**)&module) == 0) {               ALOGI("VirtualPosition JNI: vp Stub found.");               if(vp_device_open(&(module->common), &vp_device) == 0) {                   ALOGI("VirtualPosition JNI: vp device is open.");                   return 0;               }               ALOGE("VirtualPosition JNI: failed to open vp device.");               return -1;           }           ALOGE("VirtualPosition JNI: failed to get vp stub module.");           return -1;             }            static void android_server_VirtualPositionService_set_virtual_toggle(JNIEnv* env, jclass clazz, jint tog)     {         virtual_position.toggle = tog;         vp_setVal();     }         static jint android_server_VirtualPositionService_get_virtual_toggle(JNIEnv* env, jclass clazz)     {         vp_getVal();         return virtual_position.toggle;     }         static void android_server_VirtualPositionService_set_virtual_latitude(JNIEnv* env, jclass clazz, jdouble vlat)     {         virtual_position.virtual_latitude = vlat;         vp_setVal();     }         static jdouble android_server_VirtualPositionService_get_virtual_latitude(JNIEnv* env, jclass clazz)     {         vp_getVal();         return virtual_position.virtual_latitude;     }         static void android_server_VirtualPositionService_set_virtual_longitude(JNIEnv* env, jclass clazz, jdouble vlon)     {         virtual_position.virtual_longitude = vlon;         vp_setVal();     }         static jdouble android_server_VirtualPositionService_get_virtual_longitude(JNIEnv* env, jclass clazz)     {         vp_getVal();         return virtual_position.virtual_longitude;     }                 /*JNI方法表*/       static const JNINativeMethod method_table[] = {           {"init_native",             "()Z",              (void*)vp_init},           {"native_set_virtual_toggle",             "(I)V",             (void*)android_server_VirtualPositionService_set_virtual_toggle},         {"native_get_virtual_toggle",             "()I",             (void*)android_server_VirtualPositionService_get_virtual_toggle},         {"native_set_virtual_latitude",             "(D)V",             (void*)android_server_VirtualPositionService_set_virtual_latitude},         {"native_get_virtual_latitude",             "()D",             (void*)android_server_VirtualPositionService_get_virtual_latitude},         {"native_set_virtual_longitude",             "(D)V",             (void*)android_server_VirtualPositionService_set_virtual_longitude},         {"native_get_virtual_longitude",             "()D",             (void*)android_server_VirtualPositionService_get_virtual_longitude},         };           /*注册JNI方法*/       int register_android_server_VirtualPositionService(JNIEnv *env) {               return jniRegisterNativeMethods(env, "com/android/server/VirtualPositionService", method_table, NELEM(method_table));       }   };  

修改同目录下的onload.cpp文件,首先在namespace android增加com_android_server_VirtualPositionService函数声明:

namespace android {          ..............................................................................................          int register_android_server_VirtualPositionService(JNIEnv *env);          };   在JNI_onLoad增加register_android_server_VirtualPositionService函数调用: extern "C" jint JNI_onLoad(JavaVM* vm, void* reserved)      {       .................................................................................................       register_android_server_VirtualPositionService(env);       .................................................................................................      }  

修改同目录下的Android.mk文件,在LOCAL_SRC_FILES变量中增加一行:

LOCAL_SRC_FILES:= \         com_android_server_AlarmManagerService.cpp \         com_android_server_BatteryService.cpp \         com_android_server_InputManager.cpp \         com_android_server_LightsService.cpp \         com_android_server_PowerManagerService.cpp \         com_android_server_SystemServer.cpp \         com_android_server_UsbService.cpp \         com_android_server_VibratorService.cpp \         com_android_server_location_GpsLocationProvider.cpp \         com_android_server_VirtualPositionService.cpp \        onload.cpp  

=============分割线4============== 第四步,修改Framework 进入到frameworks/base/core/java/android/os目录,新增VirtualPositionService.aidl接口定义文件

package android.os;     interface IVirtualPositionService {     void setVirtualToggle(int tog);     int getVirtualToggle();     void setVirtualLatitude(double vlat);     double getVirtualLatitude();     void setVirtualLongitude(double vlon);     double getVirtualLongitude(); }

然后进入 frameworks/base目录,打开Android.mk文件,修改LOCAL_SRC_FILES变量的值,增加IVirtualPosition.aidl源文件:

LOCAL_SRC_FILES += / .................................................................... core/java/android/os/IVibratorService.aidl / core/java/android/os/IVirtualPosition.aidl / core/java/android/service/urlrenderer/IUrlRendererService.aidl / .....................................................................

进入到frameworks/base/services/java/com/android/server目录,新增VirtualPositionService.java文件

package com.android.server;   import android.content.Context;   import android.os.IVirtualPositionService;   import android.util.Slog;       public class VirtualPositionService extends IVirtualPositionService.Stub {       private static final String TAG = "VirtualPositionService";       VirtualPositionService() {           init_native();       }       public void setVirtualToggle(int tog) {         native_set_virtual_toggle(tog);     }         public int getVirtualToggle(){         return native_get_virtual_toggle();     }         public void setVirtualLatitude(double vlat) {         native_set_virtual_latitude(vlat);     }         public double getVirtualLatitude(){         return native_get_virtual_latitude();     }         public void setVirtualLongitude(double vlon) {         native_set_virtual_longitude(vlon);     }         public double getVirtualLongitude() {         return native_get_virtual_longitude();     }          private static native boolean init_native();     private static native void native_set_virtual_toggle(int tog);     private static native int native_get_virtual_toggle();     private static native void native_set_virtual_latitude(double vlat);     private static native double native_get_virtual_latitude();     private static native void native_set_virtual_longitude(double vlon);     private static native double native_get_virtual_longitude();     };  

修改同目录的SystemServer.java文件,在ServerThread::run函数中增加加载VirtualPositionService的代码:

@Override public void run() { .................................................................................... try { Slog.i(TAG, "DiskStats Service"); ServiceManager.addService("diskstats", new DiskStatsService(context)); } catch (Throwable e) { Slog.e(TAG, "Failure starting DiskStats Service", e); } try { Slog.i(TAG, "VirtualPosition Service"); ServiceManager.addService("virtualposition", new VirtualPositionService()); } catch (Throwable e) { Slog.e(TAG, "Failure starting VirtualPosition Service", e); } ...................................................................................... } 

然后需要修改sepolicy文件,具体的文件在github上,请下载使用。

=============分割线5============== 第五步,修改application APP的文件比较多,请到github上下载,这里只贴具体的逻辑代码:

package com.example.phdemo.myapplication;     import android.os.RemoteException; import android.app.Activity; import android.os.ServiceManager; import android.os.Bundle; import android.widget.CompoundButton; import android.os.IVirtualPositionService; import android.os.RemoteException; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; import android.widget.ToggleButton; import android.widget.CompoundButton.OnCheckedChangeListener;     public class MainActivity extends Activity implements View.OnClickListener {         private final static String LOG_TAG = "com.example.phdemo.virtualposition";         private IVirtualPositionService virtualpositionService = null; private ToggleButton toggleButton = null; private EditText altitudeValueText = null;     private EditText longitudeValueText = null;     private Button getButton = null;     private Button setButton = null;     private Button clearButton = null;         /** Called when the activity is first created. */     @Override     public void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.activity_main);             virtualpositionService = IVirtualPositionService.Stub.asInterface(                 ServiceManager.getService("virtualposition"));             toggleButton=(ToggleButton)findViewById(R.id.toggleButton); altitudeValueText = (EditText)findViewById(R.id.altitude_value); longitudeValueText = (EditText)findViewById(R.id.longitude_value);         getButton = (Button)findViewById(R.id.button_get);         setButton = (Button)findViewById(R.id.button_set);         clearButton = (Button)findViewById(R.id.button_clear);                  getButton.setOnClickListener(this);         setButton.setOnClickListener(this);         clearButton.setOnClickListener(this);             try{          int val_tog = virtualpositionService.getVirtualToggle();             if(val_tog == 1){                 toggleButton.setChecked(true);             }else{                 toggleButton.setChecked(false);             }         } catch (Exception e) {}             toggleButton.setOnCheckedChangeListener(new OnCheckedChangeListener(){ public void onCheckedChanged(CompoundButton buttonView,boolean isChecked) { toggleButton.setChecked(isChecked); try{                     virtualpositionService.setVirtualToggle(isChecked?1:0);                 }catch(Exception e){} } });         Log.i(LOG_TAG, "VirtualPosition Activity Created");     }         @Override     public void onClick(View v) {         if(v.equals(getButton)) {             try {                 double val_altitude = virtualpositionService.getVirtualLatitude();                 String text_altitude = String.valueOf(val_altitude);                 altitudeValueText.setText(text_altitude); double val_longitude = virtualpositionService.getVirtualLongitude();                 String text_longitude = String.valueOf(val_longitude);                 longitudeValueText.setText(text_longitude); int val_tog = virtualpositionService.getVirtualToggle();                 if(val_tog == 1){                     toggleButton.setChecked(true);                 }else{                     toggleButton.setChecked(false);                 }             } catch (Exception e) {                 Log.e(LOG_TAG, "Remote Exception while reading value from GpsLocationProvider.");             }         }         else if(v.equals(setButton)) {             try {                 String text_altitude = altitudeValueText.getText().toString(); String text_longitude = longitudeValueText.getText().toString();                 double val_altitude = Double.parseDouble(text_altitude); double val_longitude = Double.parseDouble(text_longitude);                 virtualpositionService.setVirtualLatitude(val_altitude); virtualpositionService.setVirtualLongitude(val_longitude);             } catch (Exception e) {                 Log.e(LOG_TAG, "Remote Exception while writing value to GpsLocationProvider.");             }         }         else if(v.equals(clearButton)) {             String text = "";             altitudeValueText.setText(text); longitudeValueText.setText(text);         }     } }

=============分割线6============== 最后一步,在JNI层面修改location report 机制。 进入 frameworks/base/services/core/jni 目录,修改com_android_server_location_GpsLocationProvider.cpp文件: 在全局变量部分加入

// add by aggresss static int vp_fd = open("/dev/vp", O_RDWR);  static VirtualPosition vp_val;

修改location_callback函数:

static void location_callback(GpsLocation* location) {     JNIEnv* env = AndroidRuntime::getJNIEnv();     //add by aggresss     read(vp_fd, &vp_val, sizeof(VirtualPosition));     if(vp_val.toggle  == 1){     env->CallVoidMethod(mCallbacksObj, method_reportLocation, location->flags,             (jdouble)vp_val.virtual_latitude, (jdouble)vp_val.virtual_longitude,             (jdouble)location->altitude,             (jfloat)location->speed, (jfloat)location->bearing,             (jfloat)location->accuracy, (jlong)location->timestamp);     checkAndClearExceptionFromCallback(env, __FUNCTION__);     }     else{     env->CallVoidMethod(mCallbacksObj, method_reportLocation, location->flags,             (jdouble)location->latitude, (jdouble)location->longitude,             (jdouble)location->altitude,             (jfloat)location->speed, (jfloat)location->bearing,             (jfloat)location->accuracy, (jlong)location->timestamp);     checkAndClearExceptionFromCallback(env, __FUNCTION__);     } }

=============我是完成的分割线============== 完成后,重新编译固件,开机后启动VirtualPosition的APP,设置你想要的坐标,想在哪就在哪了。                   



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3