【Android Developers Training】 103. 查询当

系统 1722 0

注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好。

原文链接: http://developer.android.com/training/location/retrieve-current.html


地点服务自动维护用户当前的地点,所以你的应用所要做的事情就是在需要时去获取它。地点的精确度是基于你所申请的地点查询权限,以及当前设备上激活的的位置传感器。

地点服务会通过定位客户端(定位服务类的一个实例: LocationClient ),将当前的位置发送给你的应用,所有地点信息的请求都通过这一客户端。

Note:

在你开始这节课之前,请确定你的开发环境和测试设备都已经配置正确。可以阅读 Setup 获取更多这方面的信息。


一). 指定应用权限

使用位置服务的应用必须请求定位权限。Android有两个定位权限: ACCESS_COARSE_LOCATION (粗定位)和 ACCESS_FINE_LOCATION (精定位)。你所选择的权限决定了定位的精度。如果你只请求粗定位,位置服务所范围的地点信息大致会精确到一个城市街区。

如果请求 ACCESS_FINE_LOCATION ,它也暗含了 ACCESS_COARSE_LOCATION 的权限。

例如,要添加 ACCESS_COARSE_LOCATION ,将下面的代码作为 <manifest> 元素的子元素:

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

二). 检查Google Play服务

位置服务是Google Play服务APK的其中一部分。由于用户设备的状态时难以预料的,你应该一直在你尝试连接定位服务之前,检查APK是否已经安装。要检查APK是否安装,可以调用 GooglePlayServicesUtil.isGooglePlayServicesAvailable() ,它会返回一个整形的结果码,其含义可以参阅: ConnectionResult 。如果你遇到了一个错误,可以调用 GooglePlayServicesUtil.getErrorDialog() ,来获取一个本地的对话框,引导用户执行正确地行为,之后将这一对话框显示在一个 DialogFragment 上。这一对话框可能允许用户解决当前的问题,此时Google Play服务会发回一个结果到你的activity中。要处理这一结果,需要覆写 onActivityResult() 方法。

由于你一直需要在你的代码多个地方检查Google Play服务,所以应该定义一个方法将检查行为进行封装,之后在每次连接尝试之前进行检查。下面的代码片段包含了检查Google Play服务所需要的代码:

      
        public
      
      
        class
      
       MainActivity 
      
        extends
      
      
         FragmentActivity {

    ...

    
      
      
        //
      
      
         Global constants
      
      
        /*
      
      
        

     * Define a request code to send to Google Play services

     * This code is returned in Activity.onActivityResult

     
      
      
        */
      
      
        private
      
      
        final
      
      
        static
      
      
        int
      
      
        

            CONNECTION_FAILURE_RESOLUTION_REQUEST 
      
      = 9000
      
        ;

    ...

    
      
      
        //
      
      
         Define a DialogFragment that displays the error dialog
      
      
        public
      
      
        static
      
      
        class
      
       ErrorDialogFragment 
      
        extends
      
      
         DialogFragment {

        
      
      
        //
      
      
         Global field to contain the error dialog
      
      
        private
      
      
         Dialog mDialog;

        
      
      
        //
      
      
         Default constructor. Sets the dialog field to null
      
      
        public
      
      
         ErrorDialogFragment() {

            
      
      
        super
      
      
        ();

            mDialog 
      
      = 
      
        null
      
      
        ;

        }

        
      
      
        //
      
      
         Set the dialog to display
      
      
        public
      
      
        void
      
      
         setDialog(Dialog dialog) {

            mDialog 
      
      =
      
         dialog;

        }

        
      
      
        //
      
      
         Return a Dialog to the DialogFragment.
      
      
                @Override

        
      
      
        public
      
      
         Dialog onCreateDialog(Bundle savedInstanceState) {

            
      
      
        return
      
      
         mDialog;

        }

    }

    ...

    
      
      
        /*
      
      
        

     * Handle results returned to the FragmentActivity

     * by Google Play services

     
      
      
        */
      
      
        

    @Override

    
      
      
        protected
      
      
        void
      
      
         onActivityResult(

            
      
      
        int
      
       requestCode, 
      
        int
      
      
         resultCode, Intent data) {

        
      
      
        //
      
      
         Decide what to do based on the original request code
      
      
        switch
      
      
         (requestCode) {

            ...

            
      
      
        case
      
      
         CONNECTION_FAILURE_RESOLUTION_REQUEST :

            
      
      
        /*
      
      
        

             * If the result code is Activity.RESULT_OK, try

             * to connect again

             
      
      
        */
      
      
        switch
      
      
         (resultCode) {

                    
      
      
        case
      
      
         Activity.RESULT_OK :

                    
      
      
        /*
      
      
        

                     * Try the request again

                     
      
      
        */
      
      
        

                    ...

                    
      
      
        break
      
      
        ;

                }

            ...

        }

     }

    ...

    
      
      
        private
      
      
        boolean
      
      
         servicesConnected() {

        
      
      
        //
      
      
         Check that Google Play services is available
      
      
        int
      
       resultCode =
      
        

                GooglePlayServicesUtil.

                        isGooglePlayServicesAvailable(
      
      
        this
      
      
        );

        
      
      
        //
      
      
         If Google Play services is available
      
      
        if
      
       (ConnectionResult.SUCCESS ==
      
         resultCode) {

            
      
      
        //
      
      
         In debug mode, log the status
      
      

            Log.d("Location Updates"
      
        ,

                    
      
      "Google Play services is available."
      
        );

            
      
      
        //
      
      
         Continue
      
      
        return
      
      
        true
      
      
        ;

        
      
      
        //
      
      
         Google Play services was not available for some reason
      
      

        } 
      
        else
      
      
         {

            
      
      
        //
      
      
         Get the error code
      
      
        int
      
       errorCode =
      
         connectionResult.getErrorCode();

            
      
      
        //
      
      
         Get the error dialog from Google Play services
      
      

            Dialog errorDialog =
      
         GooglePlayServicesUtil.getErrorDialog(

                    errorCode,

                    
      
      
        this
      
      
        ,

                    CONNECTION_FAILURE_RESOLUTION_REQUEST);



            
      
      
        //
      
      
         If Google Play services can provide an error dialog
      
      
        if
      
       (errorDialog != 
      
        null
      
      
        ) {

                
      
      
        //
      
      
         Create a new DialogFragment for the error dialog
      
      

                ErrorDialogFragment errorFragment =

                        
      
        new
      
      
         ErrorDialogFragment();

                
      
      
        //
      
      
         Set the dialog in the DialogFragment
      
      
                        errorFragment.setDialog(errorDialog);

                
      
      
        //
      
      
         Show the error dialog in the DialogFragment
      
      
                        errorFragment.show(getSupportFragmentManager(),

                        
      
      "Location Updates"
      
        );

            }

        }

    }

    ...

}
      
    

在后续章节的代码片段中,都会调用这一方法来验证是否可获取Google Play服务。


三). 定义位置服务回调函数

要获取当前的地点,创建一个地点客户端,将它连接至定位服务,之后调用它的 getLastLocation() 方法。返回的值是最佳最新的地理位置,它基于你应用所请求的权限以及当前设备上已激活的定位传感器。

在你创建定位客户端之前,实现定位服务的接口,以和你的应用进行交互:

ConnectionCallbacks

指定当定位连接上或者没有连接上时,定位服务调用的方法。

OnConnectionFailedListener

指定当尝试连接到定位客户端时,如果出现了错误,定位服务调用的方法。这一方法使用之前定义的 showErrorDialog 方法来显示一个错误对话框,它尝试使用Google Play服务来解决这一问题。

下面的样例代码展示了如何指定接口和定义相关的函数:

      
        public
      
      
        class
      
       MainActivity 
      
        extends
      
       FragmentActivity 
      
        implements
      
      
        

        GooglePlayServicesClient.ConnectionCallbacks,

        GooglePlayServicesClient.OnConnectionFailedListener {

    ...

    
      
      
        /*
      
      
        

     * Called by Location Services when the request to connect the

     * client finishes successfully. At this point, you can

     * request the current location or start periodic updates

     
      
      
        */
      
      
        

    @Override

    
      
      
        public
      
      
        void
      
      
         onConnected(Bundle dataBundle) {

        
      
      
        //
      
      
         Display the connection status
      
      

        Toast.makeText(
      
        this
      
      , "Connected"
      
        , Toast.LENGTH_SHORT).show();



    }

    ...

    
      
      
        /*
      
      
        

     * Called by Location Services if the connection to the

     * location client drops because of an error.

     
      
      
        */
      
      
        

    @Override

    
      
      
        public
      
      
        void
      
      
         onDisconnected() {

        
      
      
        //
      
      
         Display the connection status
      
      

        Toast.makeText(
      
        this
      
      , "Disconnected. Please re-connect."
      
        ,

                Toast.LENGTH_SHORT).show();

    }

    ...

    
      
      
        /*
      
      
        

     * Called by Location Services if the attempt to

     * Location Services fails.

     
      
      
        */
      
      
        

    @Override

    
      
      
        public
      
      
        void
      
      
         onConnectionFailed(ConnectionResult connectionResult) {

        
      
      
        /*
      
      
        

         * Google Play services can resolve some errors it detects.

         * If the error has a resolution, try sending an Intent to

         * start a Google Play services activity that can resolve

         * error.

         
      
      
        */
      
      
        if
      
      
         (connectionResult.hasResolution()) {

            
      
      
        try
      
      
         {

                
      
      
        //
      
      
         Start an Activity that tries to resolve the error
      
      
                        connectionResult.startResolutionForResult(

                        
      
      
        this
      
      
        ,

                        CONNECTION_FAILURE_RESOLUTION_REQUEST);

                
      
      
        /*
      
      
        

                 * Thrown if Google Play services canceled the original

                 * PendingIntent

                 
      
      
        */
      
      
        

            } 
      
      
        catch
      
      
         (IntentSender.SendIntentException e) {

                
      
      
        //
      
      
         Log the error
      
      
                        e.printStackTrace();

            }

        } 
      
      
        else
      
      
         {

            
      
      
        /*
      
      
        

             * If no resolution is available, display a dialog to the

             * user with the error.

             
      
      
        */
      
      
        

            showErrorDialog(connectionResult.getErrorCode());

        }

    }

    ...

}
      
    

四). 连接定位客户端

现在回调函数已经就位了,创建定位客户端并且连接它至定位服务。

你应该在 onCreate() 方法中创建定位客户端,之后再 onStart() 方法中进行连接。这样定位服务就能在你的应用完全可见时维护当前的定位信息。在 onStop() 方法中关闭连接,这样当应用不可见时,定位服务就会停止更新地点。这样的连接方式还能节省电量。

Note:

只有在定位客户端连接到了定位服务后,当前的地点才能维护。假设没有其他应用连接到定位服务,如果你关闭了客户端,过一段时间后,调用了 getLastLocation() ,获得的结果可能将是过期的。

例如:

      
        public
      
      
        class
      
       MainActivity 
      
        extends
      
       FragmentActivity 
      
        implements
      
      
        

        GooglePlayServicesClient.ConnectionCallbacks,

        GooglePlayServicesClient.OnConnectionFailedListener {

    ...

    @Override

    
      
      
        protected
      
      
        void
      
      
         onCreate(Bundle savedInstanceState) {

        ...

        
      
      
        /*
      
      
        

         * Create a new location client, using the enclosing class to

         * handle callbacks.

         
      
      
        */
      
      
        

        mLocationClient 
      
      = 
      
        new
      
       LocationClient(
      
        this
      
      , 
      
        this
      
      , 
      
        this
      
      
        );

        ...

    }

    ...

    
      
      
        /*
      
      
        

     * Called when the Activity becomes visible.

     
      
      
        */
      
      
        

    @Override

    
      
      
        protected
      
      
        void
      
      
         onStart() {

        
      
      
        super
      
      
        .onStart();

        
      
      
        //
      
      
         Connect the client.
      
      
                mLocationClient.connect();

    }

    ...

    
      
      
        /*
      
      
        

     * Called when the Activity is no longer visible.

     
      
      
        */
      
      
        

    @Override

    
      
      
        protected
      
      
        void
      
      
         onStop() {

        
      
      
        //
      
      
         Disconnecting the client invalidates it.
      
      
                mLocationClient.disconnect();

        
      
      
        super
      
      
        .onStop();

    }

    ...

}
      
    

五). 获取当前地点

要获取当前地点,调用 getLastLocation() ,例如:

      
        public
      
      
        class
      
       MainActivity 
      
        extends
      
       FragmentActivity 
      
        implements
      
      
        

        GooglePlayServicesClient.ConnectionCallbacks,

        GooglePlayServicesClient.OnConnectionFailedListener {

    ...

    
      
      
        //
      
      
         Global variable to hold the current location
      
      
            Location mCurrentLocation;

    ...

    mCurrentLocation 
      
      =
      
         mLocationClient.getLastLocation();

    ...

}
      
    

在下一节课中,将会向你展示从定位服务定期地接受地点更新的方法。

【Android Developers Training】 103. 查询当前地点


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论