Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android 使用模擬位置(支持Android 6.0)

Android 使用模擬位置(支持Android 6.0)

編輯:關於Android編程

開啟系統設置中的模擬位置

Android 6.0 以下:【開發者選項 -> 允許模擬位置】

允許模擬位置

Android 6.0 及以上:【開發者選項 -> 選擇模擬位置信息應用】

選擇模擬位置信息應用


AndroidManifest.xml

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

判斷是否開啟了系統模擬位置

Android 6.0 以下:使用Settings.Secure.ALLOW_MOCK_LOCATION判斷。

// Android 6.0 以下:是否開啟【允許模擬位置】
boolean canMockPosition = Settings.Secure.getInt(getContentResolver(), Settings.Secure.ALLOW_MOCK_LOCATION, 0) != 0

Android 6.0 及以上:沒有【允許模擬位置】選項,同時棄用了Settings.Secure.ALLOW_MOCK_LOCATION,無法通過上面的方法判斷。增加了【選擇模擬位置信息應用】的方法,需要選擇使用模擬位置的應用。但是不知道怎麼獲取當前選擇的應用,因此通過是否能夠成功執行addTestProvider方法來進行判斷,如果沒有選擇當前的應用,則addTestProvider會拋出異常。(有沒有人知道,有沒有人知道。。。)

boolean hasAddTestProvider = false;
boolean canMockPosition = (Settings.Secure.getInt(getContentResolver(), Settings.Secure.ALLOW_MOCK_LOCATION, 0) != 0)
        || Build.VERSION.SDK_INT > 22;
if (canMockPosition && hasAddTestProvider == false) {
    try {
        String providerStr = LocationManager.GPS_PROVIDER;
        LocationProvider provider = locationManager.getProvider(providerStr);
        if (provider != null) {
            locationManager.addTestProvider(
                    provider.getName()
                    , provider.requiresNetwork()
                    , provider.requiresSatellite()
                    , provider.requiresCell()
                    , provider.hasMonetaryCost()
                    , provider.supportsAltitude()
                    , provider.supportsSpeed()
                    , provider.supportsBearing()
                    , provider.getPowerRequirement()
                    , provider.getAccuracy());
        } else {
            locationManager.addTestProvider(
                    providerStr
                    , true, true, false, false, true, true, true
                    , Criteria.POWER_HIGH, Criteria.ACCURACY_FINE);
        }
        locationManager.setTestProviderEnabled(providerStr, true);
        locationManager.setTestProviderStatus(providerStr, LocationProvider.AVAILABLE, null, System.currentTimeMillis());

        // 模擬位置可用
        hasAddTestProvider = true;
        canMockPosition = true;
    } catch (SecurityException e) {
        canMockPosition = false;
    }
}

模擬位置

private class RunnableMockLocation implements Runnable {

    @Override
    public void run() {
        while (true) {
            try {
                Thread.sleep(INTERVEL);

                if (hasAddTestProvider() == false) {
                    continue;
                }

                try {
                    // 模擬位置(addTestProvider成功的前提下)
                    String providerStr = LocationManager.GPS_PROVIDER;
                    Location mockLocation = new Location(providerStr);
                    mockLocation.setLatitude(22);   // 維度(度)
                    mockLocation.setLongitude(113);  // 經度(度)
                    mockLocation.setAltitude(30);    // 高程(米)
                    mockLocation.setBearing(180);   // 方向(度)
                    mockLocation.setSpeed(10);    //速度(米/秒)
                    mockLocation.setAccuracy(0.1f);   // 精度(米)
                    mockLocation.setTime(new Date().getTime());   // 本地時間 
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
                        mockLocation.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
                    }
                    locationManager.setTestProviderLocation(providerStr, mockLocation);
                } catch (Exception e) {
                    // 防止用戶在軟件運行過程中關閉模擬位置或選擇其他應用
                    stopMockLocation();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

停止模擬位置

/**
 * 停止模擬位置,以免啟用模擬數據後無法還原使用系統位置
 * 若模擬位置未開啟,則removeTestProvider將會拋出異常;
 * 若已addTestProvider後,關閉模擬位置,未removeTestProvider將導致系統GPS無數據更新;
 */
public void stopMockLocation() {
    if (hasAddTestProvider) {
        try {
            locationManager.removeTestProvider(LocationManager.GPS_PROVIDER);
        } catch (Exception ex) {
            // 若未成功addTestProvider,或者系統模擬位置已關閉則必然會出錯
        }
        hasAddTestProvider = false;
    }
}

Android Studio Project

系統原生位置

模擬位置

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved