--> -->
#blog2navi() *AppStateClientをServiceから動かす [#zb7317b7] Google PlayのAppStateは、サンプルを見てもActivityから使うケースしか無く、ぐぐってもサービスから使っているものが見つかりませんでした。~ 恐らく、あまりに自明なのでわざわざ書く人が居ないのかも・・・。~ ~ ---- ~ まず、AppStateを使うクラスをサンプル通りに適当に書きます。~ ただし、Activityは継承しません。~ #code(java){{ public class AppStateControl implements ConnectionCallbacks, OnConnectionFailedListener, OnStateLoadedListener { // イベントを返す用 private AppStateListenerInterface listener = null; private AppStateClient mAppStateClient; private boolean mConnecting; private byte[] data; private Context c; private static final int STATE_KEY = 0; AppStateControl(Context c) { Log.d(TAG,"AppStateControl"); this.c = c; // for APP_STATE String[] scopes = new String[] { Scopes.APP_STATE }; mAppStateClient = new AppStateClient.Builder(c, this, this).setScopes(scopes).create(); data = null; } protected void connect() { // super.onStart(); Log.d(TAG,"onStart"); if (!mConnecting) { mConnecting = true; mAppStateClient.connect(); Log.v(TAG,"do connect()"); } } protected void disconnect() { // super.onStop(); Log.d(TAG,"onStop"); if (mAppStateClient != null && mAppStateClient.isConnected()) { mAppStateClient.disconnect(); Log.v(TAG,"do disconnect()"); } } @Override public void onStateLoaded(int statusCode, int stateKey, byte[] resultData) { if (statusCode == AppStateClient.STATUS_OK) { // successfully loaded/saved data Log.v(TAG,"onStateLoaded: STATUS_OK"); } else if ( statusCode == AppStateClient.STATUS_DEVELOPER_ERROR ) { Log.v(TAG,"onStateLoaded: STATUS_DEVELOPER_ERROR"); } else { // handle error Log.v(TAG,"onStateLoaded: handle error."); } if (resultData == null) { Log.v(TAG,"onStateLoaded: data is null."); return; } // イベント通知 listener.onStateLoaded(statusCode, stateKey, resultData); } @Override public void onStateConflict(int stateKey, String ver, byte[] localData, byte[] serverData) { Log.d(TAG,"onStateConflict"); // resolve conflict, then call mAppStateClient.resolveConflict() mAppStateClient.resolveState(this, STATE_KEY, ver, serverData); } } }} 一つずつ解説していきます。~ ~ 1行目で必要なサービスをimplementします。Activityは継承しません。~ 13行目〜でコンストラクタを置き、その中でServiceからcontextを受け取って、Builderに渡しています。~ 29,39行目〜で、onStart, onStopの代わりに独自の処理を書いています。これはService側から明示的に呼びます。~ 49行目では、Serviceに取得した値を返すためにイベント通知しています。ListenerはService側で仕掛けます。~ ~ 次にService側を見てみます。~ #code(java){{ public class InfoTransferService extends Service implements AppStateListenerInterface { static final String TAG="InfoTransferService"; RBWBroadcastReceiver mBroadcastReceiver; AppStateControl appStateControl; @Override public void onCreate() { Log.d(TAG, "onCreate"); // APP_STATE Initialize appStateControl = new AppStateControl(getApplicationContext()); // APP_STATEのListenerを仕掛ける appStateControl.setListener(this); // GooglePlay Connect appStateControl.connect(); } @Override public void onDestroy() { // APP_STATEのListenerを外す appStateControl.removeListener(); // disconnect appStateControl.disconnect(); } // データを読むとき private void loadData() { appStateControl.LoadData(); } // データを書くとき private void saveData() { appStateControl.SaveData(); } @Override public void onStateLoaded(int statusCode, int stateKey, byte[] resultData) { // TODO Auto-generated method stub Log.d(TAG, "onStateLoaded"); Log.v(TAG, "Cloud Saveサービス上のデータ:" + new String(resultData)); } }} ~ 8行目〜のonCreate内で、AppStateControlをnewしてcontextを渡します。~ 15行目で結果を受け取るためのListenerを仕掛けています。~ あとは・・・まあ、コードの通りですね(笑)。~ ~ ついでに、Interface部分も乗せておきます。~ ~ #code(java){{ public interface AppStateListenerInterface extends EventListener { /** * onStateLoaded発生 * @param resultData * @param stateKey * @param statusCode */ public void onStateLoaded(int statusCode, int stateKey, byte[] resultData); } }} MainActivityからサービスを起こす方法は、別途文献にあたってみてください。~ [[http://www.atmarkit.co.jp/ait/articles/0906/18/news102.html:http://www.atmarkit.co.jp/ait/articles/0906/18/news102.html]] ---- #htmlinsert(20130813_service.html) ---- RIGHT:Category: [[[android>日記/Category/android]]] - 18:19:31 ---- ~ RIGHT:&blog2trackback(); #comment(above) #blog2navi()