Android GPS 첫 경험
이 섹션 소개:
GPS라는 용어에 대해 말하자면, GPS 위성 위치 확인 기술, 즉 Android의 위치 확인 방법은 모두가 잘 알고 있을 것입니다. 일반적으로 GPS 포지셔닝, WIFI 포지셔닝, 기지국 포지셔닝, AGPS 포지셔닝(기지국 + GPS)의 네 가지 유형이 있습니다.
이 튜토리얼 시리즈는 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(위도 2배, 경도 2배, 부동 반경, 긴 만료, PendingIntent 인텐트): 중요한 경고 추가
- getAllProviders(): 모든 LocationProviders 목록 가져오기
- getBestProvider(기준 기준, 부울 활성화 전용): 지정된 조건
- getGpsStatus(GpsStatus 상태)에 따라 최상의 LocationProvider를 반환합니다. GPS 상태 가져오기
- getLastKnownLocation(문자열 공급자): LocationProvider
- getProvider(문자열 이름)를 기반으로 마지막으로 알려진 위치 가져오기: 이름
- getProviders(부울 활성화 전용)을 기반으로 LocationProvider 가져오기: 사용 가능한 모든 LocationProviders 가져오기 VGetProvider(Criteria Criteria, Boolean Enabledonly): 지정된 조건에 따라 모든 로컬 LocationsProvider
- isProvidEreenables(String PROVIDER)를 가져옵니다. 지정된 이름의 LocationProvider를 판단합니다. mremovegpsstatusListener (gpsstatus.Listener Listener) 사용 가능 여부 ): GPS 상태 리스너 제거
- removeProximityAlert (PendingIntent 인텐트): 근접 경고 제거
- requestLocationUpdates (long minTime, float minDistance, Criteria 기준, PendingIntent 인텐트): 지정된 LocationProvider를 통해 주기적으로 위치 정보를 얻고 Intent
- requestLocationUpdates (String 공급자, long minTime, float minDistance, LocationListener 리스너)를 통해 해당 구성 요소를 시작합니다. 지정된 LocationProvider를 통해 주기적으로 위치 정보를 얻고 리스너에 해당하는 트리거를 트리거합니다.
- 2) LocationProvider(위치 공급자) 공식 API 문서:
이것은 GPS 포지셔닝 구성 요소입니다. 추상 표현, 호출 포지셔닝 구성 요소의 관련 정보를 얻으려면 다음 방법을 사용하십시오!
일반적으로 사용되는 방법은 다음과 같습니다.- getAccuracy(): LocationProvider 정확도를 반환합니다.
- getName(): LocationProvider 이름을 반환합니다.
- getPowerRequirement(): LocationProvider의 전력 요구 사항을 가져옵니다.
- hasMonetaryCost(): 위치를 반환합니다. 공급자는 유료인가요, 무료인가요?
- meetsCriteria(기준 기준): LocationProvider가 기준 조건을 충족하는지 확인
- requiresCell(): LocationProvider가 네트워크 기지국에 액세스해야 하는지 여부를 결정
- requiresNetwork( ): LocationProvider가 네트워크 데이터에 액세스해야 하는지 여부를 결정합니다
- requireSatellite(): LocationProvider가 위성 기반 위치 확인 시스템에 액세스해야 하는지 여부를 결정합니다
- supportsAltitude(): LocationProvider가 고도 정보를 지원하는지 여부
- supportBearing(): LocationProvider가 방향 정보를 지원하는지 확인
- supportsSpeed(): LocationProvider가 속도 정보를 지원하는지 확인
3) Location(위치 정보)
공식 API 문서: Location
위치 정보의 추상 클래스, 관련 위치 정보를 얻기 위해 다음 메소드를 호출할 수 있습니다!
일반적으로 사용되는 메소드는 다음과 같습니다.
- float getAccuracy(): 위치 정보의 정확도를 가져옵니다.
- double getAltitude(): 위치 정보의 높이를 가져옵니다.
- float getBearing(): Get 위치 정보의 방향
- double getLatitude():获得定位信息적纬島
- double getLongitude():获得determin位信息的精島
- String getProvider():获得提供该位信息의 LocationProvider
- float getSpeed( ): 위치 정보를 얻는 속도
- boolean hasAccuracy(): 위치 정보에 정확도 정보가 포함되어 있는지 확인
4) 기준(필터 조건)
공식 API 문서: Criteria
Get LocationProvider 일 때 필터 조건을 설정할 수 있는데, 이는 이 클래스를 통해 관련 조건을 설정하는 것입니다~
일반적인 방법은 다음과 같습니다.
ㅋㅋㅋ 고도 정보 제공 방향 정보 제공- setCostAllowed(boolean costAllowed): LocationProvider가 방향 정보를 제공해야 하는지 여부를 설정
- setPowerRequirement(int level): LocationProvider에 필요한 전력 소비를 설정
- setSpeedRequired (boolean speedRequired): 속도 정보 제공을 위해 LocationProvider 요구 여부 설정
- 2. LocationProvider의 예 가져오기
- 렌더링 실행 :
- 그림에서 볼 수 있듯이 현재 사용 가능한 LocationProvider는 3개입니다. , 즉:
수동
: 수동적으로 제공, 다른 프로그램에서 제공
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(); } }
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는 야외에서 사용해야 하기 때문에 이번 기회에 달려봤습니다. 편의점에 가서 밀크티 한잔 마시고, 아래 스크린샷을 찍으세요~
requestLocationUpdates
(문자열 공급자, 긴 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, longexpiration, PendingIntentintent)
속성 설명:
- latitude: 고정점의 경도 지정
- longitude: 고정 지점 지정 지점의 위도
- 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 renders:
PS: 음, 10m를 설정했는데 B1에서 D1까지 걸어보니 10m가 넘더군요.. . 비가 내렸습니다