--> -->

skimemo


skimemo - 日記/2013-08-13/AppStateClientをServiceから動かす

_ AppStateClientをServiceから動かす

Google PlayのAppStateは、サンプルを見てもActivityから使うケースしか無く、ぐぐってもサービスから使っているものが見つかりませんでした。
恐らく、あまりに自明なのでわざわざ書く人が居ないのかも・・・。



まず、AppStateを使うクラスをサンプル通りに適当に書きます。
ただし、Activityは継承しません。

Everything is expanded.Everything is shortened.
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 
-
|
-
!
|
|
|
|
|
|
|
-
|
|
|
|
|
-
-
|
!
|
|
|
|
!
|
-
-
!
-
|
|
|
!
!
|
-
-
!
-
|
|
!
!
|
|
-
-
-
!
-
|
-
-
!
!
-
|
|
!
-
!
!
|
|
-
|
-
!
!
!
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側を見てみます。

Everything is expanded.Everything is shortened.
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
-
|
|
|
|
|
|
-
|
|
-
!
|
-
!
|
-
!
|
!
|
-
-
!
-
!
!
|
-
-
|
!
|
-
-
|
!
|
|
-
-
!
|
!
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部分も乗せておきます。

Everything is expanded.Everything is shortened.
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
-
|
-
|
|
|
|
!
|
!
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


Amazon.co.jp
いや、あの、そのサービスではありません。。。

Category: [android] - 18:19:31


 
Last-modified: 2013-08-18 (日) 07:39:35 (3897d)