ラベル apllication の投稿を表示しています。 すべての投稿を表示
ラベル apllication の投稿を表示しています。 すべての投稿を表示

2014年3月30日日曜日

SwipeRefreshLayoutを使ってSwipe更新を実装する

Layoutの作成

レイアウトはandroid.support.v4.widget.SwipeRefreshLayoutを使用します。
コンテンツはSwipeRefreshLayoutの子Viewとして記述します。

<android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/swipe_refresh_widget"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    
    <!-- some full screen pullable view that will be the offsetable content -->

    <ListView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/content"/>
</android.support.v4.widget.SwipeRefreshLayout>


Swipeによる更新

Swipeによる更新は次のように行います。
1. 更新開始タイミングをハンドルするために、setOnRefreshListenerメソッドにリスナーをセット
2. onRefresh()で更新開始をハンドリング
3. 更新処理が終わったら、setRefreshing(false)をコールする


 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.sample_swipe_refresh_widget);
  mSwipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_refresh_widget);
  mSwipeRefreshLayout.setOnRefreshListener(this);
 }


 @Override
 public void onRefresh() {
  refresh();
 }

 private void refresh() {
  Message msg = mHander.obtainMessage(0, this);
  mHander.sendMessageDelayed(msg, 1000);
 }

 private static Handler mHander = new Handler() {
  @Override
  public void handleMessage(Message msg) {
   SwipeRefreshLayoutActivity activity = (SwipeRefreshLayoutActivity) msg.obj;
   activity.mSwipeRefreshLayout.setRefreshing(false);
  }
 };

2014年3月3日月曜日

GeoFenceの解除

GeoFenceの解除は次のような手順で行います。

1. LocationClientクラスのconnectメソッドをコールして、Location Serviceに接続
2. 接続完了後、removeGeofencesメソッドをコールして、GeoFenceを解除
3. 解除結果はOnRemoveGeofencesResultListenerリスナーで受け取る

removeGeofencesメソッドは2種類あり、GeoFenceのIDを指定(リクエストID)するメソッドとPendingIntentを指定するメソッドがあります。

public void removeGeofences(List<String> geofenceRequestIds,
                            LocationClient.OnRemoveGeofencesResultListener listener)

public void removeGeofences(PendingIntent pendingIntent,
                            LocationClient.OnRemoveGeofencesResultListener listener)


次はGeoFenceのIDを指定(リクエストID)して解除を行うプログラムです。

    @Override
    public void onConnected(Bundle bundle) {
        super.onConnected(bundle);

        Bundle fragmentBundle = getArguments();
        ArrayList<GeoFenceData> list = fragmentBundle.getParcelableArrayList(GEOFENCE_DATA);

        List<String> idList = new ArrayList<String>();
        for (GeoFenceData data : list) {
            idList.add(data.getId());
        }

        getLocationClient().removeGeofences(idList, mOnRemoveGeofencesResultListener);

    }


指定するクラスにより、OnRemoveGeofencesResultListenerリスナーの呼ばれるメソッドが異なります。

メソッド内容
onRemoveGeofencesByPendingIntentResultGeoFenceのID指定による削除用
onRemoveGeofencesByRequestIdsResultPendingIntent指定による削除用


次はonRemoveGeofencesByRequestIdsResultメソッドで結果を受け取るプログラムです。

    private OnRemoveGeofencesResultListener mOnRemoveGeofencesResultListener = new OnRemoveGeofencesResultListener() {

        @Override
        public void onRemoveGeofencesByPendingIntentResult(int statusCode,
                PendingIntent pendingIntent) {
            // TODO Auto-generated method stub

        }

        @Override
        public void onRemoveGeofencesByRequestIdsResult(int statusCode, String[] geofenceRequestIds) {
            switch (statusCode) {
                case LocationStatusCodes.SUCCESS:
                    Toast.makeText(getActivity(), "LocationStatusCodes.SUCCESS", Toast.LENGTH_LONG)
                            .show();
                    break;
                case LocationStatusCodes.GEOFENCE_NOT_AVAILABLE:
                case LocationStatusCodes.GEOFENCE_TOO_MANY_GEOFENCES:
                case LocationStatusCodes.GEOFENCE_TOO_MANY_PENDING_INTENTS:
                case LocationStatusCodes.ERROR:
                    break;
                default:
                    break;
            }
            mLocationClient.disconnect();
            mOnGeoFenceRemoverInterface.onGeoFenceRemoved();
        }

    };

2014年2月20日木曜日

位置情報取得に利用するLocationClient

位置情報を取得するにはLocationManagerが提供されていますが、GPSとWiFiの設定に依存してLocationProviderの切り替えが必要でした。Google Play services APKが提供するLocation Serviceを使用すれば、Providerを考慮することなく位置情報を取得することができます。



Permissionの設定

Location Serviceを使用すには、AndroidManifest.xmlにPermissionの記載が必要です。LocationManagerと同様に、位置情報の精度に応じてPermissionが異なります。

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


LocationClientの接続

Location Serviceを使用するには、LocationClientクラスの生成が必要です。

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

第2引数にConnectionCallbacksインターフェイス、第3引数にOnConnectionFailedListenerインターフェイスをセットします。ConnectionCallbacksインターフェイスは、LocationClientがLocation Serviceに接続 / 切断した際にコールされます。OnConnectionFailedListenerは何らかのエラーが発生した場合にコールされます。

LocationClientの接続要求はLocationClient#connectメソッドをコールします。

     @Override
    protected void onStart() {
        super.onStart();
        if (isGooglePlayServicesAvailable()) {
            if (!mLocationClient.isConnected()) {
                mLocationClient.connect();
            }
        }
    }

接続に成功すると、mConnectionCallbacks#onConnectedがコールされます。



LocationRequestの生成

LocationClientの接続が成功した後に、requestLocationUpdatesメソッドをコールし位置情報の取得要求を行います。

 @Override
public void onConnected(Bundle bundle) {
    mLocationClient.requestLocationUpdates(mLocationRequest, mLocationListener);
}

第1引数にLocationRequestクラスを、第2引数にLocationListenerインターフェイスをセットします。LocationRequestクラスは次のようなセットモジュールを提供します。

メソッド内容
setInterval位置情報の更新間隔をmsで指定
setPriorityプライオリティ(精度)の指定
setExpirationDuration要求の期間(動作時間を)msで指定
setFastestInterval位置情報の最速更新間隔をmsで指定
setSmallestDisplacement最小移動距離をmで指定(指定メートル移動したら更新)


位置情報の取得

位置情報はmLocationListener#onLocationChangedメソッドにてAndroid OSから受け取ります。位置情報はLocationクラスとして取得します。

 private LocationListener mLocationListener = new LocationListener() {

    @Override
    public void onLocationChanged(Location location) {
    }

};


LocationClientの停止

位置情報の更新を停止するには、LocationClientクラスのremoveLocationUpdatesメソッドをコールしリスナーを解除します。続けて、disconnectメソッドをコールしLocation Serviceから切断します。

     @Override
    protected void onStop() {
        if (isGooglePlayServicesAvailable()) {
            if (mLocationClient.isConnected()) {
                mLocationClient.removeLocationUpdates(mLocationListener);
            }
            mLocationClient.disconnect();
        }
        super.onStop();
    }

2014年2月19日水曜日

Google Play servicesを使う

Google Play servicesを使う準備

Google Play services APIを使うには、Android SDK ManagerでGoogle Play servicesをダウンロードします。ダウンロードすると、次のディレクトリに保存されます。<AndroidSDK>\sdk\extras\google\google_play_services\libproject\google-play-services_lib

上記のプロジェクトをEclipseにインポートします。

Google Play services APIを使用するプロジェクトにて、AndroidManifest.xmlにmeta-dataの記載を行います。

    <application
        <meta-data
            android:name="com.google.android.gms.version"
            android:value="@integer/google_play_services_version" />
    </application>


Google Play servicesの存在確認

アプリケーションが動作するユーザー端末がどのような状態かわかりません。Google Play services APIを使用する前に、Google Play services APKがインストールされてるかどうかチェックしましょう。

public class UsingGooglePlayServiceSampleActivity extends FragmentActivity {

    private boolean isGooglePlayServicesAvailable() {
        int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);

        if (ConnectionResult.SUCCESS == resultCode) {
            return true;
        } else {
            Dialog dialog = GooglePlayServicesUtil.getErrorDialog(resultCode, this,
                    CONNECTION_FAILURE_RESOLUTION_REQUEST);
            if (dialog != null) {
                ErrorDialogFragment errorFragment = new ErrorDialogFragment();
                errorFragment.setDialog(dialog);
                errorFragment.show(getSupportFragmentManager(), "errro_dialog");
            }
        }

        return false;
    }

    public static class ErrorDialogFragment extends DialogFragment {

        private Dialog mDialog;

        public ErrorDialogFragment() {
            super();
            mDialog = null;
        }

        public void setDialog(Dialog dialog) {
            mDialog = dialog;
        }

        @Override
        public Dialog onCreateDialog(Bundle savedInstanceState) {
            return mDialog;
        }

        @Override
        public void onDestroy() {
            mDialog = null;
            super.onDestroy();
        }
    }
}

GooglePlayServicesUtil.isGooglePlayServicesAvailable()をコールします。APIリファレンスに記載されているResultコード一覧の値が返ってきます。エラーが発生した場合、GooglePlayServicesUtil.getErrorDialog()をコールしDialogを取得します。取得したDialogはDialogFragmentを使って、表示してください。

Dialogを通じてユーザーに発生した問題を通知します。Dialogを閉じると、onActivityResultがコールされてResultを通知します。

    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == CONNECTION_FAILURE_RESOLUTION_REQUEST) {
            if (resultCode == Activity.RESULT_OK) {
                // retry process
            }
        }
    }