13.3.3. 重构StatusActivity

优质
小牛编辑
130浏览
2023-12-01

13.3.3.重构StatusActivity

StatusActivity是位置信息。同WhereAmI一样,我们仍调用LocationManager的getSystemService(),并注册到位置服务,订阅其更新。也同样实现一个LocationListener接口,也就意味着需要在Activity里面添加几个回调方法,好在位置变化时得到新的location对象。到下次更新状态的时候,即可在这里看到我们的位置信息。

例 13.8. StatusActivity.java

package com.marakana.yamba8;

import winterwell.jtwitter.Twitter;

import android.graphics.Color;

import android.location.Location;

import android.location.LocationListener;

import android.location.LocationManager;

import android.os.AsyncTask;

import android.os.Bundle;

import android.text.Editable;

import android.text.TextWatcher;

import android.util.Log;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.Button;

import android.widget.EditText;

import android.widget.TextView;

import android.widget.Toast;

public class StatusActivity extends BaseActivity implements OnClickListener,

TextWatcher, LocationListener { //

private static final String TAG = "StatusActivity";

private static final long LOCATION_MIN_TIME = 3600000; // One hour

private static final float LOCATION_MIN_DISTANCE = 1000; // One kilometer

EditText editText;

Button updateButton;

TextView textCount;

LocationManager locationManager; //

Location location;

String provider;

/** Called when the activity is first created. */

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.status);

// Find views

editText = (EditText) findViewById(R.id.editText);

updateButton = (Button) findViewById(R.id.buttonUpdate);

updateButton.setOnClickListener(this);

textCount = (TextView) findViewById(R.id.textCount);

textCount.setText(Integer.toString(140));

textCount.setTextColor(Color.GREEN);

editText.addTextChangedListener(this);

}

@Override

protected void onResume() {

super.onResume();

// Setup location information

provider = yamba.getProvider(); //

if (!YambaApplication.LOCATION_PROVIDER_NONE.equals(provider)) { //

locationManager = (LocationManager) getSystemService(LOCATION_SERVICE); //

}

if (locationManager != null) {

location = locationManager.getLastKnownLocation(provider); //

locationManager.requestLocationUpdates(provider, LOCATION_MIN_TIME,

LOCATION_MIN_DISTANCE, this); //

}

}

@Override

protected void onPause() {

super.onPause();

if (locationManager != null) {

locationManager.removeUpdates(this); //

}

}

// Called when button is clicked

public void onClick(View v) {

String status = editText.getText().toString();

new PostToTwitter().execute(status);

Log.d(TAG, "onClicked");

}

// Asynchronously posts to twitter

class PostToTwitter extends AsyncTask<String, Integer, String> {

// Called to initiate the background activity

@Override

protected String doInBackground(String...statuses) {

try {

// Check if we have the location

if (location != null) { //

double latlong[] = {location.getLatitude(), location.getLongitude()};

yamba.getTwitter().setMyLocation(latlong);

}

Twitter.Status status = yamba.getTwitter().updateStatus(statuses[0]);

return status.text;

} catch (RuntimeException e) {

Log.e(TAG, "Failed to connect to twitter service", e);

return "Failed to post";

}

}

// Called once the background activity has completed

@Override

protected void onPostExecute(String result) {

Toast.makeText(StatusActivity.this, result, Toast.LENGTH_LONG).show();

}

}

// TextWatcher methods

public void afterTextChanged(Editable statusText) {

int count = 140 - statusText.length();

textCount.setText(Integer.toString(count));

textCount.setTextColor(Color.GREEN);

if (count < 10)

textCount.setTextColor(Color.YELLOW);

if (count < 0)

textCount.setTextColor(Color.RED);

}

public void beforeTextChanged(CharSequence s, int start, int count, int after) {

}

public void onTextChanged(CharSequence s, int start, int before, int count) {

}

// LocationListener methods

public void onLocationChanged(Location location) { //

this.location = location;

}

public void onProviderDisabled(String provider) { //

if (this.provider.equals(provider))

locationManager.removeUpdates(this);

}

public void onProviderEnabled(String provider) { //

if (this.provider.equals(provider))

locationManager.requestLocationUpdates(this.provider, LOCATION_MIN_TIME,

LOCATION_MIN_DISTANCE, this);

}

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

}

}

  1. 令StatusActivity实现LocationListener,也就是供LocationManager回调的接口。
  2. 定义几个私有变量,分别表示LocationManager、Location对象与位置信息源(Provider)。
  3. 获取YambaApplication对象提供的位置信息源(Provider)。使用哪个信息源由用户在首选项中决定。
  4. 检查用户是否愿意发布自己的位置信息。
  5. 如果检查通过,就使用getSystemService()获取位置信息。这个调用只是获得现有系统服务的引用,因此它的代价并不是很高昂。
  6. 如果可以,获取缓存中的位置信息。
  7. 注册到LocationManager,订阅位置的更新。在这里,我们可以为位置变化指明一个时间间隔以及位置间距。我们只关心城市级别的位置变化,因此将间距的值定为一千米,时间间隔定为一小时(3,600,000微秒)。留意这只是给系统的一个提示,而非强制。
  8. 在用户发布消息时,检查当前是否有位置信息存在。如果有,就把它放在一个double类型的数组里,传给Twitter对象的setMyLocation()方法。
  9. 实现LocationManager触发的回调方法,onLocationChanged()。它在位置变化时触发,以一个新的Location对象作为参数。
  10. 这个方法在位置信息源不可用时触发。我们可以在这里注销订阅,以节约电能。
  11. 在位置信息源可用时,重新订阅位置信息的更新。
  12. 这个方法在位置信息源变化时触发,在此留空。

到这里,Yamba已经实现了位置更新的功能。用户可以设置首选项,按自己的意愿选择位置信息源,也可以关闭这个功能。

接下来看下另一个系统服务:Alarm服务,我们将通过它来触发IntentService。