Android GPS の初体験


このセクションの紹介:

GPS という用語について言えば、GPS 全地球測位技術、つまり Android での測位方法については誰もがよく知っていると思います。 一般に、GPS 測位、WIFI 測位、基地局測位、AGPS 測位 (基地局 + GPS) の 4 つのタイプがあります

この一連のチュートリアルでは、GPS 測位の基本的な使用法のみを説明します。 GPS は衛星と通信してデバイスの現在の経度と緯度を取得します。これは正確です 度数は比較的高いですが、デメリットもいくつかあります。 最大のデメリットは屋内ではほぼ使用不可…衛星4機以上の受信が必要です。 この信号により、GPS の正確な測位が保証されます。ただし、屋外にいてネットワークがない場合でも、GPS は使用できます。

このセクションでは、Android での GPS の基本的な使用方法について説明します~


1. 測位関連の API


1) LocationManager

公式 API ドキュメント: LocationManager

これはシステムですサービスは提供されますが、直接新規にすることはできません。必要なものは次のとおりです:

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

さらに、GPS 測位を使用するときは権限を追加することを忘れないでください:

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

さて、LocationManager オブジェクトを取得した後、次の一般的なメソッドを呼び出すことができます。

  • addGpsStatusListener(GpsStatus.Listener リスナー): GPS ステータス リスナーを追加します
  • addProximityAlert(倍緯度、倍経度、浮動小数点数半径、長い有効期限、PendingIntent インテント): 重要な警告を追加します
  • getAllProviders(): すべての LocationProvider のリストを取得します
  • getBestProvider(Criteria criteria、boolean EnabledOnly): 指定された条件に従って最適な LocationProvider を返します
  • getGpsStatus(GpsStatus status): GPS ステータスを取得します
  • getLastKnownLocation(文字列プロバイダー): LocationProvider に基づいて最後の既知の場所を取得します
  • getProvider(文字列名): 名前に基づいて LocationProvider を取得します
  • getProviders(ブール値有効のみ):利用可能なLocationProvider
  • をすべて取得 VGetProvider(Criteria Criteria、Boolean Enabledonly): 指定した条件に従ってローカルのLocationProvider
  • isProvidEreenables(String PROVIDER)をすべて取得: 指定された名前のLocationProviderを判定 mremovegpsstatusListener
  • (GPSSTATUS.Listener Listener)が使用可能かどうかを判定): GPS ステータス リスナーを削除します
  • removeProximityAlert
  • (PendingIntent インテント): 近接警告を削除します
  • requestLocationUpdates
  • (long minTime、float minDistance、Criteria 条件、PendingIntent インテント): 指定された LocationProvider を通じて位置情報を定期的に取得し、Intent
  • requestLocationUpdates
  • (String Provider、long minTime、Float minDistance、LocationListener リスナー) を通じて対応するコンポーネントを開始します。 指定された LocationProvider を通じて位置情報を定期的に取得し、リスナーに対応するトリガーをトリガーします
  • 2) LocationProvider (位置プロバイダー)
  • 公式 API ドキュメント:
LocationProvider

これは GPS 測位コンポーネントです の抽象表現, 次のメソッドを呼び出すことで、位置決めコンポーネントの関連情報を取得できます。

一般的に使用される方法は次のとおりです:

  • getAccuracy(): LocationProvider の精度を返します
  • getName(): LocationProvider 名を返します
  • getPowerRequirement(): LocationProvider の電力要件を取得します
  • hasMonetaryCost():場所を返しますプロバイダーは有料ですか?
  • meetsCriteria(Criteria criteria): LocationProvider が Criteria 条件を満たすかどうかを判断します
  • requiresCell(): LocationProvider がネットワーク基地局にアクセスする必要があるかどうかを判断します
  • requiresNetwork( ): LocationProvider がネットワーク データにアクセスする必要があるかどうかを決定します
  • RequiredSatellite(): LocationProvider が衛星ベースの測位システムにアクセスする必要があるかどうかを決定します
  • supportsAltitude(): LocationProvider が高度情報をサポートしているかどうかを決定します
  • supportBearing(): LocationProvider が方向情報をサポートしているかどうかを決定します
  • supportsSpeed() : LocationProvider が速度情報をサポートしているかどうかを決定します

3) Location (位置情報)

公式 API ドキュメント: Location

位置情報の抽象クラス。次のメソッドを呼び出して、関連する位置情報を取得できます。

よく使われるメソッドは以下の通りです。

  • float getAccuracy(): 位置情報の精度を取得
  • double getAltitude(): 位置情報の高さを取得
  • float getBearing(): Get位置情報の方向
  • double getLatitude():位置情報の精度を取得
  • double getLongitude():位置情報の精度を取得
  • String getProvider():位置情報の提供するLocationProviderを取得
  • float getSpeed(): 位置情報の取得速度
  • boolean hasAccuracy(): 位置情報に精度情報が含まれているかどうかを判定

4) 基準(フィルター条件)

公式APIドキュメント: Criteria

Get LocationProvider When では、フィルター条件を設定できます。これは、このクラスを通じて関連する条件を設定することです~

一般的なメソッドは次のとおりです:

  • setAccuracy(int precision): 精度要件を設定します
  • setAltitudeRequired(boolean AltitudeRequired): LocationProvider が高度情報を提供する必要があるかどうかを設定します
  • setBearingRequired(boolean bearingRequired): LocationProvider が必要かどうかを設定します高度情報を提供する 方向情報を提供する
  • setCostAllowed(booleancostAllowed): LocationProviderが方向情報を提供する必要があるかどうかを設定します
  • setPowerRequirement(int level): LocationProviderの必要な電力消費を設定します
  • setSpeedRequired (boolean SpeedRequired): 速度情報を提供するために LocationProvider を要求するかどうかを設定します

2. LocationProvider の例を取得します

レンダリングの実行:

1.gif

写真からわかるように、現在利用可能な LocationProvider が 3 つあります。 、つまり:

  • passive : 他のプログラムによって提供される、受動的に提供される
  • gps: GPS を通じて位置情報を取得する
  • network: ネットワークを通じて位置情報を取得する

実装コード :

レイアウト ファイル:

activity_main.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <Button
        android:id="@+id/btn_one"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="获得系统所有的LocationProvider" />

    <Button
        android:id="@+id/btn_two"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="根据条件获取LocationProvider" />

    <Button
        android:id="@+id/btn_three"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="获取指定的LocationProvider" />

    <TextView
        android:id="@+id/tv_result"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="10dp"
        android:background="#81BB4D"
        android:padding="5dp"
        android:textColor="#FFFFFF"
        android:textSize="20sp"
        android:textStyle="bold" /></LinearLayout>

MainActivity.java:

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private Button btn_one;
    private Button btn_two;
    private Button btn_three;
    private TextView tv_result;
    private LocationManager lm;
    private List pNames = new ArrayList(); // 存放LocationProvider名称的集合

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        bindViews();
    }

    private void bindViews() {
        btn_one = (Button) findViewById(R.id.btn_one);
        btn_two = (Button) findViewById(R.id.btn_two);
        btn_three = (Button) findViewById(R.id.btn_three);
        tv_result = (TextView) findViewById(R.id.tv_result);

        btn_one.setOnClickListener(this);
        btn_two.setOnClickListener(this);
        btn_three.setOnClickListener(this);
    }


    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_one:
                pNames.clear();
                pNames = lm.getAllProviders();
                tv_result.setText(getProvider());
                break;
            case R.id.btn_two:
                pNames.clear();
                Criteria criteria = new Criteria();
                criteria.setCostAllowed(false);   //免费
                criteria.setAltitudeRequired(true);  //能够提供高度信息
                criteria.setBearingRequired(true);   //能够提供方向信息
                pNames = lm.getProviders(criteria, true);
                tv_result.setText(getProvider());
                break;
            case R.id.btn_three:
                pNames.clear();
                pNames.add(lm.getProvider(LocationManager.GPS_PROVIDER).getName()); //指定名称
                tv_result.setText(getProvider());
                break;
        }
    }

    //遍历数组返回字符串的方法
    private String getProvider(){
        StringBuilder sb = new StringBuilder();
        for (String s : pNames) {
            sb.append(s + "\n");
        }
        return sb.toString();
    }
}


3. GPS がオンになっているかどうかを確認する、および GPS をオンにする 2 つの方法

GPS 測位を使用する前に、最初に行う必要があるのは、 GPS がオンになっているか、オンになっていない場合は、出発する必要があります。 GPSをオンにして位置測位を完了します。ここでは AGPS は考慮されていません~


1) GPS が利用可能かどうかを確認します
private boolean isGpsAble(LocationManager lm){
    return lm.isProviderEnabled(android.location.LocationManager.GPS_PROVIDER)?true:false;
}


2) GPS がオンになっていないことを検出し、GPS をオンにします

方法 1: GPS を強制的にオンにする、役に立たないAndroid 5.0 以降 ...

//强制帮用户打开GPS 5.0以前可用
private void openGPS(Context context){
    Intent gpsIntent = new Intent();
    gpsIntent.setClassName("com.android.settings", "com.android.settings.widget.SettingsAppWidgetProvider");
    gpsIntent.addCategory("android.intent.category.ALTERNATIVE");
    gpsIntent.setData(Uri.parse("custom:3"));
    try {
        PendingIntent.getBroadcast(LocationActivity.this, 0, gpsIntent, 0).send();
    } catch (PendingIntent.CanceledException e) {
        e.printStackTrace();
    }
}

方法 2: GPS 位置情報設定ページを開き、ユーザーが自分で開かせる

//打开位置信息设置页面让用户自己设置
private void openGPS2(){
    Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
    startActivityForResult(intent,0);
}
4. 位置情報を動的に取得する

これは非常に簡単で、requestLocationUpdates を呼び出すだけです。定期的に位置を検出するために LocationListener を設定するメソッドです。

サンプルコードは次のとおりです:

Layout:

activity_location.xml

:

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

    <TextView
        android:id="@+id/tv_show"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:padding="5dp"
        android:textSize="20sp"
        android:textStyle="bold" /></LinearLayout>
LocationActivity.java:

/**
 * Created by Jay on 2015/11/20 0020.
 */
public class LocationActivity extends AppCompatActivity {

    private LocationManager lm;
    private TextView tv_show;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_location);
        tv_show = (TextView) findViewById(R.id.tv_show);
        lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        if (!isGpsAble(lm)) {
            Toast.makeText(LocationActivity.this, "请打开GPS~", Toast.LENGTH_SHORT).show();
            openGPS2();
        }
        //从GPS获取最近的定位信息
        Location lc = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
        updateShow(lc);
        //设置间隔两秒获得一次GPS定位信息
        lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 2000, 8, new LocationListener() {
            @Override
            public void onLocationChanged(Location location) {
                // 当GPS定位信息发生改变时,更新定位
                updateShow(location);
            }

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

            }

            @Override
            public void onProviderEnabled(String provider) {
                // 当GPS LocationProvider可用时,更新定位
                updateShow(lm.getLastKnownLocation(provider));
            }

            @Override
            public void onProviderDisabled(String provider) {
                updateShow(null);
            }
        });
    }


    //定义一个更新显示的方法
    private void updateShow(Location location) {
        if (location != null) {
            StringBuilder sb = new StringBuilder();
            sb.append("当前的位置信息:\n");
            sb.append("精度:" + location.getLongitude() + "\n");
            sb.append("纬度:" + location.getLatitude() + "\n");
            sb.append("高度:" + location.getAltitude() + "\n");
            sb.append("速度:" + location.getSpeed() + "\n");
            sb.append("方向:" + location.getBearing() + "\n");
            sb.append("定位精度:" + location.getAccuracy() + "\n");
            tv_show.setText(sb.toString());
        } else tv_show.setText("");
    }


    private boolean isGpsAble(LocationManager lm) {
        return lm.isProviderEnabled(android.location.LocationManager.GPS_PROVIDER) ? true : false;
    }


    //打开设置页面让用户自己设置
    private void openGPS2() {
        Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
        startActivityForResult(intent, 0);
    }

}

さて、GPSは屋外で使用する必要があるため、非常に簡単なので、この機会に実行してみましたミルクティーを買いにコンビニへ行きました。 以下のスクリーンショットを撮ってください~

2.png3..png

4.png

requestLocationUpdates

(文字列プロバイダー、long minTime、float minDistance、LocationListener リスナー)

時間が minTime (単位: ミリ秒) を超えるか、位置の移動が minDistance (単位: メートル) を超える場合、リスナー内のメソッドが呼び出されて GPS 情報が更新されます。minTime は 60000 以上であることをお勧めします。これは 1 分で、より効率的で電気代の節約になります。必要な分だけ参加してください。 GPS をリアルタイムで更新するには、minTime と minDistance を 0 に設定します

ちなみに、許可も必要です:

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

5 近接警告 (ジオフェンシング)

ポイントを固定するには、携帯電話とポイントの間の距離が指定された範囲未満になったときに、対応する処理をトリガーできます。 ジオフェンシングのようなものです...LocationManager の addProximityAlert メソッドを呼び出して、近接アラートを追加できます。 完全なメソッドは次のとおりです:

addProximityAlert(double latitude、double longitude、float radius、long Expiration、PendingIntent Intent)

属性の説明:

  • latitude: 固定点の経度を指定します
  • 経度: 固定点を指定します 点の緯度
  • radius: 半径の長さを指定します
  • expiration: 近接警告が期限切れになるまでのミリ秒を指定します。-1 は期限切れしないことを意味します
  • intent : このパラメータは固定小数点への近接度を指定します インテントに対応するコンポーネントがトリガーされたとき

サンプルコードは以下の通りです:

ProximityActivity.java:

/**
 * Created by Jay on 2015/11/21 0021.
 */
public class ProximityActivity extends AppCompatActivity {
    private LocationManager lm;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_proximity);
        lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        //定义固定点的经纬度
        double longitude = 113.56843;
        double latitude = 22.374937;
        float radius = 10;     //定义半径,米
        Intent intent = new Intent(this, ProximityReceiver.class);
        PendingIntent pi = PendingIntent.getBroadcast(this, -1, intent, 0);
        lm.addProximityAlert(latitude, longitude, radius, -1, pi);
    }
}

ブロードキャストレシーバーの登録も必要です:ProximityReceiver.java:

/**
 * Created by Jay on 2015/11/21 0021.
 */
public class ProximityReceiver extends BroadcastReceiver{
    @Override
    public void onReceive(Context context, Intent intent) {
        boolean isEnter = intent.getBooleanExtra( LocationManager.KEY_PROXIMITY_ENTERING, false);
        if(isEnter) Toast.makeText(context, "你已到达南软B1栋附近", Toast.LENGTH_LONG).show();
        else Toast.makeText(context, "你已离开南软B1栋附近", Toast.LENGTH_LONG).show();
    }
}

登録を忘れないでください:

<receiver android:name=".ProximityReceiver"/>

Operation renderings:

PS: さて、10mに設定しましたが、B1からD1まで歩いたら10m以上でした。雨が降りました

6.png 6.png


6. ベンセクションのサンプルコードのダウンロード

GPSDemo.zip


このセクションの概要:

さて、このセクションでは GPS 測位の基本的な使い方を紹介します。 Android の場合は非常に簡単です。コンテンツ部分を参照してください。 Li Gang 先生の「Android Crazy 講義ノート」では、サンプルにいくつかの変更を加え、ユーザビリティ テストを実施しました。 このセクションはここまでです、ありがとうございました~6.jpg