デバイス上のAndroidモックの場所?


147

物理デバイス(Nexus One)で現在地を模擬するにはどうすればよいですか?エミュレータコントロールパネルのエミュレータを使用してこれを実行できることを知っていますが、これは物理デバイスでは機能しません。


デスクトップコンピューターの場合、この種のテストを行うために、GPSデバイス/シリアルポートデバイスをエミュレートするドライバーを作成/インストールできます。おそらく、Androidに似たものを作成または検索できます。
AaronLS 2010年

6
マーケットには、GPS位置をエミュレートできるアプリケーションがいくつかあります。たとえば、「ロケーションスプーファー」です。
Vlad

アプリケーションの多くは、これを行う店である..あなたはこれを試すことができます- play.google.com/store/apps/...または本- play.google.com/store/apps/...
イェフダ

1
ストアには、エミュレーターのように「geo fix」コマンドと「geo nmea」コマンドをサポートするアプリもあります。play.google.com/store/apps/...
LUV

@Iuvの詳細はオープンソースgithub.com/luv/mockgeofix
Vlad

回答:


166

これを行う唯一の方法は、模擬位置情報プロバイダーを使用することです。

設定の開発パネルでモックの場所を有効にし、追加する必要があります

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

あなたのマニフェストに。

これで、コードにアクセスして独自のモックロケーションプロバイダーを作成し、このプロバイダーの場所を設定できます。


83
市場には「Fake GPS」というアプリがあります。デバイスでモック場所を有効にすると、場所を設定するための優れたGUIが提供されます。これは日曜大工のソリューションではありませんが、迅速なテストには確かに役立つソリューションです。
Tim Green

2
これはリンクである可能性があります-同じ日付、および関連するコンテンツ。
DefenestrationDay

4
@TimGreenあなたのものは(単なるコメントではなく)受け入れられる答えでなければなりません!はるかに簡単なテスト方法
Bostone 2013年

実際には、「偽のGPS」アプリケーションは、場所を設定してランダムに移動することしかできないため、最適ではありません。彼らの新しいバージョンはルーティングできますが、ウェイポイントを反復するだけなので、ロケーションで大きなジャンプをします。Januszの答えは確かに正しいので、独自のモックプロバイダーを作成する必要があります。私たちは最近それを行い、誰かがそれを必要とする場合、またはこの質問がまだ助けを必要とする場合、私はコードを投稿します。
vkinra 2013年

5
「コードにアクセスして、独自のモックロケーションプロバイダーを作成する」というステートメントは、さらに詳しく説明する必要があります。
2017

102

この電話を開発ラボでのみ使用する場合、GPSチップをはんだ付けして、シリアルポートに他のデバイスからのNMEAシーケンスを直接供給することができる可能性があります。


68
なぜ嫌いですか?この答えは驚くほどハードコアです。
Ben Zotto

61
驚くほどハードコアですが、まったく役に立たない/無関係でもあります。
olivervbk

13
しかし、十分に楽しいです。
etienne

23
ええと、私はこの答えが関係するだれでも、彼らがこれを行うことができることをすでに知っています。その3人がスタックオーバーフローで解決策を探しているのではないかと思います。
ToolmakerSteve 2014

10
はんだ付けされていないデバイスに現実的なNMEAシーケンスを生成する方法がわからない場合は、素晴らしいオプションがあります。実際の外部GPSデバイスをはんだ付けし、ランナー/バイカーのチームの上にある実際のトラックに開発ラボ全体を移動します。車/飛行機/シミュレートしたい速度に応じて何でも。デバイスが衛星からの無線信号を受信できるように、開発ラボの屋上に穴を開けることを忘れないでください。どういたしまして。;-)
ステフェイン・グーリッホン

32

ケーブルが手元にあればよかったのに。エミュレータにtelnetしてその場所を変更できることを知っています

$ telnet localhost 5554
Android Console: type 'help' for a list of commands
OK
geo fix -82.411629 28.054553
OK

デバイスにtelnetできるかどうか覚えていませんが、できると思います。これがお役に立てば幸いです。

これには(CLI)adb(Androidデバッグブリッジ)が必要です。


デバイスのコンソールにコマンドとして送信するすべてに対して拒否された権限を取得します。多分それはターミナルアプリケーションで可能ですが、私はそれがルートアクセスを必要とすると思う
Janusz

ちょうど同じページにいるので、あなたは「adb shell」について話していませんか?私が話していることは異なります。これは、Android固有のパラメーターを設定できる設定です。たとえば、ルートアクセスなしでポート転送(つまりlocalhost:1234がphone:1234に移動する)を設定できるので、SOCKSプロキシを設定して、ルートなしのケーブル経由でトンネルを作成できます。
Tim Green、

adb forward tcp:6000 tcp:23を使用して、マシンのポート6000をデバイスのポート23に転送できますが、ポートが開いていると表示されていても接続できませんでした。デバイスでtelnetクライアントを使用してlocalhostに接続することも失敗します
Janusz

15
これはエミュレーターでは正常に機能しますが、実際のデバイスでは機能しません。したがって、OPの質問にはまったく答えません:(
Matthew Gilliard '28

4
@TimGreenソリューションはエミュレータ専用です。問題は、実際のデバイスに関するものでした。
IgorGanapolsky 2015年

29

位置情報サービスの権限を使用して位置情報を模擬できます...

"android.permission.ACCESS_MOCK_LOCATION"

そしてあなたのJavaコードで、

// Set location by setting the latitude, longitude and may be the altitude...
String[] MockLoc = str.split(",");
Location location = new Location(mocLocationProvider);            
Double lat = Double.valueOf(MockLoc[0]);
location.setLatitude(lat);
Double longi = Double.valueOf(MockLoc[1]);
location.setLongitude(longi);
Double alti = Double.valueOf(MockLoc[2]);
location.setAltitude(alti);

9
mocLocationProviderの値には何がありますか?
ビクター

例:LocationManager.GPS_PROVIDER
enigma969

25

次のコードで成功しました。何らかの理由で私が単一のロックを取得したとしても(別のLatLngペアを試した場合でも)、それは私にとってはうまくいきました。mLocationManagerLocationManager接続されているLocationListener

private void getMockLocation()
{
    mLocationManager.removeTestProvider(LocationManager.GPS_PROVIDER);
    mLocationManager.addTestProvider
    (
      LocationManager.GPS_PROVIDER,
      "requiresNetwork" == "",
      "requiresSatellite" == "",
      "requiresCell" == "",
      "hasMonetaryCost" == "",
      "supportsAltitude" == "",
      "supportsSpeed" == "",
      "supportsBearing" == "",

      android.location.Criteria.POWER_LOW,
      android.location.Criteria.ACCURACY_FINE
    );      

    Location newLocation = new Location(LocationManager.GPS_PROVIDER);

    newLocation.setLatitude (/* TODO: Set Some Lat */);
    newLocation.setLongitude(/* TODO: Set Some Lng */);

    newLocation.setAccuracy(500);

    mLocationManager.setTestProviderEnabled
    (
      LocationManager.GPS_PROVIDER, 
      true
    );

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

    mLocationManager.setTestProviderLocation
    (
      LocationManager.GPS_PROVIDER, 
      newLocation
    );      
}

1
いい投稿、追加については以下の私の答えを見てください。
icyerasor '26年

私が覚えている限り、setTestProviderStatusここでは、GPSプロバイダーが修正を「今」見つけたことをLocationManagerでイベントに通知/投稿/スケジュールするために使用され、そのイベントの処理を実行できます。
Dr1Ku

「の意味は何でmLocationManagerあるLocationManagerLocationListenerにフックアップされているが、」?これどうやってするの?ありがとう..
イェフダ

LocationManagerサービスと場所を使用して場所の変更を確認する方法を説明する1つの記事を次に示しLocationListenerます。blog.doityourselfandroid.com
2010/12/25

2
プラス1は、メソッドaddTestProvider
A.Alqadomi

16

Dr1Kuが投稿したものは機能します。今日コードを使用しましたが、locsを追加する必要がありました。だからここにいくつかの改善があります:

オプション:LocationManager.GPS_PROVIDER文字列を使用する代わりに、独自のconstat PROVIDER_NAMEを定義して使用することができます。場所の更新を登録するときは、プロバイダーを文字列として直接指定するのではなく、基準を使用して選択します。

最初:removeTestProviderを呼び出す代わりに、まず削除するプロバイダーがあるかどうかを確認します(IllegalArgumentExceptionを回避するため)。

if (mLocationManager.getProvider(PROVIDER_NAME) != null) {
  mLocationManager.removeTestProvider(PROVIDER_NAME);
}

2番目:複数の場所を公開するには、場所の時間を設定する必要があります。

newLocation.setTime(System.currentTimeMillis());
...
mLocationManager.setTestProviderLocation(PROVIDER_NAME, newLocation);

MockLocationProvidersを使用するGoogleテストもあるようです: http

別の良い動作例は、http//pedroassuncao.com/blog/2009/11/12/android-location-provider-mock/にあります。

別の良い記事は次のとおりです。http//ballardhack.wordpress.com/2010/09/23/location-gps-and-automated-testing-on-android/#comment-1358 また、実際に機能するコードもいくつか見つかりますエミュレータで私。


独自のプロバイダーを定義することについてのクールな提案は、GPS_PROVIDERを使用することで、再起動するまで(どうやら)疑似プロバイダーを削除できない(正確には、通常のGPSに切り替えることができない)ことです。素晴らしい投稿もあるので、参考文献をチェックします。
Dr1Ku 2011年

@ Dr1KUそれでも、通常のGPSに戻すことができないのですか?それはどこかで指定されていますか?
Kaz Dragon

@KazDragon当時はそうだった。思い出すとMock Provider、電源を入れた後、通常のGPSが機能せず、解決策を得ることができませんでした(デバイスで直接テストしていました)。それ以来、Androidで多くのことが起こっているため、これは当てはまらない場合があります。
Dr1Ku 2013年

@ Dr1Kuああ、まあ、私は今非常に似たようなことをしていて、あなたが説明したものと同様の結果を受け取っています。これがプラットフォームに組み込まれた制限なのか、どこかに関数呼び出しがないだけなのかを知りたいと思っていました。私はおそらくこれから質問をする必要があります。
Kaz Dragon

9

Androidマーケットには、デバイスの「模擬GPS位置」を指定できるアプリがあります。

https://market.android.comを検索しましたしたところ、「My Fake Location」というアプリが見つかりました。

上記のポールによって言及されたモックGPSプロバイダー(http://www.cowlumbus.nl/forum/MockGpsProvider.zipで)は、ソースコードを含む別の例です-提供されたAPKをインストールできませんでした(失敗と表示されています) [INSTALL_FAILED_OLDER_SDK]および再コンパイルが必要な場合があります)

GPSモック位置を使用するには、デバイスの設定で有効にする必要があります。[設定]-> [アプリケーション]-> [開発]に移動し、[モックの場所を許可する]をオンにします

次に、上記のようなアプリを使用してGPS座標とGoogleマップを設定できます。他のアプリは、指定した模擬GPS位置を使用します。


偽のGPSの方が簡単です。私はなぜ彼らがアプリの許可で発信者IDを要求しているのか疑問に思っています:S
GuillaumeMassé13年

8

これは私のために働きました(Android Studio):

電話でGPSおよびWiFiトラッキングを無効にします。Android 5.1.1以下では、開発者向けオプションで「モック場所を有効にする」を選択します。

マニフェストのコピーをsrc / debugディレクトリに作成します。以下を(「application」タグの外に)追加します。

uses-permission android:name = "android.permission.ACCESS_MOCK_LOCATION"

「マップ」と呼ばれるマップフラグメントを設定します。onCreate()に次のコードを含めます。

lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
ll = new MyLocationListener();
if (lm.getProvider("Test") == null) {
    lm.addTestProvider("Test", false, false, false, false, false, false, false, 0, 1);
}
lm.setTestProviderEnabled("Test", true);
lm.requestLocationUpdates("Test", 0, 0, ll);

map.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
    @Override
    public void onMapClick(LatLng l) {
        Location loc = new Location("Test");
        loc.setLatitude(l.latitude);
        loc.setLongitude(l.longitude);
        loc.setAltitude(0); 
        loc.setAccuracy(10f);
        loc.setElapsedRealtimeNanos(System.nanoTime());
        loc.setTime(System.currentTimeMillis()); 
        lm.setTestProviderLocation("Test", loc);
    }
};

「setElapsedRealtimeNanos」メソッドを使用するために、モジュールグラドルファイルの「minSdkVersion」を一時的に17に増やす必要がある場合があることに注意してください。

メインアクティビティクラス内に次のコードを含めます。

private class MyLocationListener implements LocationListener {
    @Override
    public void onLocationChanged(Location location) {
        // do whatever you want, scroll the map, etc.
    }
}

ASでアプリを実行します。Android 6.0以降では、セキュリティ例外が発生します。次に、[設定]の[開発者向けオプション]に移動し、[モック位置アプリを選択]を選択します。リストからアプリを選択します。

これで、地図をタップすると、onLocationChanged()がタップの座標で起動します。

私はこれを理解しただけなので、今では携帯電話を手にして近所をぶらぶらする必要はありません。


このコードを使用すると、android 6で機能すると思います
Hamza

7

初期位置からの移動位置をシミュレートする単純なハンドラーを作成しました。

接続コールバックで開始します。

private final GoogleApiClient.ConnectionCallbacks mConnectionCallbacks = new GoogleApiClient.ConnectionCallbacks() {
    @Override
    public void onConnected(Bundle bundle) {
        if (BuildConfig.USE_MOCK_LOCATION) {
            LocationServices.FusedLocationApi.setMockMode(mGoogleApiClient, true);
            new MockLocationMovingHandler(mGoogleApiClient).start(48.873399, 2.342911);
        }
    }

    @Override
    public void onConnectionSuspended(int i) {

    }
};

ハンドラクラス:

   private static class MockLocationMovingHandler extends Handler {

    private final static int SET_MOCK_LOCATION = 0x000001;
    private final static double STEP_LATITUDE =  -0.00005;
    private final static double STEP_LONGITUDE = 0.00002;
    private final static long FREQUENCY_MS = 1000;
    private GoogleApiClient mGoogleApiClient;
    private double mLatitude;
    private double mLongitude;

    public MockLocationMovingHandler(final GoogleApiClient googleApiClient) {
        super(Looper.getMainLooper());
        mGoogleApiClient = googleApiClient;
    }

    public void start(final double initLatitude, final double initLongitude) {
        if (hasMessages(SET_MOCK_LOCATION)) {
            removeMessages(SET_MOCK_LOCATION);
        }
        mLatitude = initLatitude;
        mLongitude = initLongitude;
        sendEmptyMessage(SET_MOCK_LOCATION);
    }

    public void stop() {
        if (hasMessages(SET_MOCK_LOCATION)) {
            removeMessages(SET_MOCK_LOCATION);
        }
    }

    @Override
    public void handleMessage(Message message) {
        switch (message.what) {
            case SET_MOCK_LOCATION:
                Location location = new Location("network");
                location.setLatitude(mLatitude);
                location.setLongitude(mLongitude);
                location.setTime(System.currentTimeMillis());
                location.setAccuracy(3.0f);
                location.setElapsedRealtimeNanos(System.nanoTime());
                LocationServices.FusedLocationApi.setMockLocation(mGoogleApiClient, location);

                mLatitude += STEP_LATITUDE;
                mLongitude += STEP_LONGITUDE;
                sendEmptyMessageDelayed(SET_MOCK_LOCATION, FREQUENCY_MS);
                break;
        }
    }
}

お役に立てれば幸いです。


6

icyerasorによって言及され、http: //pedroassuncao.com/blog/2009/11/12/android-location-provider-mock/でPedroによって提供されたソリューションは 、私にとって非常にうまく機能しました。ただし、模擬GPSプロバイダーの適切な起動、停止、再起動はサポートされていません。

私は彼のコードを少し変更し、クラスをスレッドではなくAsyncTaskに書き直しました。これにより、UIスレッドと通信できるようになるため、停止した時点でプロバイダーを再起動できます。これは、画面の向きが変わるときに便利です。

コードとEclipseのサンプルプロジェクトは、GitHubで見つけることができます:https : //github.com/paulhoux/Android-MockProviderGPS

すべての功績は、ほとんどの困難な作業を行ったペドロに送られるべきです。


6

マニフェストに追加

<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION"
    tools:ignore="MockLocation,ProtectedPermissions" />

モックロケーション機能

void setMockLocation() {
    LocationManager locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
    locationManager.addTestProvider(LocationManager.GPS_PROVIDER, false, false,
            false, false, true, true, true, 0, 5);
    locationManager.setTestProviderEnabled(LocationManager.GPS_PROVIDER, true);

    Location mockLocation = new Location(LocationManager.GPS_PROVIDER);
    mockLocation.setLatitude(-33.852);  // Sydney
    mockLocation.setLongitude(151.211);
    mockLocation.setAltitude(10);
    mockLocation.setAccuracy(5);
    mockLocation.setTime(System.currentTimeMillis());
    mockLocation.setElapsedRealtimeNanos(System.nanoTime());
    locationManager.setTestProviderLocation(LocationManager.GPS_PROVIDER, mockLocation);
}

また、デバイスの開発者設定でモックの場所を有効にする必要があります。それが利用できない場合は、上記を実装した後、「モック位置アプリケーション」をアプリケーションに設定します。


3

グーグルプレイからの偽のGPSアプリは私のためのトリックをしました。アプリの説明にあるすべての説明を必ずお読みください。「Fake GPS」を有効にした後は、他の位置情報サービスを無効にし、アプリを起動する必要があります。私が必要とするもののためにうまく働きました。

GooglePlayのアプリへのリンクは次のとおりです: 偽のGPS



2

Fake GPSアプリをインストール https://play.google.com/store/apps/details?id=com.incorporateapps.fakegps.fre&hl=en

開発者オプション-> 模擬位置情報アプリを選択します(つまり、偽の位置情報アプリが選択されています)。

偽のGPSアプリ

追加するマップ上のダブルタブ->再生ボタンをクリック->トーストを表示 "偽の場所が停止しました"

最後にグーグルマップアプリで確認してください。


2

AndroidフォンでWebServer(RESTのような)を実行するアプリを作成したので、GPS位置をリモートで設定できます。Webサイトには、新しい位置を設定するためにクリックするか、「wasd」キーを使用して任意の方向に移動できるマップが用意されています。アプリは迅速なソリューションでしたので、UIやドキュメントはほとんどありませんが、実装は簡単で、すべて(4つだけ)のクラスで検索できます。

プロジェクトリポジトリ:https : //github.com/juliusmh/RemoteGeoFix


1

デバイスがコンピューターに接続されており、エミュレーターコントロールを介して送信GPSコードを変更しようとしても、機能しません。
これは、理由のためのEMULATORコントロールです。
GPSの変更時に更新するように設定するだけです。

lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);  

    ll = new LocationListener() {        
        public void onLocationChanged(Location location) {  
          // Called when a new location is found by the network location provider.  
            onGPSLocationChanged(location); 
        }

        public void onStatusChanged(String provider, int status, Bundle extras) {       
            bigInfo.setText("Changed "+ status);  
        }

        public void onProviderEnabled(String provider) {
            bigInfo.setText("Enabled "+ provider);
        }

        public void onProviderDisabled(String provider) {
            bigInfo.setText("Disabled "+ provider);
        }
      };

GPSが更新されたら、次のメソッドを書き換えて希望どおりに実行します。

public void onGPSLocationChanged(Location location){  
if(location != null){  
    double pLong = location.getLongitude();  
    double pLat = location.getLatitude();  
    textLat.setText(Double.toString(pLat));  
    textLong.setText(Double.toString(pLong));  
    if(autoSave){  
        saveGPS();  
        }
    }
}

これらをマニフェストに
追加することを忘れないでくださいandroid.permission.ACCESS_FINE_LOCATION
android.permission.ACCESS_MOCK_LOCATION


0

複雑なモックの場所の設定が必要かどうか。私の場合、固定位置を取得すると、その新しい位置で何かを行うための関数を呼び出していました。タイマーで模擬場所を作成します。代わりに、その場所で関数を呼び出します。GPSが本当の現在の場所を思い付くまでの短い間で、そのすべてを知っています。大丈夫です。更新時間を十分に長く設定している場合。


0

多分それは「プログラマー」のアプローチではありませんが、時間を節約してソリューションをすぐに活用したい場合は、Google Playで利用可能なモックの場所に特化したアプリの1つを試してください:

偽のGPSロケーションスプーファー

モックの場所

偽のGPS位置


1
やってみましたか?それらは質問で要求されたとおりに機能しましたか?
arekolek 2017

好みは?または、それらすべてが必要ですか?:P
arekolek 2018年

偽のGPS Location Spooferで十分ですが、Mock Locationsではルートを設定できるので便利です。
klimat 2018年

0

Android搭載の携帯電話とタブレット(CATLESという名前)用の非常に便利で無料のインタラクティブな位置情報シミュレータを利用してください。システム全体のレベルで(GoogleマップやFacebookアプリ内でも)GPS位置を模倣し、物理デバイスと仮想デバイスの両方で機能します。

ウェブサイト:http : //ubicom.snet.tu-berlin.de/catles/index.html

ビデオ:https : //www.youtube.com/watch?v=0WSwH5gK7yg


0

この権限をマニフェストファイルで使用する

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

android studioは、「モックの場所は、テストまたはデバッグ固有のマニフェストファイル(通常はsrc / debug / AndroidManifest.xml)でのみリクエストする必要があります」という検査を無効にすることを推奨します。

お使いの携帯電話の開発者設定で「模擬場所を許可する」をチェックしたことを確認してください

LocationManagerを使用する

locationManager.addTestProvider(mocLocationProvider, false, false,
                false, false, true, true, true, 0, 5);
locationManager.setTestProviderEnabled(mocLocationProvider, true);

次に、好きな場所に場所を設定します

Location mockLocation = new Location(mocLocationProvider); 
mockLocation.setLatitude(lat); 
mockLocation.setLongitude(lng); 
mockLocation.setAltitude(alt); 
mockLocation.setTime(System.currentTimeMillis()); 
locationManager.setTestProviderLocation( mocLocationProvider, mockLocation); 

0

FusedLocationProviderClientを利用する最新のGoogle Play 開発者サービスバージョンを搭載したAndroidデバイスでテストを行っていたため、上記のソリューションは機能しませんでした。アプリのマニフェストでモックの場所のアクセス許可を設定し、開発者の設定でアプリを指定のモックの場所のアプリとして設定した後(上記の回答で述べたように)、以下のKotlinコードを追加して、場所を正常にモックしました。

locationProvider = FusedLocationProviderClient(context)
locationProvider.setMockMode(true)

val loc = Location(providerName)
val mockLocation = Location(providerName) // a string
mockLocation.latitude = latitude  // double
mockLocation.longitude = longitude
mockLocation.altitude = loc.altitude
mockLocation.time = System.currentTimeMillis()
mockLocation.accuracy = 1f
mockLocation.elapsedRealtimeNanos = SystemClock.elapsedRealtimeNanos()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    mockLocation.bearingAccuracyDegrees = 0.1f
    mockLocation.verticalAccuracyMeters = 0.1f
    mockLocation.speedAccuracyMetersPerSecond = 0.01f
}
//        locationManager.setTestProviderLocation(providerName, mockLocation)
locationProvider.setMockLocation(mockLocation)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.