Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

作者您好,关于安卓11 的适配问题 #28

Open
1173859245 opened this issue Jan 22, 2021 · 11 comments
Open

作者您好,关于安卓11 的适配问题 #28

1173859245 opened this issue Jan 22, 2021 · 11 comments

Comments

@1173859245
Copy link

您好,安卓11更新导致定位失效,如果你有时间的话可以,能解决下么,如果不难适配我可以有偿解决,因为我一直再用I人事的软件打卡,小公司的,手机更新后就不能用了

@ms1728
Copy link

ms1728 commented Feb 20, 2021

我拷了源码自己适配了下安卓11,我自己三星S10可以用,你可以下来试试
PS:默认打开授权的是访问媒体文件,需要退出应用,先单独进应用程序信息里重新设置权限(存储权限->允许管理所有文件),要不然会闪退
链接: https://pan.baidu.com/s/1Wz_94NuAaO2wpk2wjRkASw 提取码: b5dj

@1173859245
Copy link
Author

能发下源码么。因为我现在没安卓11 的测试机子,测试难

@1173859245
Copy link
Author

安卓 11 的log 我看了是:java.lang.IllegalArgumentException: gps provider is not a test provider
我开始以为是11 的后台位置服务权限的问题,加了过后还是一样,应该是更新了什么API方法,但是不知道怎么修改

@ms1728
Copy link

ms1728 commented Mar 1, 2021

安卓 11 的log 我看了是:java.lang.IllegalArgumentException: gps provider is not a test provider
我开始以为是11 的后台位置服务权限的问题,加了过后还是一样,应该是更新了什么API方法,但是不知道怎么修改

com\example\service\MockGpsService类的locationManager.addTestProvider这个调用方法最后两个参数改成Criteria.POWER_LOW, Criteria.ACCURACY_FINE应该可以

@ms1728
Copy link

ms1728 commented Mar 1, 2021

能发下源码么。因为我现在没安卓11 的测试机子,测试难

链接: https://pan.baidu.com/s/1YB_23dkSM1F0usirtbDULQ 提取码: jqyc
这是我改动后的源码,本地没法用git克隆,这个我重新替换百度地图的API包,可能多了些没用的功能,比较大,其他改动就一个存储权限和上面test provider的一个改动吧

@wjbd
Copy link

wjbd commented Apr 13, 2021

能发下源码么。因为我现在没安卓11 的测试机子,测试难

链接: https://pan.baidu.com/s/1YB_23dkSM1F0usirtbDULQ 提取码: jqyc
这是我改动后的源码,本地没法用git克隆,这个我重新替换百度地图的API包,可能多了些没用的功能,比较大,其他改动就一个存储权限和上面test provider的一个改动吧

大佬,我自己写了一个简易版的MockGps,把你的修改后的代码MockGpsService给模仿下来了,但是自己写的为什么不能成功修改定位呢,有没有什么特别需要注意的点,还望赐教

@wjbd
Copy link

wjbd commented Apr 13, 2021

代码如下:
`
public class MockGPSService extends Service {
private LocationManager locationManager;
//使用HandlerThread不断发送虚拟定位数据
private HandlerThread handlerThread;
private Handler handler;
private boolean isStop = true;

private FloatWindow floatWindow;
private boolean isFloatWindowStart = false;

@Nullable
@Override
public IBinder onBind(Intent intent) {
    return null;
}

@Override
public void onCreate() {
    super.onCreate();
    locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
    removeNetworkTestProvider();
    removeGPSTestProvider();
    setNetworkTestProvider();
    setGPSTestProvider();
    handlerThread = new HandlerThread(UUID.randomUUID().toString(), -2);
    handlerThread.start();
    handler = new Handler(handlerThread.getLooper()) {
        public void handleMessage(Message msg) {
            try {
                Thread.sleep(128);
                if (!isStop) {
                    setNetworkProviderLocation();
                    setGPSLocation();
                    sendEmptyMessage(0);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
                Log.e("lxq", "handleMessage error");
                Thread.currentThread().interrupt();
            }
        }
    };
    handler.sendEmptyMessage(0);
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    String channelId = "channel_01";
    String name = "channel_name";
    NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
    Notification notification = null;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        NotificationChannel mChannel = new NotificationChannel(channelId, name, NotificationManager.IMPORTANCE_LOW);
        Log.e("lxq", mChannel.toString());
        if (notificationManager != null) {
            notificationManager.createNotificationChannel(mChannel);
        }
        notification = new Notification.Builder(this)
                .setChannelId(channelId)
                .setContentTitle("位置模拟服务已启动")
                .setContentText("MockLocation service is running")
                .setSmallIcon(R.mipmap.ic_launcher).build();
    } else {
        NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
                .setContentTitle("位置模拟服务已启动")
                .setContentText("MockLocation service is running")
                .setSmallIcon(R.mipmap.ic_launcher)
                .setOngoing(true)
                .setChannelId(channelId);//无效
        notification = notificationBuilder.build();
    }
    startForeground(1, notification);

    //这里开启悬浮窗
    if (!isFloatWindowStart) {
        floatWindow = new FloatWindow(this);
        floatWindow.showFloatWindow();
        isFloatWindowStart = true;
    }

    isStop = false;
    return super.onStartCommand(intent, flags, startId);
}

@Override
public void onDestroy() {
    super.onDestroy();
    isStop = true;
    //移除悬浮窗
    floatWindow.hideFloatWindow();
    isFloatWindowStart = false;
    handler.removeMessages(0);
    handlerThread.quit();
    removeNetworkTestProvider();
    removeGPSTestProvider();
    stopForeground(true);

}

public void removeNetworkTestProvider() {
    String providerStr = LocationManager.NETWORK_PROVIDER;
    try {
        if (locationManager.isProviderEnabled(providerStr)) {
            locationManager.removeTestProvider(providerStr);
            Log.e("lxq", "NetworkProvider已移除");
        } else {
            Log.e("lxq", "NetworkProvider未注册");
        }
    } catch (Exception e) {
        Log.e("lxq", "NetworkProvider移除失败");
    }
}

public void removeGPSTestProvider() {
    String providerStr = LocationManager.GPS_PROVIDER;
    try {
        if (locationManager.isProviderEnabled(providerStr)) {
            locationManager.removeTestProvider(providerStr);
            Log.e("lxq", "GPSTestProvider已移除");
        } else {
            Log.e("lxq", "GPSTestProvider未注册");
        }
    } catch (Exception e) {
        Log.e("lxq", "GPSTestProvider移除失败");
    }
}

private void setNetworkTestProvider() {
    String providerStr = LocationManager.NETWORK_PROVIDER;
    try {
        locationManager.addTestProvider(providerStr,
                false,
                false,
                false,
                false,
                false,
                false,
                false,
                Criteria.POWER_LOW,
                Criteria.ACCURACY_FINE);
        Log.e("lxq", "添加TestProvider[NETWORK_PROVIDER]成功");
    } catch (SecurityException e) {
        Log.e("lxq", "添加TestProvider[NETWORK_PROVIDER]失败");
    }
    if (!locationManager.isProviderEnabled(providerStr)) {
        try {
            locationManager.setTestProviderEnabled(providerStr, true);
            Log.e("lxq", "设置TestProvider[NETWORK_PROVIDER]成功");
        } catch (Exception e) {
            Log.e("lxq", "设置TestProvider[NETWORK_PROVIDER]失败");
        }
    }
}

private void setGPSTestProvider() {
    LocationProvider provider = locationManager.getProvider(LocationManager.GPS_PROVIDER);
    try {
        locationManager.addTestProvider(LocationManager.GPS_PROVIDER,
                false,
                true,
                true,
                false,
                true,
                true,
                true,
                Criteria.POWER_LOW,
                Criteria.ACCURACY_FINE);
        Log.e("lxq", "添加TestProvider[GPS_PROVIDER]成功");
    } catch (Exception e) {
        Log.e("lxq", "添加TestProvider[GPS_PROVIDER]成功");
    }
    if (!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
        try {
            locationManager.setTestProviderEnabled(LocationManager.GPS_PROVIDER, true);
            Log.e("lxq", "设置TestProvider[GPSTestProvider]成功");
        } catch (Exception e) {
            Log.e("lxq", "设置TestProvider[GPSTestProvider]失败");
        }

    }
    locationManager.setTestProviderStatus(LocationManager.GPS_PROVIDER, LocationProvider.AVAILABLE, null, System.currentTimeMillis());
}


private void setNetworkProviderLocation() {
    String providerStr = LocationManager.NETWORK_PROVIDER;
    try {
        locationManager.setTestProviderLocation(providerStr, generateLocation());
        Log.e("lxq", "设置Network定位数据成功");
    } catch (Exception e) {
        Log.e("lxq", "设置Network定位数据失败");
        e.printStackTrace();
    }
}

private void setGPSLocation() {
    String providerStr = LocationManager.GPS_PROVIDER;
    try {
        locationManager.setTestProviderLocation(providerStr, generateLocation());
        Log.e("lxq", "设置GPS定位数据成功");
    } catch (Exception e) {
        Log.e("lxq", "设置GPS定位数据失败");
        e.printStackTrace();
    }
}

//生成模拟定位
public Location generateLocation() {
    Location loc = new Location("gps");
    loc.setAccuracy(2.0F);
    loc.setAltitude(55.0D);
    loc.setBearing(1.0F);
    Bundle bundle = new Bundle();
    bundle.putInt("satellites", 7);
    loc.setExtras(bundle);
    loc.setLatitude(39.906633);
    loc.setLongitude(116.404053);
    loc.setTime(System.currentTimeMillis());
    if (Build.VERSION.SDK_INT >= 17) {
        loc.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
    }
    return loc;
}

}
`

@ms1728
Copy link

ms1728 commented Jun 24, 2021

能发下源码么。因为我现在没安卓11 的测试机子,测试难

链接: https://pan.baidu.com/s/1YB_23dkSM1F0usirtbDULQ 提取码: jqyc
这是我改动后的源码,本地没法用git克隆,这个我重新替换百度地图的API包,可能多了些没用的功能,比较大,其他改动就一个存储权限和上面test provider的一个改动吧

大佬,我自己写了一个简易版的MockGps,把你的修改后的代码MockGpsService给模仿下来了,但是自己写的为什么不能成功修改定位呢,有没有什么特别需要注意的点,还望赐教

太久了,我比较了下MainActivity.java还加了个后台请求位置的权限ACCESS_BACKGROUND_LOCATION,具体1460行,这些应该错误也能看出来或者查下安卓11更新权限特性也能了解,不过现在换了水果机了,这玩意也用不上了。

@Guoye
Copy link

Guoye commented Jul 27, 2021

经过整合ms1728的代码,亲测在安卓11下可运行。https://github.com/Guoye/MockGPS

@xkdwby
Copy link

xkdwby commented Nov 16, 2021

就这个项目,存储权限手动给到所有文件就能正常运行了。这种项目本就是用来app调试的,线上正式软件基本上都规避了这个模拟位置。要是要假位置打卡,还是应用分身在虚拟容器里打开去篡改位置。

@ZCShou
Copy link

ZCShou commented Dec 4, 2021

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants