«

Android---58---初学GPS定位

时间:2024-3-2 19:12     作者:韩俊     分类: Android


GPS英文是Global Positioning System 全球定位系统的简称。

Android为GPS功能支持专门提供了一个LocationManager,位置管理器。所有GPS定位相关的服务、对象都将由该对象产生。


获取LocationManager实例:
LocationManager lm = (LocationManager)getSystemService (Context.LOCATION_SERVICE)

三个核心API:LocationManager、LocationProvider、Location

LocationManager提供如下方法:

boolean addGpsStatusListener(GpsStatus.Listener listener):添加一个监听GPS状态的监听器;

void addProximityAlert(double latitude,double longitude,float radius,long expiration,PendingIntent intent):添加一个临近警告;

List getAllProviders():获取所有的LocationProvider列表;
String getBestProvider(Criteria criteria,boolean enabledOnly):根据制定条件返回最优的LocationProvider对象;

GpsStatus getGpsStatus(GpsStatus status):获取GPS状态;

Location getLastKnownLocation(String provider):根据LocationProvider获取最近一次已知的Location;

LocationProvider getProvider(String name):根据名称来获取LocationProvider;

List getProviders(Criteria criteria,boolean enabledOnly):根据制定条件获取满足条件的全部LocationProvier的名称;
List getProviders(boolean enabledOnly):获取所有可用的LocationProvider;
boolean isProviderEnabled(String provider):判断制定名称的LocationProvider是否可用;

void removeGpsStatusListener(GpsStatus.Listener listener):删除GPS状态监听器;

void removeProximityAlert(PendingIntent intent):删除一个趋近警告;

void requestLocationUpdates(String provider,long minTime,float minDistance,PendingIntent intent):通过指定的LocationProvider周期性获取定位信息,并通过Intent启动相应的组件;

void requestLocationUpdates(String provider,long minTime,float minDistance,LcoationListener listener):通过指定的LocationProvider周期性的获取定位信息,并触发listener对应的触发器;

LocationProvider类

定位组件的抽象标识,通过它可以获取定位的相关信息;

提供如下常用方法:

String getName():返回该LocationProvider的名称;

int getAccuracy():返回该LocationProvider的精度;

int getPowerRequirement():返回该LocationProvider的电源需求;

boolean hasMonetaryCost():返回LocationProvider是收费还是免费;

boolean meetsCriteria(Criteria criteria):判断该LocationProvider是否满足Criteria条件;

boolean requiresCell():判断该LocationProvider是否需要访问网路基站;

boolean requiresNetword():判断该LocationProvider是否需要网路数据;

boolean requiresStatellite():判断该LocationProvider是否需要访问卫星的定位系统;

boolean supportsAltitude():判断该LocationProvider是否支持高度信息;

boolean supportsBearing():判断该LocationProvider是否支持方向信息;

boolean supportsSpeed():判断该LocationProvider是否支持速度信息;


LocationListener:位置监听器,监听位置变化,监听设备开关与状态

Location类

代表位置信息的抽象类;

提供如下方法来获取定位信息:

float getAccuracy():获取定位信息的精度;

double getAltitude():获取定位信息的高度;

float getBearing():获取定位信息的方向;

double getLatitude():获取定位信息的经度;

double getLongitude():获取定位信息的纬度;

String getProvider():获取提供该定位信息的LocationProvider;

float getSpeed():获取定位信息的速度;

boolean hasAccuracy():判断该定位信息是否有经度信息;

boolean hasAltitude():判断定位信息是否有高度信息;

boolean hasBearing():判断定位信息是否有方向信息;

boolean hasSpeed():判断定位信息是否有速度信息;


LocationListener:位置监听器,监听位置变化,监听设备开关与状态

步骤:
1.获取系统的LocationManager对象
2.使用LocationManager,通过指定LocationProvider来获取定位信息,定位信息由Location对象来表示
3.从Location对象中获取定位信息

下面是几个例子:

1.获取所有可用的LocationProvider:

布局文件:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.allproviderstest.AllProvidersTest" >

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/providerList" />

    <ListView
        android:id="@+id/providers"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >
    </ListView>

</LinearLayout>


Activity:

public class AllProvidersTest extends Activity {

    ListView providers;
    LocationManager lm;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_all_providers_test);
        providers = (ListView) findViewById(R.id.providers);
        lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

        List<String> providerNames = lm.getAllProviders();
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
                android.R.layout.simple_list_item_1, providerNames);

        providers.setAdapter(adapter);
    }
}


模拟器中所有可用的LocationProvider有两个:
passive:由LocationProvider.PASSIVE_PROVIDER常量表示
gps:由LocationProvider.GPS_PROVIDER常量表示。代表通过GPS获取定位信息的LocationProvider对象

还有一个名为network的LocationProvider,由LocationProvider.NETWORK_PROVIDER常量表示,
代表通过移动通信网络获取定位信息的LocationProvider对象。

2.通过名称来获取指定的LocationProvider:

例如:

获取基于GPS的LocationProvider:
LocationProvider locProvider = lm.getProvider(LocationManager.GPS_PROVIDER)

根据Criteria获得LocationProvider:

布局文件:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.freeproviderstest.FreeProvidersTest" >

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/providerList" />

    <ListView
        android:id="@+id/providers"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" />

</LinearLayout>


Activity:

public class FreeProvidersTest extends Activity {

    ListView providers;
    LocationManager lm;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_free_providers_test);

        providers = (ListView) findViewById(R.id.providers);
        lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

        // 创建一个LocationProvider的过滤条件
        Criteria cri = new Criteria();
        // 设置要求LocationProvider必须是免费的。
        cri.setCostAllowed(false);
        // 设置要求LocationProvider能提供高度信息
        cri.setAltitudeRequired(true);
        // 设置要求LocationProvider能提供方向信息
        cri.setBearingRequired(true);
        // 获取系统所有复合条件的LocationProvider的名称
        List<String> providerNames = lm.getProviders(cri, false);
        System.out.println(providerNames.size());
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
                android.R.layout.simple_list_item_1, providerNames);
        // 使用ListView来显示所有可用的LocationProvider
        providers.setAdapter(adapter);
    }
}


3.
获取定位数据:


通过模拟器发送GPS信息:

启动模拟器之后,在DDMS下的Emulator Control 面板即可发送GPS定位信息。

布局文件:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.locationtest.LocationTest" >

    <EditText
        android:id="@+id/show"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:cursorVisible="false"
        android:editable="false" />

</LinearLayout>


Activity:

public class LocationTest extends Activity {

    // 定义LocationManager对象
    LocationManager locManager;
    // 定义程序界面中的EditText组件
    EditText show;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_location_test);

        show = (EditText) findViewById(R.id.show);
        locManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        // 从GPS获取最近的最近的定位信息
        Location location = locManager
                .getLastKnownLocation(LocationManager.GPS_PROVIDER);
        // 使用location根据EditText的显示
        updateView(location);// 设置每3秒获取一次GPS的定位信息
        locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 3000,
                8, new LocationListener() // ①
                {
                    @Override
                    public void onLocationChanged(Location location) {
                        // 当GPS定位信息发生改变时,更新位置
                        updateView(location);
                    }

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

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

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

    // 更新EditText中显示的内容
    public void updateView(Location newLocation) {
        if (newLocation != null) {
            StringBuilder sb = new StringBuilder();
            sb.append("实时的位置信息:n");
            sb.append("经度:");
            sb.append(newLocation.getLongitude());
            sb.append("n纬度:");
            sb.append(newLocation.getLatitude());
            sb.append("n高度:");
            sb.append(newLocation.getAltitude());
            sb.append("n速度:");
            sb.append(newLocation.getSpeed());
            sb.append("n方向:");
            sb.append(newLocation.getBearing());
            show.setText(sb.toString());
        } else {
            // 如果传入的Location对象为空则清空EditText
            show.setText("");
        }
    }
}



4.
临近警告:
通过LocationManager.addProximityAlert(double latitude,double longitude , float radius , long expiration ,PendingIntent intent)添加一个临近警告

参数:

latitude:指定固定点的经度
longitude:指定固定点的纬度
radius:半径长度
expiration:该参数指定经过多少毫秒后该临近警告就会过期失效
intent:该参数指定临近该固定点时出发该intent对应的组件。


布局文件:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.proximitytest.ProximityTest" >

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/hello" />

</LinearLayout>


Activity:

public class ProximityTest extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_proximity_test);
        // 定位服务常量
                String locService = Context.LOCATION_SERVICE;
                // 定位服务管理器实例
                LocationManager locationManager;
                // 通过getSystemService方法获得LocationManager实例
                locationManager = (LocationManager) getSystemService(locService);
                // 定义山东淄博的大致经度、纬度
                double longitude = 117.3;
                double latitude = 36.5;
                // 定义半径(5公里)
                float radius = 5000;
                // 定义Intent
                Intent intent = new Intent(this, ProximityAlertReciever.class);
                // 将Intent包装成PendingIntent
                PendingIntent pi = PendingIntent.getBroadcast(this, -1, intent, 0);
                // 添加临近警告
                locationManager.addProximityAlert(latitude, longitude, radius, -1, pi);
    }
}


ProximityAlertReciever:

public class ProximityAlertReciever extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        // 获取是否为进入指定区域
        boolean isEnter = intent.getBooleanExtra(
                LocationManager.KEY_PROXIMITY_ENTERING, false);
        if (isEnter) {
            // 显示提示信息
            Toast.makeText(context, "您已经进入广州天河区", Toast.LENGTH_LONG).show();
        } else {
            // 显示提示信息
            Toast.makeText(context, "您已经离开广州天河区", Toast.LENGTH_LONG).show();
        }
    }
}


标签: android

热门推荐