Android-location-based-services

提供:Dev Guides
移動先:案内検索

Android-ロケーションベースのサービス

'_AndroidのロケーションAPIを使用すると、基盤となるロケーションテクノロジーの詳細に集中する必要なく、ロケーション認識アプリケーションを簡単に構築できます。_

これは、自動化された位置追跡、ジオフェンシング、アクティビティ認識により、アプリへの位置認識の追加を容易にする Google Play services の助けを借りて可能になります。

このチュートリアルでは、APPでロケーションサービスを使用して現在の位置を取得する方法、定期的な位置の更新を取得する方法、住所を検索する方法などを示します。

ロケーションオブジェクト

*Location* オブジェクトは、緯度、経度、タイムスタンプ、および方位、高度、速度などのその他の情報で構成される地理的な場所を表します。 あなたは場所の特定の情報を取得するためにLocationオブジェクトで使用できる次の重要な方法があります-
Sr.No. Method & Description
1

float distanceTo(Location dest)

この場所と指定された場所の間のおよその距離をメートル単位で返します。

2

float getAccuracy()

この場所の推定精度をメートル単位で取得します。

3

double getAltitude()

利用可能な場合は、標高をメートル単位で取得します。

4

float getBearing()

度で方位を取得します。

5

double getLatitude()

緯度を度で取得します。

6

double getLongitude()

度で経度を取得します。

7

float getSpeed()

速度が利用可能な場合は、地上のメートル/秒で速度を取得します。

8

boolean hasAccuracy()

この場所に精度がある場合はtrue。

9

boolean hasAltitude()

この場所に高度がある場合はtrue。

10

boolean hasBearing()

この場所にベアリングがある場合はtrue。

11

boolean hasSpeed()

この場所に速度がある場合はtrue。

12

void reset()

ロケーションの内容をクリアします。

13

void setAccuracy(float accuracy)

この場所の推定精度、メートルを設定します。

14

void setAltitude(double altitude)

標高を、海抜0メートルで設定します。

15

void setBearing(float bearing)

方位を角度で設定します。

16

void setLatitude(double latitude)

緯度を度で設定します。

17

void setLongitude(double longitude)

経度を度単位で設定します。

18

void setSpeed(float speed)

地上の速度をメートル/秒で設定します。

19

String toString()

このオブジェクトの簡潔で人間が読み取れる説明を含む文字列を返します。

現在地を取得する

現在の場所を取得するには、 LocationClient オブジェクトであるロケーションクライアントを作成し、* connect()メソッドを使用してロケーションサービスに接続し、その getLastLocation()メソッドを呼び出します。 このメソッドは、上記で説明した緯度と経度の座標およびその他の情報を含む *Location オブジェクトの形式で最新の場所を返します。 あなたの活動で位置ベースの機能を使用するには、2つのインターフェイスを実装する必要があります-

  • GooglePlayServicesClient.ConnectionCallbacks *GooglePlayServicesClient.OnConnectionFailedListener

これらのインターフェイスは、アクティビティクラスに実装する必要がある次の重要なコールバックメソッドを提供します-

Sr.No. Callback Methods & Description
1
  • abstract void onConnected(Bundle connectionHint)*

ロケーションサービスがロケーションクライアントに正常に接続されると、このコールバックメソッドが呼び出されます。 * connect()*メソッドを使用して、ロケーションクライアントに接続します。

2

abstract void onDisconnected()

このコールバックメソッドは、クライアントが切断されたときに呼び出されます。 * disconnect()*メソッドを使用して、ロケーションクライアントから切断します。

3

abstract void onConnectionFailed(ConnectionResult result)

このコールバックメソッドは、クライアントをサービスに接続する際にエラーが発生したときに呼び出されます。

'_アクティビティクラスの* onCreate()メソッドでロケーションクライアントを作成し、それを onStart()*で接続する必要があります。これにより、ロケーションサービスは、アクティビティが完全に見える間、現在のロケーションを維持します。 * onStop()*メソッドでクライアントを切断する必要があります。これにより、アプリが表示されないときに、位置情報サービスが現在の位置を維持しなくなります。 これにより、バッテリーの電力を大幅に節約できます。_

更新された場所を取得する

場所の更新を希望する場合は、上記のインターフェイスとは別に、 LocationListener インターフェイスも実装する必要があります。 このインターフェイスは、アクティビティクラスに実装する必要がある次のコールバックメソッドを提供します-

Sr.No. Callback Method & Description
1

abstract void onLocationChanged(Location location)

このコールバックメソッドは、場所が変更されたときにLocationClientから通知を受信するために使用されます。

ロケーションのサービス品質

*LocationRequest* オブジェクトは、 *LocationClient* からのロケーション更新のサービス品質(QoS)を要求するために使用されます。 QoSの処理に使用できる次の便利な設定メソッドがあります。 Androidの公式ドキュメントで確認できる同等のゲッターメソッドがあります。
Sr.No. Method & Description
1

setExpirationDuration(long millis)

このリクエストの期間をミリ秒単位で設定します。

2

setExpirationTime(long millis)

ブートからのミリ秒単位で、リクエストの有効期限を設定します。

3

setFastestInterval(long millis)

ロケーション更新の最速の間隔をミリ秒単位で明示的に設定します。

4

setInterval(long millis)

アクティブな場所の更新に必要な間隔をミリ秒単位で設定します。

5

setNumUpdates(int numUpdates)

ロケーション更新の数を設定します。

6

setPriority(int priority)

リクエストの優先度を設定します。

たとえば、アプリケーションで高精度の位置情報が必要な場合は、* setPriority(int)をPRIORITY_HIGH_ACCURACYに、 setInterval(long)*を5秒に設定して位置情報要求を作成する必要があります。 また、「都市」レベルの精度を要求するPRIORITY_LOW_POWERや「ブロック」レベルの精度を要求するPRIORITY_BALANCED_POWER_ACCURACYなど、より大きな間隔や優先順位を使用できます。

'_アクティビティでは、バックグラウンドに入るとき(onPause()など)にすべてのロケーションリクエストを削除するか、少なくともリクエストをより長い間隔で低品質に切り替えて電力消費を節約することを強く検討する必要があります。_

ロケーション住所の表示

*Location* オブジェクトを取得したら、* Geocoder.getFromLocation()*メソッドを使用して、特定の緯度と経度の住所を取得できます。 このメソッドは同期的であり、作業に時間がかかる場合があるため、 *AsyncTask* クラスの* doInBackground()*メソッドからメソッドを呼び出す必要があります。
*AsyncTask* は使用するサブクラスである必要があり、サブクラスはバックグラウンドでタスクを実行するために* doInBackground(Params ...)*メソッドをオーバーライドし、バックグラウンドの計算後に* onPostExecute(Result)*メソッドがUIスレッドで呼び出されます終了し、その時点で結果を表示します。 AyncTaskで使用できるもう1つの重要なメソッドは、* execute(Params ... params)*、このメソッドは指定されたパラメーターでタスクを実行します。

次の例は、アプリで位置情報サービスを使用して現在の位置とその同等の住所などを取得する方法を実際に示しています。

'_この例を試すには、最新のAndroid OSを搭載した実際のモバイルデバイスが必要です。そうでない場合は、エミュレータが動作しないことがあります。_

Androidアプリケーションを作成する

Step Description
1 You will use Android studio IDE to create an Android application and name it as finddevguides under a package com.example.finddevguides7.myapplication.
2 add src/GPSTracker.java file and add required code.
3 Modify src/MainActivity.java file and add required code as shown below to take care of getting current location and its equivalent address.
4 Modify layout XML file res/layout/activity_main.xml to add all GUI components which include three buttons and two text views to show location/address.
5 Modify res/values/strings.xml to define required constant values
6 Modify AndroidManifest.xml as shown below
7 Run the application to launch Android emulator and verify the result of the changes done in the application.

以下は、変更されたメインアクティビティファイル MainActivity.java の内容です。

package com.example.finddevguides7.myapplication;

import android.Manifest;
import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.test.mock.MockPackageManager;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends Activity {

   Button btnShowLocation;
   private static final int REQUEST_CODE_PERMISSION = 2;
   String mPermission = Manifest.permission.ACCESS_FINE_LOCATION;

  //GPSTracker class
   GPSTracker gps;

   @Override
   public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);

      try {
         if (ActivityCompat.checkSelfPermission(this, mPermission)
            != MockPackageManager.PERMISSION_GRANTED) {

            ActivityCompat.requestPermissions(this, new String[]{mPermission},
               REQUEST_CODE_PERMISSION);

           //If any permission above not allowed by user, this condition will
               execute every time, else your else part will work
         }
      } catch (Exception e) {
         e.printStackTrace();
      }

      btnShowLocation = (Button) findViewById(R.id.button);

     //show location button click event
      btnShowLocation.setOnClickListener(new View.OnClickListener() {

         @Override
         public void onClick(View arg0) {
           //create class object
            gps = new GPSTracker(MainActivity.this);

           //check if GPS enabled
            if(gps.canGetLocation()){

               double latitude = gps.getLatitude();
               double longitude = gps.getLongitude();

              //\n is for new line
               Toast.makeText(getApplicationContext(), "Your Location is - \nLat: "
                  + latitude + "\nLong: " + longitude, Toast.LENGTH_LONG).show();
            }else{
              //can't get location
              //GPS or Network is not enabled
              //Ask user to enable GPS/network in settings
               gps.showSettingsAlert();
            }

         }
      });
   }
}

以下は、変更されたメインアクティビティファイル GPSTracker.java の内容です。

package com.example.finddevguides7.myapplication;

import android.app.AlertDialog;
import android.app.Service;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
import android.provider.Settings;
import android.util.Log;

public class GPSTracker extends Service implements LocationListener {

   private final Context mContext;

  //flag for GPS status
   boolean isGPSEnabled = false;

  //flag for network status
   boolean isNetworkEnabled = false;

  //flag for GPS status
   boolean canGetLocation = false;

   Location location;//location
   double latitude;//latitude
   double longitude;//longitude

  //The minimum distance to change Updates in meters
   private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10;//10 meters

  //The minimum time between updates in milliseconds
   private static final long MIN_TIME_BW_UPDATES = 1000 *60* 1;//1 minute

  //Declaring a Location Manager
   protected LocationManager locationManager;

   public GPSTracker(Context context) {
      this.mContext = context;
      getLocation();
   }

   public Location getLocation() {
      try {
         locationManager = (LocationManager) mContext.getSystemService(LOCATION_SERVICE);

        //getting GPS status
         isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);

        //getting network status
         isNetworkEnabled = locationManager
            .isProviderEnabled(LocationManager.NETWORK_PROVIDER);

         if (!isGPSEnabled && !isNetworkEnabled) {
           //no network provider is enabled
         } else {
            this.canGetLocation = true;
           //First get location from Network Provider
            if (isNetworkEnabled) {
               locationManager.requestLocationUpdates(
                  LocationManager.NETWORK_PROVIDER,
                  MIN_TIME_BW_UPDATES,
                  MIN_DISTANCE_CHANGE_FOR_UPDATES, this);

               Log.d("Network", "Network");
               if (locationManager != null) {
                  location = locationManager
                     .getLastKnownLocation(LocationManager.NETWORK_PROVIDER);

                  if (location != null) {
                     latitude = location.getLatitude();
                     longitude = location.getLongitude();
                  }
               }
            }

           //if GPS Enabled get lat/long using GPS Services
            if (isGPSEnabled) {
               if (location == null) {
                  locationManager.requestLocationUpdates(
                     LocationManager.GPS_PROVIDER,
                     MIN_TIME_BW_UPDATES,
                     MIN_DISTANCE_CHANGE_FOR_UPDATES, this);

                  Log.d("GPS Enabled", "GPS Enabled");
                  if (locationManager != null) {
                     location = locationManager
                        .getLastKnownLocation(LocationManager.GPS_PROVIDER);

                     if (location != null) {
                        latitude = location.getLatitude();
                        longitude = location.getLongitude();
                     }
                  }
               }
            }
         }

      } catch (Exception e) {
         e.printStackTrace();
      }

      return location;
   }

  /**
 *Stop using GPS listener
     * Calling this function will stop using GPS in your app
   * */

   public void stopUsingGPS(){
      if(locationManager != null){
         locationManager.removeUpdates(GPSTracker.this);
      }
   }

  /**
 *Function to get latitude
  * */

   public double getLatitude(){
      if(location != null){
         latitude = location.getLatitude();
      }

     //return latitude
      return latitude;
   }

  /**
 *Function to get longitude
  * */

   public double getLongitude(){
      if(location != null){
         longitude = location.getLongitude();
      }

     //return longitude
      return longitude;
   }

  /**
 *Function to check GPS/wifi enabled
     * @return boolean
   * */

   public boolean canGetLocation() {
      return this.canGetLocation;
   }

  /**
 *Function to show settings alert dialog
     * On pressing Settings button will lauch Settings Options
   * */

   public void showSettingsAlert(){
      AlertDialog.Builder alertDialog = new AlertDialog.Builder(mContext);

     //Setting Dialog Title
      alertDialog.setTitle("GPS is settings");

     //Setting Dialog Message
      alertDialog.setMessage("GPS is not enabled. Do you want to go to settings menu?");

     //On pressing Settings button
      alertDialog.setPositiveButton("Settings", new DialogInterface.OnClickListener() {
         public void onClick(DialogInterface dialog,int which) {
            Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
            mContext.startActivity(intent);
         }
      });

     //on pressing cancel button
      alertDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
         public void onClick(DialogInterface dialog, int which) {
            dialog.cancel();
         }
      });

     //Showing Alert Message
      alertDialog.show();
   }

   @Override
   public void onLocationChanged(Location location) {
   }

   @Override
   public void onProviderDisabled(String provider) {
   }

   @Override
   public void onProviderEnabled(String provider) {
   }

   @Override
   public void onStatusChanged(String provider, int status, Bundle extras) {
   }

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

以下は res/layout/activity_main.xml ファイルの内容です-

<?xml version = "1.0" encoding = "utf-8"?>
<LinearLayout xmlns:android = "http://schemas.android.com/apk/res/android"
   android:layout_width = "fill_parent"
   android:layout_height = "fill_parent"
   android:orientation = "vertical" >


   <Button
      android:id = "@+id/button"
      android:layout_width = "fill_parent"
      android:layout_height = "wrap_content"
      android:text = "getlocation"/>

</LinearLayout>

以下は、2つの新しい定数を定義する res/values/strings.xml の内容です-

<?xml version = "1.0" encoding = "utf-8"?>
<resources>
   <string name = "app_name">finddevguides</string>
</resources>

以下は、 AndroidManifest.xml のデフォルトのコンテンツです-

<?xml version = "1.0" encoding = "utf-8"?>
<manifest xmlns:android = "http://schemas.android.com/apk/res/android"
   package = "com.example.finddevguides7.myapplication">
   <uses-permission android:name = "android.permission.ACCESS_FINE_LOCATION"/>
   <uses-permission android:name = "android.permission.INTERNET"/>
   <application
      android:allowBackup = "true"
      android:icon = "@mipmap/ic_launcher"
      android:label = "@string/app_name"
      android:supportsRtl = "true"
      android:theme = "@style/AppTheme">

      <activity android:name = ".MainActivity">
         <intent-filter>
            <action android:name = "android.intent.action.MAIN"/>

            <category android:name = "android.intent.category.LAUNCHER"/>
         </intent-filter>
      </activity>
   </application>

</manifest>
*finddevguides* アプリケーションを実行してみましょう。 実際のAndroidモバイルデバイスをコンピューターに接続したと思います。 Android Studioからアプリを実行するには、プロジェクトのアクティビティファイルの1つを開き、ツールバーの[画像を実行:/android/images/eclipse_run.jpg [Eclipse Run Icon]アイコンをクリックします。 アプリケーションを開始する前に、Android Studioインストーラーは次のウィンドウを表示して、Androidアプリケーションを実行するオプションを選択します。

Androidモバイルデバイス

今場所を表示するには、次のように場所情報を表示しますGet Location Buttonを選択します-

Android Mobile Location Info