skimemo


skimemo - 日記/2013-08-13/AppStateClientをServiceから動かす の変更点


#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()