使用 runOnUiThread 获取当前位置

Posted

技术标签:

【中文标题】使用 runOnUiThread 获取当前位置【英文标题】:get current location with runOnUiThread 【发布时间】:2015-05-22 19:54:14 【问题描述】:

我是安卓的学习者。我正在尝试获取当前位置的天气。我的应用程序中有一个“刷新”按钮,可以使用最新的天气详细信息更新 UI。当应用程序加载时,它会显示 0.0、0.0 纬度和经度的天气。当我点击“刷新”按钮时,它会显示我当前位置的天气。应用程序加载时如何获取当前位置的天气?我已经使用 Google Play 服务来获取当前位置。下面是我的代码。

MainActivity.java

public class MainActivity extends ActionBarActivity implements GoogleApiClient.ConnectionCallbacks,
        GoogleApiClient.OnConnectionFailedListener 

    public String apiKey;
    public double latitude;
    public double longitude;
    public String forecastUrl;
    public static final String TAG = MainActivity.class.getSimpleName();
    private GoogleApiClient mGoogleApiClient;
    protected Location mLastLocation;

    public MainActivity() 
        apiKey = “XXXXXXXXXX";
    

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        buildGoogleApiClient();
        mRefreshImageView.setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View v) 
                getForecast();
            
        );
        getForecast();
    

    protected synchronized void buildGoogleApiClient() 
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();
    

    protected void onStart() 
        super.onStart();
        mGoogleApiClient.connect();
    

    protected void onResume() 
        super.onResume();
        mGoogleApiClient.connect();
    

    protected void onStop() 
        super.onStop();
        if (mGoogleApiClient.isConnected()) 
            mGoogleApiClient.disconnect();
        
    

    private void getForecast() 
        if (isNetworkAvailable()) 
            forecastUrl = “http://www.forecastUrlGoesHere.com/" + apiKey + “/“ + latitude + "," + longitude;
            toggleRefresh();

            OkHttpClient client = new OkHttpClient();
            Request request = new Request.Builder().url(forecastUrl).build();
            client.newCall(request).enqueue(new Callback() 
                @Override
                public void onFailure(Request request, IOException e) 
                    runOnUiThread(new Runnable() 
                        @Override
                        public void run() 
                            toggleRefresh();
                        
                    );
                

                @Override
                public void onResponse(Response response) throws IOException 
                    runOnUiThread(new Runnable() 
                        @Override
                        public void run() 
                            toggleRefresh();
                        
                    );
                    try 
                        String jsonData = response.body().string();
                        if (response.isSuccessful()) 
                            runOnUiThread(new Runnable() 
                                @Override
                                public void run() 
                                    updateView(); //updates the screen ui
                                
                            );
                         else 
                            alertUserAboutError();
                        
                     catch (IOException e) 
                        e.printStackTrace();
                     catch (JSONException e) 

                    
                
            );
         else 
            Toast.makeText(this, getString(R.string.network_error_message), Toast.LENGTH_LONG).show();
        
    

    private void updateView() 
    //code to update ui
    

    private boolean isNetworkAvailable() 
    //check network availability
    

    private void alertUserAboutError() 
        AlertDialogFragment dialog = new AlertDialogFragment();
        dialog.show(getFragmentManager(), "error_dialog");
    

    private void toggleRefresh() 
    

    @Override
    public void onConnected(Bundle bundle) 
        mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
        if (mLastLocation != null) 
            latitude = mLastLocation.getLatitude();
            longitude = mLastLocation.getLongitude();
            Toast.makeText(this, latitude + " " + longitude, Toast.LENGTH_LONG).show();
         else 
            Toast.makeText(this, getString(R.string.no_location_detected), Toast.LENGTH_LONG).show();
        
    

    @Override
    public void onConnectionSuspended(int i) 
        Log.i(TAG, "Connection suspended");
        mGoogleApiClient.connect();
    

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) 
        if (connectionResult.hasResolution()) 
            try 
                connectionResult.startResolutionForResult(this, 9000);
             catch (IntentSender.SendIntentException e) 
                e.printStackTrace();
            
         else 
            Log.i(TAG, "Connection failed, ERROR: " + connectionResult.getErrorCode());
        
    

【问题讨论】:

【参考方案1】:

嗯,有几种方法可以获得预期的结果。让我为其中一个写下步骤:

a) 使用 ProgressDialog 并在 onCreate 中启动它

b) 从 onCreate 中移动 getForecast()

c) 在 onConnected 方法中,一旦 lat 和 long 可用,检查 ProgressDialog 是否仍然可见。如果是,请关闭此对话框并调用 getForecast

ProgressDialog 链接 http://developer.android.com/reference/android/app/ProgressDialog.html

【讨论】:

【参考方案2】:

在您的onConnected 回调中,调用getForecast();

@Override
public void onConnected(Bundle bundle) 
    mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
    if (mLastLocation != null) 
        latitude = mLastLocation.getLatitude();
        longitude = mLastLocation.getLongitude();
        Toast.makeText(this, latitude + " " + longitude, Toast.LENGTH_LONG).show();
     else 
        Toast.makeText(this, getString(R.string.no_location_detected), Toast.LENGTH_LONG).show();
    

    getForecast();

【讨论】:

以上是关于使用 runOnUiThread 获取当前位置的主要内容,如果未能解决你的问题,请参考以下文章

Android中的runOnUiThread

如何正确实现runOnUiThread Android

android Activity runOnUiThread() 方法的使用

为啥在 runOnUiThread 做同样的事情时使用处理程序?

vue使用腾讯地图获取当前位置

使用 runOnUiThread在线程内更新UI