From 68f642016e3a8959ae843b2109391a35e96f8aa9 Mon Sep 17 00:00:00 2001 From: kousuke nezu Date: Tue, 14 Mar 2017 20:18:17 +0900 Subject: [PATCH] =?UTF-8?q?[update]=20wear=E2=87=94android=E3=81=AE?= =?UTF-8?q?=E5=AE=9F=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gradle/wrapper/gradle-wrapper.properties | 2 +- mobile/src/main/AndroidManifest.xml | 12 ++ .../cyder/aktivaturbo/MainActivity.java | 11 ++ .../cyder/aktivaturbo/MobileCommunicate.java | 176 ++++++++++++++++++ wear/src/main/AndroidManifest.xml | 12 ++ .../cyder/aktivaturbo/MainActivity.java | 58 ++++-- .../cyder/aktivaturbo/MobileCommunicate.java | 176 ++++++++++++++++++ 7 files changed, 428 insertions(+), 19 deletions(-) create mode 100644 mobile/src/main/java/com/example/cyder/aktivaturbo/MobileCommunicate.java create mode 100644 wear/src/main/java/com/example/cyder/aktivaturbo/MobileCommunicate.java diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 40698e7..adeec7b 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,4 +1,4 @@ -#Sat Mar 04 16:06:58 JST 2017 +#Tue Mar 14 20:26:15 JST 2017 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME diff --git a/mobile/src/main/AndroidManifest.xml b/mobile/src/main/AndroidManifest.xml index 208773f..7d6b74b 100644 --- a/mobile/src/main/AndroidManifest.xml +++ b/mobile/src/main/AndroidManifest.xml @@ -16,6 +16,18 @@ + + + + + + + + + \ No newline at end of file diff --git a/mobile/src/main/java/com/example/cyder/aktivaturbo/MainActivity.java b/mobile/src/main/java/com/example/cyder/aktivaturbo/MainActivity.java index 9a6ad95..bce90c7 100644 --- a/mobile/src/main/java/com/example/cyder/aktivaturbo/MainActivity.java +++ b/mobile/src/main/java/com/example/cyder/aktivaturbo/MainActivity.java @@ -2,12 +2,23 @@ import android.support.v7.app.AppCompatActivity; import android.os.Bundle; +import android.util.Log; public class MainActivity extends AppCompatActivity { + MobileCommunicate mobileCommunicate; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); + +// 通信用クラスのインスタンス化 + mobileCommunicate = new MobileCommunicate(); + mobileCommunicate.connect(this); + } + + @Override + protected void onResume(){ + super.onResume(); } } diff --git a/mobile/src/main/java/com/example/cyder/aktivaturbo/MobileCommunicate.java b/mobile/src/main/java/com/example/cyder/aktivaturbo/MobileCommunicate.java new file mode 100644 index 0000000..8ba00ca --- /dev/null +++ b/mobile/src/main/java/com/example/cyder/aktivaturbo/MobileCommunicate.java @@ -0,0 +1,176 @@ +package com.example.cyder.aktivaturbo; + +import android.content.Context; +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.util.Log; + +import com.google.android.gms.common.api.GoogleApiClient; +import com.google.android.gms.common.api.PendingResult; +import com.google.android.gms.common.api.ResultCallback; +import com.google.android.gms.wearable.DataApi; +import com.google.android.gms.wearable.DataEvent; +import com.google.android.gms.wearable.DataEventBuffer; +import com.google.android.gms.wearable.DataMap; +import com.google.android.gms.wearable.DataMapItem; +import com.google.android.gms.wearable.PutDataMapRequest; +import com.google.android.gms.wearable.PutDataRequest; +import com.google.android.gms.wearable.Wearable; +import com.google.android.gms.wearable.WearableListenerService; + +/** + * !!このクラスはスマホ側と完全に統一してください!! + * Created by kousuke nezu on 2017/03/14. + */ + +public class MobileCommunicate extends WearableListenerService implements GoogleApiClient.ConnectionCallbacks, ResultCallback { + // ログ用のタグ + private static String TAG = "MobileCommunicate"; + + + /** データを保存するようのDataMapです */ + private DataMap data; + + /** + * データ送信用パス + * このパスにデータは保存される。 + */ + public static final String AKTIVA_SEND_PATH = "/com/cyder/activa/data"; + + //以下データ + public static int KEYNUM = 3; // キーの数 + + public static final String[] KEY = { // キーの名前 + "is_playing", // 再生状況 + "speed", // 速度 + "now_play_time"}; // 現在の再生時間 + public static int[] VALUE = { // キーのdata(絶対に上のKEYの順番と合わせてください!!!) + 0, + 0, + 0}; + + /** Google Play Serviceインスタンス */ + GoogleApiClient mGoogleApiClient; + + + /** + * コンストラクタ + * 初期化メソッドを呼ぶのみ + */ + public MobileCommunicate(){ + init(); + } + + /** + * 一番最初の元データを作る + */ + public void init(){ + data = new DataMap(); + for(int i = 0; i < KEYNUM; i++) { + //!必ず文字列で挿入してください! + data.putString(KEY[i], String.valueOf(VALUE[i])); + } + } + + /** + * 通信を接続する + * @param context コンテキスト + */ + public void connect(Context context){ + // mGoogleApiClientのインスタンス化 + mGoogleApiClient = new GoogleApiClient.Builder(context) + .addConnectionCallbacks(this) + .addApi(Wearable.API) + .build(); + + // Google Play Serviceに接続 + // アプリが立ち上がっているかどうかにかかわらず同期させたいのでonCreate()で接続 + mGoogleApiClient.connect(); + //データ変更を受け取れるようにする + Wearable.DataApi.addListener(mGoogleApiClient, this); + } + + /** + * Google Play Serviceに接続成功したとき呼び出される + */ + @Override + public void onConnected(@Nullable Bundle bundle) { + Log.d(TAG, "接続成功"); + } + + /** + * Google Play Serviceにサスペンドしたときに呼び出される + */ + @Override + public void onConnectionSuspended(int i) { + Log.d(TAG, "サスペンド"); + } + + public void disConnect(){ + Log.d(TAG, "接続を切断しました"); + if(mGoogleApiClient != null && mGoogleApiClient.isConnected()){ + mGoogleApiClient.disconnect(); + } + } + + /** + * Wearにデータを送信 + * Google Play Serviceにデータを保管し共有します。 + * @param path パス名 + * @param key キー + * @param value バリュー + */ + public void syncData(String path, String key, String value){ + Log.d(TAG, "データを送信します."); + + // DataMapインスタンスを生成する + PutDataMapRequest dataMapRequest = PutDataMapRequest.create(path); + DataMap dataMap = dataMapRequest.getDataMap(); + + // データをセットする + // dataMap.putString(key, value); + dataMap.putAll(data); + dataMap.putString(key, value); + + // データを更新する + PutDataRequest request = dataMapRequest.asPutDataRequest(); + PendingResult pendingResult = Wearable.DataApi.putDataItem(mGoogleApiClient, request); + pendingResult.setResultCallback(this); + } + + /** + * 同期結果を受け取るメソッド + */ + @Override + public void onResult(@NonNull DataApi.DataItemResult dataItemResult) { + Log.d("TAG", "onResult: " + dataItemResult.getStatus()); + } + + @Override + public void onDataChanged(DataEventBuffer dataEvents){ + for(DataEvent event: dataEvents){ + // データアイテムが削除されたとき + if(event.getType() == DataEvent.TYPE_DELETED){ + Log.d(TAG, "データアイテムが削除されました。"); + } + // データアイテムが変更されたとき + else if(event.getType() == DataEvent.TYPE_CHANGED){ + Log.d(TAG, "データアイテムが変更されました。"); + + //パス名が同じ場合は値を取得 + if(AKTIVA_SEND_PATH.equals(event.getDataItem().getUri().getPath())){ + DataMapItem dataMapItem = DataMapItem.fromDataItem(event.getDataItem()); + for(int i = 0; i < KEYNUM; i++) { + String dataItem = dataMapItem.getDataMap().getString(KEY[i]); + if(!data.getString(KEY[i]).equals(dataItem) && dataItem != null) { + //!必ず文字列で取り出してください! + Log.d(TAG, String.valueOf(dataItem)); + data.putString(KEY[i], dataItem); + } + } + } + } + } + } +} diff --git a/wear/src/main/AndroidManifest.xml b/wear/src/main/AndroidManifest.xml index b023111..d336d7a 100644 --- a/wear/src/main/AndroidManifest.xml +++ b/wear/src/main/AndroidManifest.xml @@ -19,6 +19,18 @@ + + + + + + + + + \ No newline at end of file diff --git a/wear/src/main/java/com/example/cyder/aktivaturbo/MainActivity.java b/wear/src/main/java/com/example/cyder/aktivaturbo/MainActivity.java index ae17bde..3134655 100644 --- a/wear/src/main/java/com/example/cyder/aktivaturbo/MainActivity.java +++ b/wear/src/main/java/com/example/cyder/aktivaturbo/MainActivity.java @@ -2,11 +2,12 @@ import android.app.Activity; import android.os.Bundle; +import android.util.Log; import android.view.View; import android.widget.ImageButton; import android.widget.RelativeLayout; -public class MainActivity extends Activity { +public class MainActivity extends Activity implements View.OnClickListener { /** レイアウト */ private RelativeLayout relativeLayout; @@ -21,31 +22,52 @@ public class MainActivity extends Activity { /** 再生ボタンの状態をあらわす。ture=再生、false=停止 */ private boolean isPlaying = false; + /** mobileとの通信のためのクラス */ + MobileCommunicate mobileCommunicate; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); +// 四角形のレイアウトを読み込み。将来的には変更必要 setContentView(R.layout.rect_activity_main); -// RelativeLayoutの初期化 - relativeLayout = (RelativeLayout)findViewById(R.id.rect_relativelayout); -// ViewのIDを検索 + //Viewを初期化 + findViews(); + Log.d("MainActivity", "onCreate通過"); +// 通信用クラスのインスタンス化 + mobileCommunicate = new MobileCommunicate(); + mobileCommunicate.connect(this); + } + + /** + * Viewを初期化するためのメソッド + */ + private void findViews(){ + // ViewのIDを検索 playButton = (ImageButton)findViewById(R.id.play_button); -// 押されている状態か否かを設定 + // 押されている状態か否かを設定 playButton.setActivated(isPlaying); -// 押されたときの挙動 - playButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - isPlaying = !isPlaying; - v.setActivated(isPlaying); - } - }); - speedGauge = (CircleGauge)findViewById(R.id.speed_circlegauge); - sectionGauge = (CircleGauge)findViewById(R.id.section_circlegauge); - playingGauge = (CircleGauge)findViewById(R.id.playing_circlegauge); + // 押されたときの挙動 + playButton.setOnClickListener(this); } + int i = 0; + /** + * Viewをクリックしたときに発生するリスナーを受け取るメソッド + * @param v クリックされたView + */ @Override - protected void onResume(){ - super.onResume(); + public void onClick(View v) { + switch (v.getId()) { + case R.id.play_button: + isPlaying = !isPlaying; + v.setActivated(isPlaying); + //使用例 + mobileCommunicate.syncData( + MobileCommunicate.AKTIVA_SEND_PATH, //パスを指定(おそらくこのままで問題ないはず) + MobileCommunicate.KEY[0], //キー 変更したいもののキーを入力 + String.valueOf(i++)); //バリュー 変更する値を入力 + Log.d("MainActivity", String.valueOf(i)); + break; + } } } diff --git a/wear/src/main/java/com/example/cyder/aktivaturbo/MobileCommunicate.java b/wear/src/main/java/com/example/cyder/aktivaturbo/MobileCommunicate.java new file mode 100644 index 0000000..37ccd67 --- /dev/null +++ b/wear/src/main/java/com/example/cyder/aktivaturbo/MobileCommunicate.java @@ -0,0 +1,176 @@ +package com.example.cyder.aktivaturbo; + +import android.content.Context; +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.util.Log; + +import com.google.android.gms.common.api.GoogleApiClient; +import com.google.android.gms.common.api.PendingResult; +import com.google.android.gms.common.api.ResultCallback; +import com.google.android.gms.wearable.DataApi; +import com.google.android.gms.wearable.DataEvent; +import com.google.android.gms.wearable.DataEventBuffer; +import com.google.android.gms.wearable.DataMap; +import com.google.android.gms.wearable.DataMapItem; +import com.google.android.gms.wearable.PutDataMapRequest; +import com.google.android.gms.wearable.PutDataRequest; +import com.google.android.gms.wearable.Wearable; +import com.google.android.gms.wearable.WearableListenerService; + +/** + * !!このクラスはスマホ側と完全に統一してください!! + * Created by kousuke nezu on 2017/03/14. + */ + +public class MobileCommunicate extends WearableListenerService implements GoogleApiClient.ConnectionCallbacks, ResultCallback { + // ログ用のタグ + private static String TAG = "MobileCommunicate"; + + + /** データを保存するようのDataMapです */ + private DataMap data; + + /** + * データ送信用パス + * このパスにデータは保存される。 + */ + public static final String AKTIVA_SEND_PATH = "/com/cyder/activa/data"; + + //以下データ + public static final int KEYNUM = 3; // キーの数 + + public static final String[] KEY = { // キーの名前 + "is_playing", // 再生状況 + "speed", // 速度 + "now_play_time"}; // 現在の再生時間 + private static int[] VALUE = { // キーのdata(絶対に上のKEYの順番と合わせてください!!!) + 0, + 0, + 0}; + + /** Google Play Serviceインスタンス */ + GoogleApiClient mGoogleApiClient; + + + /** + * コンストラクタ + * 初期化メソッドを呼ぶのみ + */ + public MobileCommunicate(){ + init(); + } + + /** + * 一番最初の元データを作る + */ + public void init(){ + data = new DataMap(); + for(int i = 0; i < KEYNUM; i++) { + //!必ず文字列で挿入してください! + data.putString(KEY[i], String.valueOf(VALUE[i])); + } + } + + /** + * 通信を接続する + * @param context コンテキスト + */ + public void connect(Context context){ + // mGoogleApiClientのインスタンス化 + mGoogleApiClient = new GoogleApiClient.Builder(context) + .addConnectionCallbacks(this) + .addApi(Wearable.API) + .build(); + + // Google Play Serviceに接続 + // アプリが立ち上がっているかどうかにかかわらず同期させたいのでonCreate()で接続 + mGoogleApiClient.connect(); + //データ変更を受け取れるようにする + Wearable.DataApi.addListener(mGoogleApiClient, this); + } + + /** + * Google Play Serviceに接続成功したとき呼び出される + */ + @Override + public void onConnected(@Nullable Bundle bundle) { + Log.d(TAG, "接続成功"); + } + + /** + * Google Play Serviceにサスペンドしたときに呼び出される + */ + @Override + public void onConnectionSuspended(int i) { + Log.d(TAG, "サスペンド"); + } + + public void disConnect(){ + Log.d(TAG, "接続を切断しました"); + if(mGoogleApiClient != null && mGoogleApiClient.isConnected()){ + mGoogleApiClient.disconnect(); + } + } + + /** + * Wearにデータを送信 + * Google Play Serviceにデータを保管し共有します。 + * @param path パス名 + * @param key キー + * @param value バリュー + */ + public void syncData(String path, String key, String value){ + Log.d(TAG, "データを送信します."); + + // DataMapインスタンスを生成する + PutDataMapRequest dataMapRequest = PutDataMapRequest.create(path); + DataMap dataMap = dataMapRequest.getDataMap(); + + // データをセットする +// dataMap.putString(key, value); + dataMap.putAll(data); + dataMap.putString(key, value); + + // データを更新する + PutDataRequest request = dataMapRequest.asPutDataRequest(); + PendingResult pendingResult = Wearable.DataApi.putDataItem(mGoogleApiClient, request); + pendingResult.setResultCallback(this); + } + + /** + * 同期結果を受け取るメソッド + */ + @Override + public void onResult(@NonNull DataApi.DataItemResult dataItemResult) { + Log.d("TAG", "onResult: " + dataItemResult.getStatus()); + } + + @Override + public void onDataChanged(DataEventBuffer dataEvents){ + for(DataEvent event: dataEvents){ + // データアイテムが削除されたとき + if(event.getType() == DataEvent.TYPE_DELETED){ + Log.d(TAG, "データアイテムが削除されました。"); + } + // データアイテムが変更されたとき + else if(event.getType() == DataEvent.TYPE_CHANGED){ + Log.d(TAG, "データアイテムが変更されました。"); + + //パス名が同じ場合は値を取得 + if(AKTIVA_SEND_PATH.equals(event.getDataItem().getUri().getPath())){ + DataMapItem dataMapItem = DataMapItem.fromDataItem(event.getDataItem()); + for(int i = 0; i < KEYNUM; i++) { + String dataItem = dataMapItem.getDataMap().getString(KEY[i]); + if(!data.getString(KEY[i]).equals(dataItem) && dataItem != null) { + //!必ず文字列で取り出してください! + Log.d(TAG, String.valueOf(dataItem)); + data.putString(KEY[i], dataItem); + } + } + } + } + } + } +}