summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStratos <kam.stratos@gmail.com>2015-05-11 16:15:57 +0300
committerChristian Lohmaier <lohmaier+LibreOffice@googlemail.com>2015-07-18 13:00:00 +0000
commitaa7779ca3b8f690c3e62690d735a597c933e7e74 (patch)
tree22bf2c3a21fb5c0455042d85f75a2543147eebd2
parentc4985ad1e39ecb77a0606a45b9802a93d7ee5b74 (diff)
tdf#91162 Android Wear overhaul.
Started syncing data items. Added controls at cards. Wear shows a preview of the current slide. Improved UI. Change-Id: Ifd3dbb022d40a5c6c9d69e04ee9dbbe5835c937c Reviewed-on: https://gerrit.libreoffice.org/15701 Reviewed-by: Christian Lohmaier <lohmaier+LibreOffice@googlemail.com> Tested-by: Christian Lohmaier <lohmaier+LibreOffice@googlemail.com>
-rw-r--r--android/sdremote/mobile/src/main/java/org/libreoffice/impressremote/activity/SlideShowActivity.java29
-rw-r--r--android/sdremote/mobile/src/main/java/org/libreoffice/impressremote/communication/CommunicationServiceWear.java115
-rw-r--r--android/sdremote/wear/src/main/AndroidManifest.xml7
-rw-r--r--android/sdremote/wear/src/main/java/org/libreoffice/impressremote/activity/ControlActivity.java166
-rw-r--r--android/sdremote/wear/src/main/java/org/libreoffice/impressremote/activity/FullscreenActivity.java73
-rw-r--r--android/sdremote/wear/src/main/java/org/libreoffice/impressremote/activity/MainActivity.java151
-rw-r--r--android/sdremote/wear/src/main/java/org/libreoffice/impressremote/activity/NotificationActivity.java51
-rw-r--r--android/sdremote/wear/src/main/java/org/libreoffice/impressremote/communication/Commands.java32
-rw-r--r--android/sdremote/wear/src/main/java/org/libreoffice/impressremote/communication/DataLayerListenerService.java184
-rw-r--r--android/sdremote/wear/src/main/java/org/libreoffice/impressremote/util/SlideShowData.java64
-rw-r--r--android/sdremote/wear/src/main/res/color/button_colors.xml6
-rw-r--r--android/sdremote/wear/src/main/res/drawable-hdpi/ic_action_next.pngbin0 -> 485 bytes
-rw-r--r--android/sdremote/wear/src/main/res/drawable-hdpi/ic_action_pause.pngbin0 -> 191 bytes
-rw-r--r--android/sdremote/wear/src/main/res/drawable-hdpi/ic_action_play.pngbin0 -> 497 bytes
-rw-r--r--android/sdremote/wear/src/main/res/drawable-hdpi/ic_action_previous.pngbin0 -> 491 bytes
-rw-r--r--android/sdremote/wear/src/main/res/drawable-mdpi/ic_action_next.pngbin0 -> 362 bytes
-rw-r--r--android/sdremote/wear/src/main/res/drawable-mdpi/ic_action_pause.pngbin0 -> 190 bytes
-rw-r--r--android/sdremote/wear/src/main/res/drawable-mdpi/ic_action_play.pngbin0 -> 375 bytes
-rw-r--r--android/sdremote/wear/src/main/res/drawable-mdpi/ic_action_previous.pngbin0 -> 375 bytes
-rw-r--r--android/sdremote/wear/src/main/res/drawable-xhdpi/ic_action_next.pngbin0 -> 524 bytes
-rw-r--r--android/sdremote/wear/src/main/res/drawable-xhdpi/ic_action_pause.pngbin0 -> 244 bytes
-rw-r--r--android/sdremote/wear/src/main/res/drawable-xhdpi/ic_action_play.pngbin0 -> 531 bytes
-rw-r--r--android/sdremote/wear/src/main/res/drawable-xhdpi/ic_action_previous.pngbin0 -> 535 bytes
-rw-r--r--android/sdremote/wear/src/main/res/drawable-xxhdpi/ic_action_next.pngbin0 -> 706 bytes
-rw-r--r--android/sdremote/wear/src/main/res/drawable-xxhdpi/ic_action_pause.pngbin0 -> 297 bytes
-rw-r--r--android/sdremote/wear/src/main/res/drawable-xxhdpi/ic_action_play.pngbin0 -> 778 bytes
-rw-r--r--android/sdremote/wear/src/main/res/drawable-xxhdpi/ic_action_previous.pngbin0 -> 726 bytes
-rw-r--r--android/sdremote/wear/src/main/res/layout/full_screen.xml57
-rw-r--r--android/sdremote/wear/src/main/res/layout/full_screen_background.xml78
-rw-r--r--android/sdremote/wear/src/main/res/layout/full_screen_minimal.xml57
-rw-r--r--android/sdremote/wear/src/main/res/layout/notification.xml64
31 files changed, 756 insertions, 378 deletions
diff --git a/android/sdremote/mobile/src/main/java/org/libreoffice/impressremote/activity/SlideShowActivity.java b/android/sdremote/mobile/src/main/java/org/libreoffice/impressremote/activity/SlideShowActivity.java
index 567b9db..3322732 100644
--- a/android/sdremote/mobile/src/main/java/org/libreoffice/impressremote/activity/SlideShowActivity.java
+++ b/android/sdremote/mobile/src/main/java/org/libreoffice/impressremote/activity/SlideShowActivity.java
@@ -661,6 +661,7 @@ public class SlideShowActivity extends ActionBarActivity implements ServiceConne
/**
* Used in Wear control
*/
+
private void nextTransition(){
if (!isLastSlideDisplayed() && !modeIsEmpty()) {
mCommunicationService.getCommandsTransmitter().performNextTransition();
@@ -672,16 +673,21 @@ public class SlideShowActivity extends ActionBarActivity implements ServiceConne
}
}
private void pausePresentation(){
+ Log.d("SlideShowActivity","pausePresentation");
changeMode(Mode.EMPTY);
setUpSlideShowPausedInformation();
pauseSlideShow();
pauseTimer();
+ CommunicationServiceWear.presentationPaused();
}
private void resumePresentation(){
+ Log.d("SlideShowActivity", "resumePresentation");
+ CommunicationServiceWear.ignoreNextSync();
changeMode(Mode.PAGER);
setUpSlideShowInformation();
resumeSlideShow();
resumeTimer();
+ CommunicationServiceWear.presentationResumed();
}
private void pauseResumePresentation(){
if(modeIsEmpty()){
@@ -692,24 +698,33 @@ public class SlideShowActivity extends ActionBarActivity implements ServiceConne
}
private void slideCountMessage(){
- CommunicationServiceWear.sendCountMessage(notificationCount());
+ Log.d("SlideShowActivity", "slideCountMessage");
+ CommunicationServiceWear.syncData(getSlideCount(), getSlidePreview());
}
- private String notificationCount(){
+
+ private void showWearNotification(){
+ Log.d("SlideShowActivity", "showWearNotification");
+ CommunicationServiceWear.syncData(getSlideCount(), getSlidePreview());
+ }
+
+ private String getSlideCount(){
return mCommunicationService.getSlideShow().getHumanCurrentSlideIndex()
+"/"+mCommunicationService.getSlideShow().getSlidesCount();
}
- private void showWearNotification(){
- Log.d("SlideShowActivity","showWearNotification");
- CommunicationServiceWear.sendStatusNotification(notificationCount());
+
+ private byte[] getSlidePreview(){
+ Log.d("SlideShowActivity","getSlidePreview");
+ int mCurrentSlideIndex = mCommunicationService.getSlideShow().getCurrentSlideIndex();
+ return mCommunicationService.getSlideShow().getSlidePreviewBytes(mCurrentSlideIndex);
}
+
private void wearableServiceConnect() {
- //TODO check if wear api is present
+ // TODO add option for enabling android wear
this.startService(new Intent(this, CommunicationServiceWear.class));
}
private void wearableServiceDisconnect() {
this.stopService(new Intent(this, CommunicationServiceWear.class));
}
-
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/android/sdremote/mobile/src/main/java/org/libreoffice/impressremote/communication/CommunicationServiceWear.java b/android/sdremote/mobile/src/main/java/org/libreoffice/impressremote/communication/CommunicationServiceWear.java
index 48cd56f..f56dc81 100644
--- a/android/sdremote/mobile/src/main/java/org/libreoffice/impressremote/communication/CommunicationServiceWear.java
+++ b/android/sdremote/mobile/src/main/java/org/libreoffice/impressremote/communication/CommunicationServiceWear.java
@@ -8,19 +8,24 @@
package org.libreoffice.impressremote.communication;
import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import com.google.android.gms.common.api.GoogleApiClient;
+import com.google.android.gms.wearable.Asset;
import com.google.android.gms.wearable.MessageEvent;
import com.google.android.gms.wearable.Node;
import com.google.android.gms.wearable.NodeApi;
+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;
import org.libreoffice.impressremote.util.Intents;
-import java.nio.charset.Charset;
+import java.io.ByteArrayOutputStream;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
@@ -35,10 +40,18 @@ public class CommunicationServiceWear extends WearableListenerService {
private static final String COMMAND_CONNECT="/connect";
private static final String COMMAND_APP_PAUSED="/appPaused";
private static final String COMMAND_PRESENTATION_STOPPED="/wearableStop";
- private static final String COMMAND_SLIDE_COUNT="/count";
+ private static final String COMMAND_PRESENTATION_PAUSED="/pause";
+ private static final String COMMAND_PRESENTATION_RESUMED="/resume";
+
+ public static final String COMMAND_NOTIFY="/notification";
+
+ public static final String INTENT_COUNT="COUNT";
+ public static final String INTENT_PREVIEW="PREVIEW";
+ public static final String INTENT_HAS_ASSET="HASASSET";
private static GoogleApiClient googleApiClient;
+ private static boolean ingoreSync;
@Override
public void onCreate(){
@@ -61,21 +74,19 @@ public class CommunicationServiceWear extends WearableListenerService {
if(null != googleApiClient){
notifyWearStop();
final ScheduledExecutorService exec = Executors.newScheduledThreadPool(1);
- exec.schedule(new Runnable(){
+ exec.schedule(new Runnable() {
@Override
- public void run(){
- if(googleApiClient!=null){
- if(googleApiClient.isConnected()){
+ public void run() {
+ if (googleApiClient != null) {
+ if (googleApiClient.isConnected()) {
googleApiClient.disconnect();
Log.v(TAG, "GoogleApiClient disconnected");
}
}
}
}, 2, TimeUnit.SECONDS);
-
}
super.onDestroy();
-
}
@Override
@@ -111,48 +122,26 @@ public class CommunicationServiceWear extends WearableListenerService {
Intent aIntent= Intents.buildWearPauseResumeIntent();
LocalBroadcastManager.getInstance(this).sendBroadcast(aIntent);
}
-
-
-
}
+
@Override
public void onPeerConnected(Node peer) {
super.onPeerConnected(peer);
-
String id = peer.getId();
String name = peer.getDisplayName();
-
Log.d(TAG, "Connected peer name & ID: " + name + "|" + id);
-
-
}
private void notifyWearStop(){
- Log.d(TAG, "notifyWearStop");
sendMessage(COMMAND_PRESENTATION_STOPPED);
}
-
- public static void sendStatusNotification(String count){
- Log.d(TAG, "sendStatusNotification");
- sendCountMessage(count);
+ public static void presentationPaused(){
+ sendMessage(COMMAND_PRESENTATION_PAUSED);
}
-
- private static void sendMessage( final String path, final String text ) {
- new Thread( new Runnable() {
- @Override
- public void run() {
- if(googleApiClient !=null){
- NodeApi.GetConnectedNodesResult nodes =
- Wearable.NodeApi.getConnectedNodes( googleApiClient ).await();
- for(Node node : nodes.getNodes()) {
- Log.d(TAG, "SendMessage " + path + "-" + text);
- Wearable.MessageApi.sendMessage(
- googleApiClient, node.getId(), path, text.getBytes(Charset.forName("UTF-8"))).await();
- }
- }
- }
- }).start();
+ public static void presentationResumed(){
+ sendMessage(COMMAND_PRESENTATION_RESUMED);
}
+
private static void sendMessage( final String path) {
new Thread( new Runnable() {
@Override
@@ -170,8 +159,56 @@ public class CommunicationServiceWear extends WearableListenerService {
}).start();
}
- public static void sendCountMessage(String s) {
- Log.d(TAG, "sendCountMessage");
- sendMessage(COMMAND_SLIDE_COUNT,s);
+ public static void syncData(final String count,final byte[] preview) {
+ if(ingoreSync){
+ Log.d(TAG, "Ignoring sync!");
+ ingoreSync=false;
+ return;
+ }else{
+ new Thread( new Runnable() {
+ @Override
+ public void run() {
+ if(googleApiClient !=null){
+ Log.d(TAG, "syncData");
+ googleApiClient.connect();
+ if (googleApiClient!=null) {
+ PutDataMapRequest dataMapRequest = PutDataMapRequest.create(COMMAND_NOTIFY);
+
+ dataMapRequest.getDataMap().putDouble("timestamp", System.currentTimeMillis());
+ dataMapRequest.getDataMap().putString(INTENT_COUNT, count);
+ if (preview == null) {
+ dataMapRequest.getDataMap().putBoolean(INTENT_HAS_ASSET,false);
+ }else{
+ Asset asset = createAssetFromByte(preview);
+ dataMapRequest.getDataMap().putBoolean(INTENT_HAS_ASSET,true);
+ dataMapRequest.getDataMap().putAsset(INTENT_PREVIEW, asset);
+ }
+ PutDataRequest putDataRequest = dataMapRequest.asPutDataRequest();
+ Wearable.DataApi.putDataItem(googleApiClient, putDataRequest);
+ }
+ else {
+ Log.e(TAG, "No connection to wearable available!");
+ }
+ }
+ }
+ }).start();
+ }
+
+ }
+
+ public static void ignoreNextSync(){
+ ingoreSync=true;
}
+
+ private static Asset createAssetFromByte(byte[] data){
+ if(data==null){
+ throw new IllegalArgumentException("Null byte array.");
+ }
+ Bitmap bitmap =BitmapFactory.decodeByteArray(data, 0, data.length);
+ Bitmap.createScaledBitmap(bitmap,150,150,false);
+ final ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
+ bitmap.compress(Bitmap.CompressFormat.JPEG, 100, byteStream);
+ return Asset.createFromBytes(byteStream.toByteArray());
+ }
+
} \ No newline at end of file
diff --git a/android/sdremote/wear/src/main/AndroidManifest.xml b/android/sdremote/wear/src/main/AndroidManifest.xml
index ba222c7..d4f6aa6 100644
--- a/android/sdremote/wear/src/main/AndroidManifest.xml
+++ b/android/sdremote/wear/src/main/AndroidManifest.xml
@@ -10,7 +10,7 @@
android:icon="@drawable/ic_launcher"
android:theme="@android:style/Theme.DeviceDefault" >
<activity
- android:name=".activity.MainActivity"
+ android:name=".activity.FullscreenActivity"
android:label="@string/application_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
@@ -18,6 +18,11 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
+ <activity android:name=".activity.NotificationActivity"
+ android:exported="true"
+ android:allowEmbedded="true"
+ android:taskAffinity=""
+ android:theme="@android:style/Theme.DeviceDefault.Light" />
<service android:name=".communication.DataLayerListenerService">
<intent-filter>
diff --git a/android/sdremote/wear/src/main/java/org/libreoffice/impressremote/activity/ControlActivity.java b/android/sdremote/wear/src/main/java/org/libreoffice/impressremote/activity/ControlActivity.java
new file mode 100644
index 0000000..2d4e61e
--- /dev/null
+++ b/android/sdremote/wear/src/main/java/org/libreoffice/impressremote/activity/ControlActivity.java
@@ -0,0 +1,166 @@
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+package org.libreoffice.impressremote.activity;
+import static org.libreoffice.impressremote.communication.Commands.*;
+
+import android.app.Activity;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.graphics.Bitmap;
+import android.graphics.Color;
+import android.graphics.drawable.ColorDrawable;
+import android.os.Bundle;
+import android.support.v4.content.LocalBroadcastManager;
+import android.util.Log;
+import android.view.View;
+import android.widget.ImageButton;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import org.libreoffice.impressremote.R;
+import org.libreoffice.impressremote.communication.DataLayerListenerService;
+import org.libreoffice.impressremote.util.SlideShowData;
+
+public class ControlActivity extends Activity {
+ private static final String TAG = "ControlActivity";
+ private IntentsReceiver mIntentsReceiver;
+ private boolean paused;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ Log.v(TAG, "onCreate");
+ super.onCreate(savedInstanceState);
+ registerIntentsReceiver();
+ this.startService(new Intent(this, DataLayerListenerService.class));
+ }
+
+ @Override
+ protected void onDestroy() {
+ Log.v(TAG, "onDestroy");
+ unregisterIntentsReceiver();
+ this.stopService(new Intent(this, DataLayerListenerService.class));
+ super.onDestroy();
+ }
+
+ @Override
+ protected void onPause(){
+ Log.v(TAG, "onPause");
+ super.onPause();
+ }
+
+ @Override
+ protected void onStop(){
+ Log.v(TAG, "onStop");
+ super.onStop();
+ }
+
+ public void onButtonClickedPrevious(View target) {
+ if(!paused){
+ DataLayerListenerService.commandPrevious();
+ }
+
+ }
+
+ public void onButtonClickedNext(View target) {
+ if(!paused){
+ DataLayerListenerService.commandNext();
+ }
+ }
+
+ public void onButtonClickedPauseResume(View target) {
+ DataLayerListenerService.commandPauseResume();
+ }
+
+ public void changeSlideCount(String count){
+ TextView textView;
+ textView = (TextView) findViewById(R.id.textView_counter);
+ textView.setText(count);
+ }
+
+ public void reset(){
+ changeSlideCount(NULL_STRING_COUNT);
+ }
+
+ public void changePreview(Bitmap bitmap){
+ Log.v(TAG,"changePreview");
+ if(!SlideShowData.getInstance().isFullscreen()){
+ return;
+ }
+ ImageView imageView;
+ imageView=(ImageView) findViewById(R.id.preview);
+ if(imageView==null){
+ Log.v(TAG,"Null imageview");
+ return;
+ }
+ if(bitmap==null){
+ imageView.setImageDrawable(new ColorDrawable(Color.WHITE));
+ }else{
+ imageView.setImageBitmap(bitmap);
+ }
+ }
+
+ private void registerIntentsReceiver() {
+ mIntentsReceiver = new IntentsReceiver(this);
+ IntentFilter aIntentFilter = buildIntentsReceiverFilter();
+
+ LocalBroadcastManager.getInstance(getApplicationContext()).registerReceiver(mIntentsReceiver, aIntentFilter);
+ }
+
+ private void unregisterIntentsReceiver() {
+ try {
+ LocalBroadcastManager.getInstance(getApplicationContext()).unregisterReceiver(mIntentsReceiver);
+ } catch (IllegalArgumentException ignored) {
+
+ }
+ }
+
+ private IntentFilter buildIntentsReceiverFilter() {
+ IntentFilter aIntentFilter = new IntentFilter();
+ aIntentFilter.addAction(INTENT_UPDATE);
+ aIntentFilter.addAction(COMMAND_PRESENTATION_STOPPED);
+ aIntentFilter.addAction(COMMAND_PRESENTATION_PAUSED);
+ aIntentFilter.addAction(COMMAND_PRESENTATION_RESUMED);
+ return aIntentFilter;
+ }
+
+ private static final class IntentsReceiver extends BroadcastReceiver {
+ private final ControlActivity activity;
+ private IntentsReceiver(ControlActivity aControlActivity) {
+ activity = aControlActivity;
+ }
+ @Override
+ public void onReceive(Context context, Intent intent) {
+
+ if(intent.getAction().equals(INTENT_UPDATE)){
+ activity.changeSlideCount(SlideShowData.getInstance().getCount());
+ if(SlideShowData.getInstance().hasPreview()){
+ activity.changePreview(SlideShowData.getInstance().getPreview());
+ }
+ }else if(intent.getAction().equals(COMMAND_PRESENTATION_STOPPED)){
+ activity.reset();
+ }else if(intent.getAction().equals(COMMAND_PRESENTATION_PAUSED)){
+ activity.setPaused(true);
+ }
+ else if(intent.getAction().equals(COMMAND_PRESENTATION_RESUMED)){
+ activity.setPaused(false);
+ }
+ }
+ }
+
+ public void setPaused(boolean paused) {
+ this.paused = paused;
+ ImageButton imageButton=(ImageButton) findViewById(R.id.button_pauseStart);
+ if(paused){
+ imageButton.setImageResource(R.drawable.ic_action_play);
+ }else{
+ imageButton.setImageResource(R.drawable.ic_action_pause);
+ }
+ }
+}
diff --git a/android/sdremote/wear/src/main/java/org/libreoffice/impressremote/activity/FullscreenActivity.java b/android/sdremote/wear/src/main/java/org/libreoffice/impressremote/activity/FullscreenActivity.java
new file mode 100644
index 0000000..c25817c
--- /dev/null
+++ b/android/sdremote/wear/src/main/java/org/libreoffice/impressremote/activity/FullscreenActivity.java
@@ -0,0 +1,73 @@
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+package org.libreoffice.impressremote.activity;
+
+import android.os.Bundle;
+import android.util.Log;
+
+import com.google.android.gms.common.ConnectionResult;
+import com.google.android.gms.common.api.GoogleApiClient;
+
+import org.libreoffice.impressremote.R;
+import org.libreoffice.impressremote.communication.DataLayerListenerService;
+import org.libreoffice.impressremote.util.SlideShowData;
+
+
+public class FullscreenActivity extends ControlActivity implements
+ GoogleApiClient.ConnectionCallbacks,
+ GoogleApiClient.OnConnectionFailedListener{
+
+ private static final String TAG = "MainActivity";
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ Log.v(TAG, "onCreate");
+ setContentView(R.layout.full_screen_background);
+ SlideShowData.getInstance().setFullscreen(true);
+ changeSlideCount(SlideShowData.getInstance().getCount());
+ if(SlideShowData.getInstance().hasPreview()){
+ changePreview(SlideShowData.getInstance().getPreview());
+ }
+ }
+
+ @Override
+ protected void onDestroy() {
+ Log.v(TAG, "onDestroy");
+ super.onDestroy();
+ }
+
+ @Override
+ protected void onPause(){
+ Log.v(TAG, "onPause");
+ SlideShowData.getInstance().setFullscreen(false);
+ super.onPause();
+ }
+
+ @Override
+ protected void onStop(){
+ Log.v(TAG, "onStop");
+ super.onStop();
+ }
+
+ @Override
+ public void onConnectionSuspended(int cause) {
+ Log.v(TAG, "onConnectionSuspended called");
+ }
+
+ @Override
+ public void onConnectionFailed(ConnectionResult connectionResult) {
+ Log.v(TAG, "onConnectionFailed called");
+ }
+
+ @Override
+ public void onConnected(Bundle connectionHint) {
+ Log.v(TAG,"onConnected called");
+ DataLayerListenerService.commandConnect();
+ }
+ }
diff --git a/android/sdremote/wear/src/main/java/org/libreoffice/impressremote/activity/MainActivity.java b/android/sdremote/wear/src/main/java/org/libreoffice/impressremote/activity/MainActivity.java
deleted file mode 100644
index eeacd4e..0000000
--- a/android/sdremote/wear/src/main/java/org/libreoffice/impressremote/activity/MainActivity.java
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * This file is part of the LibreOffice project.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- */
-package org.libreoffice.impressremote.activity;
-
-import android.app.Activity;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.Bundle;
-import android.support.v4.content.LocalBroadcastManager;
-import android.util.Log;
-import android.view.View;
-import android.widget.TextView;
-
-import com.google.android.gms.common.ConnectionResult;
-import com.google.android.gms.common.api.GoogleApiClient;
-import com.google.android.gms.wearable.Wearable;
-
-import org.libreoffice.impressremote.R;
-import org.libreoffice.impressremote.communication.DataLayerListenerService;
-
-
-public class MainActivity extends Activity implements
- GoogleApiClient.ConnectionCallbacks,
- GoogleApiClient.OnConnectionFailedListener{
-
-
- private GoogleApiClient mGoogleApiClient;
- private IntentsReceiver mIntentsReceiver;
-
- private static final String TAG = "MainActivity";
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.full_screen_minimal);
-
- if(null == mGoogleApiClient) {
- mGoogleApiClient = new GoogleApiClient.Builder(this)
- .addApi(Wearable.API)
- .addConnectionCallbacks(this)
- .addOnConnectionFailedListener(this)
- .build();
- Log.v(TAG, "GoogleApiClient created");
- }
-
- if(!mGoogleApiClient.isConnected()){
- mGoogleApiClient.connect();
- Log.v(TAG, "Connecting to GoogleApiClient..");
- }
-
- registerIntentsReceiver();
-
- this.startService(new Intent(this, DataLayerListenerService.class));
-
- }
- @Override
- protected void onDestroy() {
- Log.v(TAG, "onDestroy");
- unregisterIntentsReceiver();
- this.stopService(new Intent(this, DataLayerListenerService.class));
- super.onDestroy();
- }
-
- @Override
- protected void onPause(){
- Log.v(TAG, "onPause");
- DataLayerListenerService.commandAppPaused();
- super.onPause();
- }
-
- @Override
- protected void onStop(){
- Log.v(TAG, "onStop");
- super.onStop();
- }
-
-
- private void registerIntentsReceiver() {
- mIntentsReceiver = new IntentsReceiver(this);
- IntentFilter aIntentFilter = buildIntentsReceiverFilter();
-
- LocalBroadcastManager.getInstance(getApplicationContext()).registerReceiver(mIntentsReceiver, aIntentFilter);
- }
-
- private void unregisterIntentsReceiver() {
- try {
- LocalBroadcastManager.getInstance(getApplicationContext()).unregisterReceiver(mIntentsReceiver);
- } catch (IllegalArgumentException ignored) {
-
- }
- }
-
- private IntentFilter buildIntentsReceiverFilter() {
- IntentFilter aIntentFilter = new IntentFilter();
- aIntentFilter.addAction("SLIDE_COUNT");
- return aIntentFilter;
- }
-
- @Override
- public void onConnectionSuspended(int cause) {
- Log.v(TAG, "onConnectionSuspended called");
- }
-
- @Override
- public void onConnectionFailed(ConnectionResult connectionResult) {
- Log.v(TAG,"onConnectionFailed called");
- }
-
- @Override
- public void onConnected(Bundle connectionHint) {
- Log.v(TAG,"onConnected called");
- DataLayerListenerService.commandConnect();
- }
-
- public void onButtonClickedPrevious(View target) {
- DataLayerListenerService.commandPrevious();
- }
- public void onButtonClickedNext(View target) {
- DataLayerListenerService.commandNext();
- }
- public void onButtonClickedPauseResume(View target) {
- DataLayerListenerService.commandPauseResume();
- }
- private void changeSlideCount(String count){
- TextView textView;
- textView = (TextView) findViewById(R.id.textView_counter);
- textView.setText(count);
- }
- private static final class IntentsReceiver extends BroadcastReceiver {
- private final MainActivity mainActivity;
- private IntentsReceiver(MainActivity aMainActivity) {
- mainActivity = aMainActivity;
- }
- @Override
- public void onReceive(Context context, Intent intent) {
- if (intent.getAction().equals("SLIDE_COUNT")) {
- mainActivity.changeSlideCount(intent.getStringExtra("DATA"));
- }
- Log.d("receiver", "Got message: " + intent.getStringExtra("DATA"));
- }
- }
-
-
-}
diff --git a/android/sdremote/wear/src/main/java/org/libreoffice/impressremote/activity/NotificationActivity.java b/android/sdremote/wear/src/main/java/org/libreoffice/impressremote/activity/NotificationActivity.java
new file mode 100644
index 0000000..63d9cf4
--- /dev/null
+++ b/android/sdremote/wear/src/main/java/org/libreoffice/impressremote/activity/NotificationActivity.java
@@ -0,0 +1,51 @@
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+package org.libreoffice.impressremote.activity;
+
+import android.os.Bundle;
+import android.util.Log;
+import android.widget.TextView;
+
+import org.libreoffice.impressremote.R;
+import org.libreoffice.impressremote.util.SlideShowData;
+
+public class NotificationActivity extends ControlActivity {
+ private static final String TAG = "NotificationActivity";
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ Log.v(TAG, "onCreate");
+ setContentView(R.layout.notification);
+
+ TextView mTextView = (TextView) findViewById(R.id.textView_counter);
+ mTextView.setText(SlideShowData.getInstance().getCount());
+
+ }
+
+ @Override
+ protected void onDestroy() {
+ Log.v(TAG, "onDestroy");
+ super.onDestroy();
+ }
+
+ @Override
+ protected void onPause(){
+ Log.v(TAG, "onPause");
+ super.onPause();
+ }
+
+ @Override
+ protected void onStop(){
+ Log.v(TAG, "onStop");
+ super.onStop();
+ }
+
+
+
+}
diff --git a/android/sdremote/wear/src/main/java/org/libreoffice/impressremote/communication/Commands.java b/android/sdremote/wear/src/main/java/org/libreoffice/impressremote/communication/Commands.java
new file mode 100644
index 0000000..34b5ad1
--- /dev/null
+++ b/android/sdremote/wear/src/main/java/org/libreoffice/impressremote/communication/Commands.java
@@ -0,0 +1,32 @@
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+package org.libreoffice.impressremote.communication;
+
+public class Commands {
+
+ public static final String INTENT_COUNT="COUNT";
+ public static final String INTENT_PREVIEW="PREVIEW";
+ public static final String INTENT_HAS_ASSET="HASASSET";
+
+// public static final String INTENT_FILTER_ALL_INFO="CPFILTER";
+ public static final String INTENT_UPDATE="UPDATE";
+
+ public static final String COMMAND_PRESENTATION_STOPPED="/wearableStop";
+ public static final String COMMAND_PRESENTATION_PAUSED="/pause";
+ public static final String COMMAND_PRESENTATION_RESUMED="/resume";
+ public static final String COMMAND_NOTIFY="/notification";
+
+ public static final String COMMAND_NEXT="/next";
+ public static final String COMMAND_PREVIOUS="/previous";
+ public static final String COMMAND_PAUSERESUME="/pauseResume";
+ public static final String COMMAND_CONNECT="/connect";
+// public static final String COMMAND_APP_PAUSED="/appPaused";
+
+ public static final String NULL_STRING_COUNT="0/0";
+
+}
diff --git a/android/sdremote/wear/src/main/java/org/libreoffice/impressremote/communication/DataLayerListenerService.java b/android/sdremote/wear/src/main/java/org/libreoffice/impressremote/communication/DataLayerListenerService.java
index 625bd15..5c3046d 100644
--- a/android/sdremote/wear/src/main/java/org/libreoffice/impressremote/communication/DataLayerListenerService.java
+++ b/android/sdremote/wear/src/main/java/org/libreoffice/impressremote/communication/DataLayerListenerService.java
@@ -7,9 +7,12 @@
*/
package org.libreoffice.impressremote.communication;
-import android.app.Notification;
+import static org.libreoffice.impressremote.communication.Commands.*;
+
import android.app.PendingIntent;
import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.NotificationManagerCompat;
@@ -18,7 +21,10 @@ import android.util.Log;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
+import com.google.android.gms.wearable.Asset;
+import com.google.android.gms.wearable.DataEvent;
import com.google.android.gms.wearable.DataEventBuffer;
+import com.google.android.gms.wearable.DataMapItem;
import com.google.android.gms.wearable.MessageEvent;
import com.google.android.gms.wearable.Node;
import com.google.android.gms.wearable.NodeApi;
@@ -26,34 +32,25 @@ import com.google.android.gms.wearable.Wearable;
import com.google.android.gms.wearable.WearableListenerService;
import org.libreoffice.impressremote.R;
-import org.libreoffice.impressremote.activity.MainActivity;
+import org.libreoffice.impressremote.activity.FullscreenActivity;
+import org.libreoffice.impressremote.activity.NotificationActivity;
+import org.libreoffice.impressremote.util.SlideShowData;
+import java.io.InputStream;
import java.io.UnsupportedEncodingException;
+import java.util.concurrent.TimeUnit;
public class DataLayerListenerService extends WearableListenerService implements
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {
private static final String TAG = "DataLayerListenerSrvc";
+
private static final int NOTIFICATION_ID=1;
private static final String NOTIFICATION_TITLE="Impress Remote";
- private static final String SLIDE="Slide";
- private static final String COUNT_SPLIT="/";
- private static final String OF="of";
- private static final String SPACE=" ";
- private static final String NULL_STRING_COUNT="0/0";
-
- private static final String COMMAND_NEXT="/next";
- private static final String COMMAND_PREVIOUS="/previous";
- private static final String COMMAND_PAUSERESUME="/pauseResume";
- private static final String COMMAND_CONNECT="/connect";
- private static final String COMMAND_APP_PAUSED="/appPaused";
- private static final String COMMAND_PRESENTATION_STOPPED="/wearableStop";
- private static final String COMMAND_SLIDE_COUNT="/count";
private static GoogleApiClient mGoogleApiClient;
-
public DataLayerListenerService() {
}
@@ -79,37 +76,41 @@ public class DataLayerListenerService extends WearableListenerService implements
@Override
public void onDestroy() {
-
Log.v(TAG, "Destroyed");
-
if(null != mGoogleApiClient){
if(mGoogleApiClient.isConnected()){
mGoogleApiClient.disconnect();
Log.v(TAG, "GoogleApiClient disconnected");
}
}
-
super.onDestroy();
}
@Override
public void onConnectionSuspended(int cause) {
- Log.v(TAG,"onConnectionSuspended called");
+ Log.v(TAG, "onConnectionSuspended called");
}
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
- Log.v(TAG,"onConnectionFailed called");
+ Log.v(TAG, "onConnectionFailed called");
}
@Override
public void onConnected(Bundle connectionHint) {
- Log.v(TAG,"onConnected called");
+ Log.v(TAG, "onConnected called");
}
@Override
- public void onDataChanged(DataEventBuffer dataEvents) {
- Log.v(TAG, "Data Changed");
+ public void onPeerConnected(Node peer) {
+ super.onPeerConnected(peer);
+ Log.v(TAG, "Peer Connected " + peer.getDisplayName());
+ }
+
+ @Override
+ public void onPeerDisconnected(Node peer) {
+ super.onPeerDisconnected(peer);
+ Log.v(TAG, "Peer Disconnected " + peer.getDisplayName());
}
@Override
@@ -118,35 +119,48 @@ public class DataLayerListenerService extends WearableListenerService implements
try{
String message=new String(messageEvent.getData(), "UTF-8");
Log.v(TAG, "onMessageReceived " + messageEvent.getPath()+message);
- if(messageEvent.getPath().equals(COMMAND_SLIDE_COUNT)){
- Intent aIntent= new Intent("SLIDE_COUNT");
- aIntent.putExtra("DATA",message);
- LocalBroadcastManager.getInstance(this).sendBroadcast(aIntent);
- sendLocalNotification(message);
- }
if(messageEvent.getPath().equals(COMMAND_PRESENTATION_STOPPED)){
cancelLocalNotification();
- Intent aIntent= new Intent("SLIDE_COUNT");
- aIntent.putExtra("DATA",NULL_STRING_COUNT);
+ if(SlideShowData.getInstance().isFullscreen()){
+ Intent aIntent= new Intent(COMMAND_PRESENTATION_STOPPED);
+ LocalBroadcastManager.getInstance(this).sendBroadcast(aIntent);
+ }
+ }
+ if(messageEvent.getPath().equals(COMMAND_PRESENTATION_PAUSED)){
+ Intent aIntent= new Intent(COMMAND_PRESENTATION_PAUSED);
+ LocalBroadcastManager.getInstance(this).sendBroadcast(aIntent);
+ }
+ if(messageEvent.getPath().equals(COMMAND_PRESENTATION_RESUMED)){
+ Intent aIntent= new Intent(COMMAND_PRESENTATION_RESUMED);
LocalBroadcastManager.getInstance(this).sendBroadcast(aIntent);
}
-
}catch(UnsupportedEncodingException ignored){
}
-
- }
-
- @Override
- public void onPeerConnected(Node peer) {
- super.onPeerConnected(peer);
- Log.v(TAG, "Peer Connected " + peer.getDisplayName());
}
@Override
- public void onPeerDisconnected(Node peer) {
- super.onPeerDisconnected(peer);
- Log.v(TAG, "Peer Disconnected " + peer.getDisplayName());
+ public void onDataChanged(DataEventBuffer dataEvents) {
+ Log.v(TAG, "Data Changed");
+ for(DataEvent dataEvent: dataEvents) {
+ if (dataEvent.getType() == DataEvent.TYPE_CHANGED) {
+ Log.v(TAG, "Type Changed");
+ String path=dataEvent.getDataItem().getUri().getPath();
+ if(path.equals(COMMAND_NOTIFY)){
+ DataMapItem dataMapItem = DataMapItem.fromDataItem(dataEvent.getDataItem());
+ final String count = dataMapItem.getDataMap().getString(INTENT_COUNT);
+ SlideShowData.getInstance().setCount(count);
+ if( dataMapItem.getDataMap().getBoolean(INTENT_HAS_ASSET)){
+ Asset asset = dataMapItem.getDataMap().getAsset(INTENT_PREVIEW);
+ SlideShowData.getInstance().setPreview(loadBitmapFromAsset(asset));
+ SlideShowData.getInstance().setHasPreview(true);
+ }else{
+ SlideShowData.getInstance().setHasPreview(false);
+ }
+ notifyActivity();
+ }
+ }
+ }
}
private static void sendMessage( final String path) {
@@ -156,8 +170,8 @@ public class DataLayerListenerService extends WearableListenerService implements
if(mGoogleApiClient!=null){
NodeApi.GetConnectedNodesResult nodes =
Wearable.NodeApi.getConnectedNodes( mGoogleApiClient ).await();
- for(Node node : nodes.getNodes()) {
- Log.d(TAG, "SendMessage " + path );
+ for (Node node : nodes.getNodes()) {
+ Log.d(TAG, "SendMessage " + path);
Wearable.MessageApi.sendMessage(
mGoogleApiClient, node.getId(), path, null).await();
}
@@ -166,51 +180,89 @@ public class DataLayerListenerService extends WearableListenerService implements
}).start();
}
- private void cancelLocalNotification(){
- NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
- notificationManager.cancel(NOTIFICATION_ID);
+ private void notifyActivity(){
+ if(SlideShowData.getInstance().isFullscreen()){
+ broadcastLocalIntent();
+ }else{
+ sendLocalNotification();
+ }
+ }
+
+ private void broadcastLocalIntent(){
+ Log.v(TAG, "broadcastLocalIntent");
+ Intent aIntent= new Intent(INTENT_UPDATE);
+ LocalBroadcastManager.getInstance(this).sendBroadcast(aIntent);
}
- private void sendLocalNotification(String count) {
+ private void sendLocalNotification() {
Log.v(TAG, "sendLocalNotification");
- Intent startIntent;
- startIntent = new Intent(this, MainActivity.class).setAction(Intent.ACTION_VIEW);
+ Intent notificationIntent = new Intent(this, NotificationActivity.class);
+ PendingIntent notificationPendingIntent = PendingIntent.getActivity(
+ this, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
+
+ Intent startIntent = new Intent(this, FullscreenActivity.class).setAction(Intent.ACTION_VIEW);
PendingIntent startPendingIntent = PendingIntent.getActivity(this, 0, startIntent, 0);
- Notification notify = new NotificationCompat.Builder(this)
- .setContentTitle(NOTIFICATION_TITLE)
- .setContentText(getNotificationMessage(count))
- .setLocalOnly(true)
- .setOngoing(true)
- .setSmallIcon(R.drawable.ic_launcher)
- .setContentIntent(startPendingIntent)
- .build();
+ NotificationCompat.Builder notificationBuilder =
+ new NotificationCompat.Builder(this)
+ .setSmallIcon(R.drawable.ic_launcher)
+ .setContentTitle(NOTIFICATION_TITLE)
+ .setContentText(SlideShowData.getInstance().getCount())
+ .setOngoing(true)
+ .setContentIntent(startPendingIntent);
+ if(SlideShowData.getInstance().hasPreview()){
+ notificationBuilder.extend(new NotificationCompat.WearableExtender()
+ .setDisplayIntent(notificationPendingIntent).setBackground(SlideShowData.getInstance().getPreview()));
+ }else{
+ notificationBuilder.extend(new NotificationCompat.WearableExtender()
+ .setDisplayIntent(notificationPendingIntent));
+ }
- cancelLocalNotification();
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
- notificationManager.notify(NOTIFICATION_ID, notify);
-
+ notificationManager.notify(NOTIFICATION_ID, notificationBuilder.build());
}
- private String getNotificationMessage(String count){
- return SLIDE+SPACE+count.substring(0,count.indexOf(COUNT_SPLIT))+SPACE+OF+SPACE+count.substring(1+count.indexOf(COUNT_SPLIT));
+ private void cancelLocalNotification(){
+ NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
+ notificationManager.cancel(NOTIFICATION_ID);
}
public static void commandNext(){
sendMessage(COMMAND_NEXT);
}
+
public static void commandPrevious(){
sendMessage(COMMAND_PREVIOUS);
}
+
public static void commandPauseResume(){
sendMessage(COMMAND_PAUSERESUME);
}
+
public static void commandConnect(){
sendMessage(COMMAND_CONNECT);
}
- public static void commandAppPaused(){
- sendMessage(COMMAND_APP_PAUSED);
+
+ public Bitmap loadBitmapFromAsset(Asset asset) {
+ if (asset == null) {
+ throw new IllegalArgumentException("Asset must be non-null");
+ }
+ ConnectionResult result =
+ mGoogleApiClient.blockingConnect(5000, TimeUnit.MILLISECONDS);
+ if (!result.isSuccess()) {
+ return null;
+ }
+
+ InputStream assetInputStream = Wearable.DataApi.getFdForAsset(
+ mGoogleApiClient, asset).await().getInputStream();
+
+ if (assetInputStream == null) {
+ Log.w(TAG, "Requested an unknown Asset.");
+ return null;
+ }
+
+ return BitmapFactory.decodeStream(assetInputStream);
}
} \ No newline at end of file
diff --git a/android/sdremote/wear/src/main/java/org/libreoffice/impressremote/util/SlideShowData.java b/android/sdremote/wear/src/main/java/org/libreoffice/impressremote/util/SlideShowData.java
new file mode 100644
index 0000000..fe1678c
--- /dev/null
+++ b/android/sdremote/wear/src/main/java/org/libreoffice/impressremote/util/SlideShowData.java
@@ -0,0 +1,64 @@
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+package org.libreoffice.impressremote.util;
+
+import android.graphics.Bitmap;
+
+import org.libreoffice.impressremote.communication.Commands;
+
+public class SlideShowData {
+ private static SlideShowData instance=new SlideShowData();
+ private String count;
+ private Bitmap preview;
+ private boolean hasPreview;
+ private boolean fullscreen;
+
+ private SlideShowData(){
+ count= Commands.NULL_STRING_COUNT;
+ hasPreview=false;
+ fullscreen=false;
+ }
+ public static SlideShowData getInstance(){
+ if(instance==null){
+ instance=new SlideShowData();
+ }
+ return instance;
+ }
+
+ public String getCount() {
+ return count;
+ }
+
+ public void setCount(String count) {
+ this.count = count;
+ }
+
+ public Bitmap getPreview() {
+ return preview;
+ }
+
+ public void setPreview(Bitmap preview) {
+ this.preview = preview;
+ }
+
+ public boolean hasPreview() {
+ return hasPreview;
+ }
+
+ public void setHasPreview(boolean hasPreview) {
+ this.hasPreview = hasPreview;
+ }
+
+ public boolean isFullscreen() {
+ return fullscreen;
+ }
+
+ public void setFullscreen(boolean fullscreen) {
+ this.fullscreen = fullscreen;
+ }
+}
diff --git a/android/sdremote/wear/src/main/res/color/button_colors.xml b/android/sdremote/wear/src/main/res/color/button_colors.xml
new file mode 100644
index 0000000..dad1f40
--- /dev/null
+++ b/android/sdremote/wear/src/main/res/color/button_colors.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_pressed="true"
+ android:drawable="@color/grey"/>
+ <item android:drawable="@color/semitransparent_grey"/>
+</selector>
diff --git a/android/sdremote/wear/src/main/res/drawable-hdpi/ic_action_next.png b/android/sdremote/wear/src/main/res/drawable-hdpi/ic_action_next.png
new file mode 100644
index 0000000..b05ffcd
--- /dev/null
+++ b/android/sdremote/wear/src/main/res/drawable-hdpi/ic_action_next.png
Binary files differ
diff --git a/android/sdremote/wear/src/main/res/drawable-hdpi/ic_action_pause.png b/android/sdremote/wear/src/main/res/drawable-hdpi/ic_action_pause.png
new file mode 100644
index 0000000..d30ba3c
--- /dev/null
+++ b/android/sdremote/wear/src/main/res/drawable-hdpi/ic_action_pause.png
Binary files differ
diff --git a/android/sdremote/wear/src/main/res/drawable-hdpi/ic_action_play.png b/android/sdremote/wear/src/main/res/drawable-hdpi/ic_action_play.png
new file mode 100644
index 0000000..869f001
--- /dev/null
+++ b/android/sdremote/wear/src/main/res/drawable-hdpi/ic_action_play.png
Binary files differ
diff --git a/android/sdremote/wear/src/main/res/drawable-hdpi/ic_action_previous.png b/android/sdremote/wear/src/main/res/drawable-hdpi/ic_action_previous.png
new file mode 100644
index 0000000..06e70d5
--- /dev/null
+++ b/android/sdremote/wear/src/main/res/drawable-hdpi/ic_action_previous.png
Binary files differ
diff --git a/android/sdremote/wear/src/main/res/drawable-mdpi/ic_action_next.png b/android/sdremote/wear/src/main/res/drawable-mdpi/ic_action_next.png
new file mode 100644
index 0000000..91ca636
--- /dev/null
+++ b/android/sdremote/wear/src/main/res/drawable-mdpi/ic_action_next.png
Binary files differ
diff --git a/android/sdremote/wear/src/main/res/drawable-mdpi/ic_action_pause.png b/android/sdremote/wear/src/main/res/drawable-mdpi/ic_action_pause.png
new file mode 100644
index 0000000..2c96c7b
--- /dev/null
+++ b/android/sdremote/wear/src/main/res/drawable-mdpi/ic_action_pause.png
Binary files differ
diff --git a/android/sdremote/wear/src/main/res/drawable-mdpi/ic_action_play.png b/android/sdremote/wear/src/main/res/drawable-mdpi/ic_action_play.png
new file mode 100644
index 0000000..5f3bf86
--- /dev/null
+++ b/android/sdremote/wear/src/main/res/drawable-mdpi/ic_action_play.png
Binary files differ
diff --git a/android/sdremote/wear/src/main/res/drawable-mdpi/ic_action_previous.png b/android/sdremote/wear/src/main/res/drawable-mdpi/ic_action_previous.png
new file mode 100644
index 0000000..c862832
--- /dev/null
+++ b/android/sdremote/wear/src/main/res/drawable-mdpi/ic_action_previous.png
Binary files differ
diff --git a/android/sdremote/wear/src/main/res/drawable-xhdpi/ic_action_next.png b/android/sdremote/wear/src/main/res/drawable-xhdpi/ic_action_next.png
new file mode 100644
index 0000000..973c67f
--- /dev/null
+++ b/android/sdremote/wear/src/main/res/drawable-xhdpi/ic_action_next.png
Binary files differ
diff --git a/android/sdremote/wear/src/main/res/drawable-xhdpi/ic_action_pause.png b/android/sdremote/wear/src/main/res/drawable-xhdpi/ic_action_pause.png
new file mode 100644
index 0000000..504389a
--- /dev/null
+++ b/android/sdremote/wear/src/main/res/drawable-xhdpi/ic_action_pause.png
Binary files differ
diff --git a/android/sdremote/wear/src/main/res/drawable-xhdpi/ic_action_play.png b/android/sdremote/wear/src/main/res/drawable-xhdpi/ic_action_play.png
new file mode 100644
index 0000000..7f709bb
--- /dev/null
+++ b/android/sdremote/wear/src/main/res/drawable-xhdpi/ic_action_play.png
Binary files differ
diff --git a/android/sdremote/wear/src/main/res/drawable-xhdpi/ic_action_previous.png b/android/sdremote/wear/src/main/res/drawable-xhdpi/ic_action_previous.png
new file mode 100644
index 0000000..350ca6a
--- /dev/null
+++ b/android/sdremote/wear/src/main/res/drawable-xhdpi/ic_action_previous.png
Binary files differ
diff --git a/android/sdremote/wear/src/main/res/drawable-xxhdpi/ic_action_next.png b/android/sdremote/wear/src/main/res/drawable-xxhdpi/ic_action_next.png
new file mode 100644
index 0000000..7e31df8
--- /dev/null
+++ b/android/sdremote/wear/src/main/res/drawable-xxhdpi/ic_action_next.png
Binary files differ
diff --git a/android/sdremote/wear/src/main/res/drawable-xxhdpi/ic_action_pause.png b/android/sdremote/wear/src/main/res/drawable-xxhdpi/ic_action_pause.png
new file mode 100644
index 0000000..c3b376a
--- /dev/null
+++ b/android/sdremote/wear/src/main/res/drawable-xxhdpi/ic_action_pause.png
Binary files differ
diff --git a/android/sdremote/wear/src/main/res/drawable-xxhdpi/ic_action_play.png b/android/sdremote/wear/src/main/res/drawable-xxhdpi/ic_action_play.png
new file mode 100644
index 0000000..df59947
--- /dev/null
+++ b/android/sdremote/wear/src/main/res/drawable-xxhdpi/ic_action_play.png
Binary files differ
diff --git a/android/sdremote/wear/src/main/res/drawable-xxhdpi/ic_action_previous.png b/android/sdremote/wear/src/main/res/drawable-xxhdpi/ic_action_previous.png
new file mode 100644
index 0000000..3e0997a
--- /dev/null
+++ b/android/sdremote/wear/src/main/res/drawable-xxhdpi/ic_action_previous.png
Binary files differ
diff --git a/android/sdremote/wear/src/main/res/layout/full_screen.xml b/android/sdremote/wear/src/main/res/layout/full_screen.xml
deleted file mode 100644
index 6def45e..0000000
--- a/android/sdremote/wear/src/main/res/layout/full_screen.xml
+++ /dev/null
@@ -1,57 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="wrap_content"
- android:layout_height="fill_parent"
- android:gravity="center">
-
- <TableRow
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:gravity="center_horizontal">
-
- <Button
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="Previous"
- android:id="@+id/button_previous"
- android:onClick="onButtonClickedPrevious" />
-
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:id="@+id/textView_counter"
- android:layout_weight="1"
- android:gravity="center_horizontal"
- android:autoText="false"
- android:text="0/0" />
-
- <Button
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="Next"
- android:id="@+id/button_next"
- android:onClick="onButtonClickedNext" />
- </TableRow>
-
- <TableRow
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:gravity="center_horizontal">
-
- <Button
- style="?android:attr/buttonStyleSmall"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="Pause"
- android:id="@+id/button_pause"
- android:onClick="onButtonClickedPause" />
-
- <Button
- style="?android:attr/buttonStyleSmall"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="Resume"
- android:id="@+id/button_resume"
- android:onClick="onButtonClickedResume" />
- </TableRow>
-</TableLayout> \ No newline at end of file
diff --git a/android/sdremote/wear/src/main/res/layout/full_screen_background.xml b/android/sdremote/wear/src/main/res/layout/full_screen_background.xml
new file mode 100644
index 0000000..1312a5b
--- /dev/null
+++ b/android/sdremote/wear/src/main/res/layout/full_screen_background.xml
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FrameLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:layout_height="match_parent"
+ android:layout_width="match_parent"
+ android:padding="10dp"
+ android:background="@color/white">
+
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:id="@+id/preview"
+ android:scaleType = "centerCrop"
+ android:layout_gravity="center" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:padding="5dp"
+ app:layout_box="all">
+
+
+ <LinearLayout
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:orientation="vertical"
+ android:paddingLeft="5dp"
+ android:layout_gravity="top">
+ <TextView
+ android:fontFamily="sans-serif-light"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:text="@string/null_slide_count"
+ android:id="@+id/textView_counter"
+ android:textColor="@color/black"
+ android:textSize="20sp"
+ android:gravity="center" />
+
+ </LinearLayout>
+
+ <LinearLayout
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="bottom|center_horizontal"
+ android:divider="@color/dark_grey"
+ android:showDividers="middle"
+ android:gravity="center">
+
+ <ImageButton
+ android:layout_width="40dp"
+ android:layout_height="wrap_content"
+ android:id="@+id/button_previous"
+ android:onClick="onButtonClickedPrevious"
+ android:background="@color/button_colors"
+ android:src="@drawable/ic_action_previous" />
+
+ <ImageButton
+ android:layout_width="50dp"
+ android:layout_height="wrap_content"
+ android:id="@+id/button_pauseStart"
+ android:onClick="onButtonClickedPauseResume"
+ android:background="@color/button_colors"
+ android:src="@drawable/ic_action_pause" />
+
+ <ImageButton
+ android:layout_width="40dp"
+ android:layout_height="wrap_content"
+ android:id="@+id/button_next"
+ android:onClick="onButtonClickedNext"
+ android:background="@color/button_colors"
+ android:src="@drawable/ic_action_next" />
+ </LinearLayout>
+
+
+ </FrameLayout>
+</FrameLayout> \ No newline at end of file
diff --git a/android/sdremote/wear/src/main/res/layout/full_screen_minimal.xml b/android/sdremote/wear/src/main/res/layout/full_screen_minimal.xml
deleted file mode 100644
index 1572ed2..0000000
--- a/android/sdremote/wear/src/main/res/layout/full_screen_minimal.xml
+++ /dev/null
@@ -1,57 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<android.support.wearable.view.BoxInsetLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- android:layout_height="match_parent"
- android:layout_width="match_parent"
- android:padding="10dp">
-
- <FrameLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:padding="5dp"
- app:layout_box="all">
-
-
- <Button
- style="?android:attr/buttonStyleSmall"
- android:text="@string/left_arrow"
- android:id="@+id/button_previous"
- android:onClick="onButtonClickedPrevious"
- android:layout_gravity="center|left"
- android:layout_height="50dp"
- android:layout_width="50dp"
- />
-
- <Button
- style="?android:attr/buttonStyleSmall"
- android:text="@string/right_arrow"
- android:id="@+id/button_next"
- android:onClick="onButtonClickedNext"
- android:layout_gravity="center|right"
- android:layout_height="50dp"
- android:layout_width="50dp"
- />
-
- <Button
- style="?android:attr/buttonStyleSmall"
- android:text="@string/pause_resume"
- android:id="@+id/button_pauseStart"
- android:onClick="onButtonClickedPauseResume"
- android:layout_gravity="center"
- android:layout_height="50dp"
- android:layout_width="50dp"
- />
-
- <TextView
- android:layout_width="50dp"
- android:layout_height="50dp"
- android:id="@+id/textView_counter"
- android:gravity="top|center|bottom"
- android:autoText="false"
- android:text="@string/null_slide_count"
- android:layout_gravity="center_horizontal|top" />
-
-
- </FrameLayout>
-</android.support.wearable.view.BoxInsetLayout> \ No newline at end of file
diff --git a/android/sdremote/wear/src/main/res/layout/notification.xml b/android/sdremote/wear/src/main/res/layout/notification.xml
new file mode 100644
index 0000000..35779f8
--- /dev/null
+++ b/android/sdremote/wear/src/main/res/layout/notification.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:padding="5dp"
+ app:layout_box="all">
+
+
+ <LinearLayout
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:orientation="vertical"
+ android:paddingLeft="5dp"
+ android:layout_gravity="top">
+ <TextView
+ android:fontFamily="sans-serif-light"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:text="@string/null_slide_count"
+ android:id="@+id/textView_counter"
+ android:textColor="@color/black"
+ android:textSize="20sp"
+ android:gravity="center" />
+
+ </LinearLayout>
+
+ <LinearLayout
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="bottom|center_horizontal"
+ android:gravity="center">
+
+ <ImageButton
+ android:layout_width="40dp"
+ android:layout_height="wrap_content"
+ android:id="@+id/button_previous"
+ android:onClick="onButtonClickedPrevious"
+ android:src="@drawable/ic_action_previous" />
+
+ <ImageButton
+ android:layout_width="50dp"
+ android:layout_height="wrap_content"
+ android:id="@+id/button_pauseStart"
+ android:onClick="onButtonClickedPauseResume"
+ android:src="@drawable/ic_action_pause" />
+
+ <ImageButton
+ android:layout_width="40dp"
+ android:layout_height="wrap_content"
+ android:id="@+id/button_next"
+ android:onClick="onButtonClickedNext"
+ android:src="@drawable/ic_action_next" />
+ </LinearLayout>
+
+
+ </FrameLayout>
+
+</FrameLayout> \ No newline at end of file