2

我正在尝试在 android 中创建自己的位置提供程序,以在系统中注入我自己的定位数据。为此,我在系统中重用 LocationManager 函数,在那里注册一个我希望被调用的侦听器,但它并不总是被调用。我已经做了一些研究,但我无法弄清楚系统用来触发事件的模式,而且谷歌也没有大量的官方文档。

请注意,我不使用系统中的任何位置提供程序(GPS、网络...)。我创建自己的坐标和时间戳并将其发布在假位置提供程序中,所以几乎所有关于这个问题的问题都与这个问题略有不同(所以与 GPS 无关,无论我是否在移动,最小距离范围...)。

在这里,我向您展示代码和生成的日志。您可以很容易地看到某些事件永远不会被触发(例如启用了 onProvider)、在不应该触发时触发(onProviderDisbled)或在错误的时间触发(例如 onStatusChanged,仅在状态更改和位置更改之后触发)。

这是主要代码:

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        lm = (LocationManager) getSystemService(Service.LOCATION_SERVICE);

        if (!isMockLocationSet()) {
            throw new RuntimeException("Mock Locations are disabled!");
        }

        // 1. Generate a valid random name for the mock provider
        providerName = this.generateValidProviderName();

        // 2. Create the mock provider
        System.out.println("Step 2: Create provider (" + providerName + ")");
        try {
            if (lm.getProvider(providerName) == null) {
                throw new IllegalArgumentException();
            }
        } catch (IllegalArgumentException e) {// Doesn't exist, create
            lm.addTestProvider(providerName, false, false, false, false, false,
                    false, false, Criteria.POWER_MEDIUM, Criteria.ACCURACY_HIGH);
        }

        // 3. Register for updates
        System.out.println("Step 3: Register for updates");
        MyLocationListener l = new MyLocationListener();
        lm.requestLocationUpdates(providerName, 0, 0, l);

        MyAsyncTask task = new MyAsyncTask();
        task.execute();

    }
private class MyAsyncTask extends AsyncTask<Void, Void, Void> {

        @Override
        protected Void doInBackground(Void... params) {

            Location loc = new Location(providerName);

            // 4. Enable it!
            System.out.println("Step 4: Enable it");
            lm.setTestProviderEnabled(providerName, true);

            // 5. Change the status
            System.out.println("Step 5: Change the status to AVAILABLE");
            lm.setTestProviderStatus(providerName, LocationProvider.AVAILABLE,
                    null, System.currentTimeMillis());

            // 6. Change the status
            System.out
                    .println("Step 7: Change the status to TEMPORARILY_UNAVAILABLE");
            lm.setTestProviderStatus(providerName,
                    LocationProvider.TEMPORARILY_UNAVAILABLE, null,
                    System.currentTimeMillis());

            // 7.1. Change location
            System.out.println("Step 7.1: Change Location");
            loc.setTime(System.currentTimeMillis());
            loc.setLatitude(52.0f);
            loc.setLongitude(10.0f);
            lm.setTestProviderLocation(providerName, loc);

            // 7.2. Change location
            System.out.println("Step 7.2: Change Location");
            loc.setTime(System.currentTimeMillis());
            loc.setLatitude(52.1f);
            loc.setLongitude(10.1f);
            lm.setTestProviderLocation(providerName, loc);

            // 7.3. Change the status
            System.out.println("Step 7.3: Change the status to AVAILABLE");
            lm.setTestProviderStatus(providerName, LocationProvider.AVAILABLE,
                    null, System.currentTimeMillis());

            // 7.4. Change location
            System.out.println("Step 7.4: Change Location");
            loc.setTime(System.currentTimeMillis());
            loc.setLatitude(52.2f);
            loc.setLongitude(10.2f);
            lm.setTestProviderLocation(providerName, loc);

            // 7.5. Change the status
            System.out.println("Step 7.5: Change the status to OUT_OF_SERVICE");
            lm.setTestProviderStatus(providerName,
                    LocationProvider.OUT_OF_SERVICE, null,
                    System.currentTimeMillis());

            // 7.6. Change location
            System.out.println("Step 7.6: Change Location");
            loc.setTime(System.currentTimeMillis());
            loc.setLatitude(52.3f);
            loc.setLongitude(10.3f);
            lm.setTestProviderLocation(providerName, loc);

            try {
                // 8. Delete provider
                System.out.println("8. Delete provider");
                lm.setTestProviderEnabled(providerName, false);
                lm.removeTestProvider(providerName);
            } catch (IllegalArgumentException e) {
            }
            return null;
        }
    }

这里是日志的输出:

07-26 11:31:21.271: I/System.out(8721): Step 2: Create provider (Fake_GPS_92A4)
07-26 11:31:21.271: I/System.out(8721): Step 3: Register for updates
07-26 11:31:21.276: I/System.out(8721): Step 4: Enable it
07-26 11:31:21.276: I/System.out(8721): Step 5: Change the status to AVAILABLE
07-26 11:31:21.276: I/System.out(8721): Step 7: Change the status to TEMPORARILY_UNAVAILABLE
07-26 11:31:21.276: I/System.out(8721): Step 7.1: Change Location
07-26 11:31:21.291: I/System.out(8721): Step 7.2: Change Location
07-26 11:31:21.301: D/MainActivity(8721): onProviderDisabled
07-26 11:31:21.306: I/System.out(8721): Step 7.3: Change the status to AVAILABLE
07-26 11:31:21.306: I/System.out(8721): onLocationChanged 
07-26 11:31:21.306: D/MainActivity(8721): onStatusChanged: TEMPORARILY_UNAVAILABLE
07-26 11:31:21.306: I/System.out(8721): Step 7.4: Change Location
07-26 11:31:21.306: I/System.out(8721): Step 7.5: Change the status to OUT_OF_SERVICE
07-26 11:31:21.356: I/System.out(8721): Step 7.6: Change Location
07-26 11:31:21.361: I/System.out(8721): 8. Delete provider
07-26 11:31:21.401: I/System.out(8721): onLocationChanged 
07-26 11:31:21.401: I/System.out(8721): onLocationChanged 
07-26 11:31:21.436: D/MainActivity(8721): onStatusChanged: AVAILABLE

当然,这不是权限问题:

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" />

我在这个问题上花了很多时间,并将代码简化为最低限度的表达,所以我希望你至少可以看看。

谢谢!

4

0 回答 0