aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Monk <jmonk@google.com>2017-09-26 15:00:52 -0400
committerJason Monk <jmonk@google.com>2017-10-30 11:12:22 -0400
commit4aa13147dc5a0b12e15b8bc91a44bedc8f4ee121 (patch)
treecd893f4a69b91aa6e2392988f175a6b059a8ea80
parent4cb0d34ba8edb5affdd0bcf76905571b8624c68c (diff)
downloadexperimental-4aa13147dc5a0b12e15b8bc91a44bedc8f4ee121.tar.gz
Example Slices app and Slice Presenter app
- Enable preview behind flag for debugging / testing - Add shortcut as option - Updates to provider to display actions + shortcut - Adds a bunch of icons / images for building future templates based on UX mocks Presents any slices provided by installed apps
-rw-r--r--SlicePresenter/Android.mk29
-rw-r--r--SlicePresenter/AndroidManifest.xml38
-rw-r--r--SlicePresenter/res/layout/activity_layout.xml59
-rw-r--r--SlicePresenter/res/values/strings.xml21
-rw-r--r--SlicePresenter/src/com/android/experimental/slicepresenter/SlicePresenter.java176
-rw-r--r--SlicesApp/Android.mk29
-rw-r--r--SlicesApp/AndroidManifest.xml55
-rw-r--r--SlicesApp/res/drawable/ic_add.xml27
-rw-r--r--SlicesApp/res/drawable/ic_camera.xml18
-rw-r--r--SlicesApp/res/drawable/ic_car.xml17
-rw-r--r--SlicesApp/res/drawable/ic_create.xml9
-rw-r--r--SlicesApp/res/drawable/ic_done.xml13
-rw-r--r--SlicesApp/res/drawable/ic_down.xml13
-rw-r--r--SlicesApp/res/drawable/ic_home.xml13
-rw-r--r--SlicesApp/res/drawable/ic_list.xml14
-rw-r--r--SlicesApp/res/drawable/ic_next.xml13
-rw-r--r--SlicesApp/res/drawable/ic_pause.xml13
-rw-r--r--SlicesApp/res/drawable/ic_photo.xml14
-rw-r--r--SlicesApp/res/drawable/ic_play.xml13
-rw-r--r--SlicesApp/res/drawable/ic_prev.xml13
-rw-r--r--SlicesApp/res/drawable/ic_remove.xml27
-rw-r--r--SlicesApp/res/drawable/ic_reply.xml13
-rw-r--r--SlicesApp/res/drawable/ic_share.xml18
-rw-r--r--SlicesApp/res/drawable/ic_slice.xml9
-rw-r--r--SlicesApp/res/drawable/ic_up.xml13
-rw-r--r--SlicesApp/res/drawable/ic_video.xml14
-rw-r--r--SlicesApp/res/drawable/ic_voice.xml16
-rw-r--r--SlicesApp/res/drawable/ic_work.xml14
-rw-r--r--SlicesApp/res/drawable/mady.jpgbin0 -> 67605 bytes
-rw-r--r--SlicesApp/res/drawable/weather_1.pngbin0 -> 7909 bytes
-rw-r--r--SlicesApp/res/drawable/weather_2.pngbin0 -> 10095 bytes
-rw-r--r--SlicesApp/res/drawable/weather_3.pngbin0 -> 8737 bytes
-rw-r--r--SlicesApp/res/drawable/weather_4.pngbin0 -> 6377 bytes
-rw-r--r--SlicesApp/res/layout/activity_layout.xml86
-rw-r--r--SlicesApp/res/values/strings.xml18
-rw-r--r--SlicesApp/src/com/android/experimental/slicesapp/SlicesActivity.java136
-rw-r--r--SlicesApp/src/com/android/experimental/slicesapp/SlicesProvider.java313
37 files changed, 1274 insertions, 0 deletions
diff --git a/SlicePresenter/Android.mk b/SlicePresenter/Android.mk
new file mode 100644
index 0000000..19a5b74
--- /dev/null
+++ b/SlicePresenter/Android.mk
@@ -0,0 +1,29 @@
+# Copyright (C) 2017 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_PACKAGE_NAME := SlicePresenter
+LOCAL_SRC_FILES := $(call all-java-files-under, src) \
+ $(call all-Iaidl-files-under, src)
+
+LOCAL_CERTIFICATE := platform
+
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+
+LOCAL_PROGUARD_ENABLED := disabled
+
+include $(BUILD_PACKAGE)
diff --git a/SlicePresenter/AndroidManifest.xml b/SlicePresenter/AndroidManifest.xml
new file mode 100644
index 0000000..fff34b2
--- /dev/null
+++ b/SlicePresenter/AndroidManifest.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.experimental.slicepresenter">
+
+ <uses-sdk
+ android:minSdkVersion="26" />
+
+ <uses-permission android:name="android.permission.BIND_SLICE" />
+
+ <application android:label="@string/app_label">
+ <activity android:name=".SlicePresenter">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ </application>
+
+</manifest>
+
diff --git a/SlicePresenter/res/layout/activity_layout.xml b/SlicePresenter/res/layout/activity_layout.xml
new file mode 100644
index 0000000..98a838b
--- /dev/null
+++ b/SlicePresenter/res/layout/activity_layout.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:gravity="top"
+ android:orientation="vertical" >
+
+ <ScrollView
+ android:id="@+id/container"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1" >
+
+ <FrameLayout
+ android:id="@+id/slice_preview"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical" />
+ </ScrollView>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_gravity="bottom"
+ android:layout_margin="16dp"
+ android:layout_weight="0.25"
+ android:orientation="horizontal" >
+
+ <Spinner
+ android:id="@+id/spinner"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:padding="8dp" />
+
+ <Button
+ android:id="@+id/slice_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:padding="8dp"
+ android:text="@string/intent_button" />
+ </LinearLayout>
+
+</LinearLayout> \ No newline at end of file
diff --git a/SlicePresenter/res/values/strings.xml b/SlicePresenter/res/values/strings.xml
new file mode 100644
index 0000000..baf6e3a
--- /dev/null
+++ b/SlicePresenter/res/values/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_label">Slice Presenter</string>
+
+ <string name="intent_button">Use Intent Slice</string>
+ <string name="uri_button">Use URI Slice</string>
+</resources>
diff --git a/SlicePresenter/src/com/android/experimental/slicepresenter/SlicePresenter.java b/SlicePresenter/src/com/android/experimental/slicepresenter/SlicePresenter.java
new file mode 100644
index 0000000..e6d6550
--- /dev/null
+++ b/SlicePresenter/src/com/android/experimental/slicepresenter/SlicePresenter.java
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.experimental.slicepresenter;
+
+import android.app.Activity;
+import android.app.slice.Slice;
+import android.app.slice.widget.SliceView;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.net.Uri;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemSelectedListener;
+import android.widget.ArrayAdapter;
+import android.widget.Button;
+import android.widget.LinearLayout;
+import android.widget.Spinner;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class SlicePresenter extends Activity {
+
+ private static final String TAG = "SlicePresenter";
+
+ private static final String SLICE_METADATA_KEY = "android.metadata.SLICE_URI";
+
+ private ArrayList<Uri> mSliceUris = new ArrayList<Uri>();
+ private String mSelectedMode;
+ private ViewGroup mContainer;
+ private boolean mShowingIntentSlice;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_layout);
+
+ // Shows the slice
+ mContainer = (ViewGroup) findViewById(R.id.slice_preview);
+
+ // Select the slice mode
+ List<String> list = new ArrayList<>();
+ list.add(SliceView.MODE_SHORTCUT);
+ list.add(SliceView.MODE_SMALL);
+ list.add(SliceView.MODE_LARGE);
+ Spinner spinner = (Spinner) findViewById(R.id.spinner);
+ ArrayAdapter<String> adapter = new ArrayAdapter<>(this,
+ android.R.layout.simple_spinner_item, list);
+ adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+ spinner.setAdapter(adapter);
+ mSelectedMode = (savedInstanceState != null)
+ ? savedInstanceState.getString("SELECTED_MODE", list.get(0))
+ : list.get(0);
+ spinner.setSelection(list.indexOf(mSelectedMode));
+ spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
+ @Override
+ public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
+ mSelectedMode = list.get(position);
+ updateSliceModes();
+ }
+
+ @Override
+ public void onNothingSelected(AdapterView<?> parent) {
+ }
+ });
+
+ // Toggle slice between URI based or Intent based
+ final String intentButton = getResources().getString(R.string.intent_button);
+ final String uriButton = getResources().getString(R.string.uri_button);
+ Button button = (Button) findViewById(R.id.slice_button);
+ button.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ final String state = (String) button.getText();
+ final String newState = state.equals(intentButton) ? uriButton : intentButton;
+ button.setText(newState);
+ mShowingIntentSlice = newState.equals(uriButton);
+ if (mShowingIntentSlice) {
+ showIntentSlice();
+ } else {
+ showAvailableSlices();
+ }
+ }
+ });
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ outState.putString("SELECTED_MODE", mSelectedMode);
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ if (mShowingIntentSlice) {
+ showIntentSlice();
+ } else {
+ showAvailableSlices();
+ }
+ }
+
+ private void showAvailableSlices() {
+ mContainer.removeAllViews();
+ mSliceUris.clear();
+ List<PackageInfo> packageInfos = getPackageManager()
+ .getInstalledPackages(PackageManager.GET_ACTIVITIES | PackageManager.GET_META_DATA);
+ for (PackageInfo pi : packageInfos) {
+ ActivityInfo[] activityInfos = pi.activities;
+ if (activityInfos != null) {
+ for (ActivityInfo ai : activityInfos) {
+ if (ai.metaData != null) {
+ String sliceUri = ai.metaData.getString(SLICE_METADATA_KEY);
+ if (sliceUri != null) {
+ mSliceUris.add(Uri.parse(sliceUri));
+ }
+ }
+ }
+ }
+ }
+ for (int i = 0; i < mSliceUris.size(); i++) {
+ addSlice(mSliceUris.get(i));
+ }
+ }
+
+ private void addSlice(Uri uri) {
+ if (ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
+ SliceView v = new SliceView(getApplicationContext());
+ v.setTag(uri);
+ mContainer.addView(v);
+ v.setMode(mSelectedMode);
+ v.setSlice(uri);
+ } else {
+ Log.w(TAG, "Invalid uri, skipping slice: " + uri);
+ }
+ }
+
+ private void showIntentSlice() {
+ Intent intent = new Intent("android.intent.action.EXAMPLE_ACTION");
+ mContainer.removeAllViews();
+ SliceView v = new SliceView(getApplicationContext());
+ v.setTag(intent);
+ /*
+ boolean added = v.setSlice(intent);
+ if (added) {
+ mContainer.addView(v);
+ v.setMode(mSelectedMode);
+ }
+ */
+ }
+
+ private void updateSliceModes() {
+ final int count = mContainer.getChildCount();
+ for (int i = 0; i < count; i++) {
+ ((SliceView) mContainer.getChildAt(i)).setMode(mSelectedMode);
+ }
+ }
+}
diff --git a/SlicesApp/Android.mk b/SlicesApp/Android.mk
new file mode 100644
index 0000000..871aa4b
--- /dev/null
+++ b/SlicesApp/Android.mk
@@ -0,0 +1,29 @@
+# Copyright (C) 2017 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_PACKAGE_NAME := SlicesApp
+LOCAL_SRC_FILES := $(call all-java-files-under, src) \
+ $(call all-Iaidl-files-under, src)
+
+LOCAL_CERTIFICATE := platform
+
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+
+LOCAL_PROGUARD_ENABLED := disabled
+
+include $(BUILD_PACKAGE)
diff --git a/SlicesApp/AndroidManifest.xml b/SlicesApp/AndroidManifest.xml
new file mode 100644
index 0000000..40f714d
--- /dev/null
+++ b/SlicesApp/AndroidManifest.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.experimental.slicesapp">
+
+ <uses-sdk
+ android:minSdkVersion="26" />
+
+ <uses-permission android:name="android.permission.BIND_SLICE" />
+
+ <application android:label="@string/app_label">
+ <activity android:name=".SlicesActivity">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ <intent-filter>
+ <action android:name="android.intent.action.VIEW_SLICE" />
+ <data android:scheme="content"
+ android:host="com.android.experimental.slicesapp"
+ android:pathPrefix="/main" />
+ </intent-filter>
+ <meta-data android:name="android.metadata.SLICE_URI"
+ android:value="content://com.android.experimental.slicesapp/main" />
+ </activity>
+
+ <provider android:name=".SlicesProvider"
+ android:authorities="com.android.experimental.slicesapp"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.intent.action.VIEW_SLICE" />
+ <action android:name="android.intent.action.EXAMPLE_ACTION" />
+ </intent-filter>
+ </provider>
+
+ </application>
+
+</manifest>
+
diff --git a/SlicesApp/res/drawable/ic_add.xml b/SlicesApp/res/drawable/ic_add.xml
new file mode 100644
index 0000000..56d3416
--- /dev/null
+++ b/SlicesApp/res/drawable/ic_add.xml
@@ -0,0 +1,27 @@
+<!--
+Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24.0dp"
+ android:height="24.0dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M19.0,13.0l-6.0,0.0l0.0,6.0l-2.0,0.0l0.0,-6.0L5.0,13.0l0.0,-2.0l6.0,0.0L11.0,5.0l2.0,0.0l0.0,6.0l6.0,0.0l0.0,2.0z"/>
+ <path
+ android:pathData="M0 0h24v24H0z"
+ android:fillColor="#00000000"/>
+</vector>
diff --git a/SlicesApp/res/drawable/ic_camera.xml b/SlicesApp/res/drawable/ic_camera.xml
new file mode 100644
index 0000000..1a2ef24
--- /dev/null
+++ b/SlicesApp/res/drawable/ic_camera.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:fillColor="#000000"
+ android:pathData="M 12 8.8 C 13.7673111995 8.8 15.2 10.2326888005 15.2 12 C 15.2 13.7673111995 13.7673111995 15.2 12 15.2 C 10.2326888005 15.2 8.8 13.7673111995 8.8 12 C 8.8 10.2326888005 10.2326888005 8.8 12 8.8 Z" />
+ <path
+ android:fillColor="#000000"
+ android:pathData="M9 2L7.17 4H4c-1.1 0-2 .9-2 2v12c0 1.1 .9 2 2 2h16c1.1 0 2-.9
+2-2V6c0-1.1-.9-2-2-2h-3.17L15 2H9zm3 15c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5
+5-2.24 5-5 5z" />
+ <path
+ android:pathData="M0 0h24v24H0z" />
+</vector> \ No newline at end of file
diff --git a/SlicesApp/res/drawable/ic_car.xml b/SlicesApp/res/drawable/ic_car.xml
new file mode 100644
index 0000000..cdf0a6d
--- /dev/null
+++ b/SlicesApp/res/drawable/ic_car.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:fillColor="#000000"
+ android:pathData="M18.92 6.01C18.72 5.42 18.16 5 17.5 5h-11c-.66 0-1.21 .42 -1.42 1.01L3 12v8c0
+.55 .45 1 1 1h1c.55 0 1-.45 1-1v-1h12v1c0 .55 .45 1 1 1h1c.55 0 1-.45
+1-1v-8l-2.08-5.99zM6.5 16c-.83 0-1.5-.67-1.5-1.5S5.67 13 6.5 13s1.5 .67 1.5
+1.5S7.33 16 6.5 16zm11 0c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5 .67 1.5
+1.5-.67 1.5-1.5 1.5zM5 11l1.5-4.5h11L19 11H5z" />
+ <path
+ android:pathData="M0 0h24v24H0z" />
+</vector> \ No newline at end of file
diff --git a/SlicesApp/res/drawable/ic_create.xml b/SlicesApp/res/drawable/ic_create.xml
new file mode 100644
index 0000000..2ab2fb7
--- /dev/null
+++ b/SlicesApp/res/drawable/ic_create.xml
@@ -0,0 +1,9 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M3,17.25V21h3.75L17.81,9.94l-3.75,-3.75L3,17.25zM20.71,7.04c0.39,-0.39 0.39,-1.02 0,-1.41l-2.34,-2.34c-0.39,-0.39 -1.02,-0.39 -1.41,0l-1.83,1.83 3.75,3.75 1.83,-1.83z"/>
+</vector>
diff --git a/SlicesApp/res/drawable/ic_done.xml b/SlicesApp/res/drawable/ic_done.xml
new file mode 100644
index 0000000..5dc4039
--- /dev/null
+++ b/SlicesApp/res/drawable/ic_done.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:pathData="M0 0h24v24H0z" />
+ <path
+ android:fillColor="#000000"
+ android:pathData="M9 16.2L4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4L9 16.2z" />
+</vector> \ No newline at end of file
diff --git a/SlicesApp/res/drawable/ic_down.xml b/SlicesApp/res/drawable/ic_down.xml
new file mode 100644
index 0000000..1399b16
--- /dev/null
+++ b/SlicesApp/res/drawable/ic_down.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:fillColor="#000000"
+ android:pathData="M7.41 7.84L12 12.42l4.59-4.58L18 9.25l-6 6-6-6z" />
+ <path
+ android:pathData="M0-.75h24v24H0z" />
+</vector> \ No newline at end of file
diff --git a/SlicesApp/res/drawable/ic_home.xml b/SlicesApp/res/drawable/ic_home.xml
new file mode 100644
index 0000000..2332f3f
--- /dev/null
+++ b/SlicesApp/res/drawable/ic_home.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:fillColor="#000000"
+ android:pathData="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z" />
+ <path
+ android:pathData="M0 0h24v24H0z" />
+</vector> \ No newline at end of file
diff --git a/SlicesApp/res/drawable/ic_list.xml b/SlicesApp/res/drawable/ic_list.xml
new file mode 100644
index 0000000..6e8b482
--- /dev/null
+++ b/SlicesApp/res/drawable/ic_list.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:fillColor="#000000"
+ android:pathData="M3 13h2v-2H3v2zm0 4h2v-2H3v2zm0-8h2V7H3v2zm4 4h14v-2H7v2zm0 4h14v-2H7v2zM7
+7v2h14V7H7z" />
+ <path
+ android:pathData="M0 0h24v24H0z" />
+</vector> \ No newline at end of file
diff --git a/SlicesApp/res/drawable/ic_next.xml b/SlicesApp/res/drawable/ic_next.xml
new file mode 100644
index 0000000..0b61487
--- /dev/null
+++ b/SlicesApp/res/drawable/ic_next.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:fillColor="#000000"
+ android:pathData="M6 18l8.5-6L6 6v12zM16 6v12h2V6h-2z" />
+ <path
+ android:pathData="M0 0h24v24H0z" />
+</vector> \ No newline at end of file
diff --git a/SlicesApp/res/drawable/ic_pause.xml b/SlicesApp/res/drawable/ic_pause.xml
new file mode 100644
index 0000000..a581384
--- /dev/null
+++ b/SlicesApp/res/drawable/ic_pause.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:fillColor="#000000"
+ android:pathData="M6 19h4V5H6v14zm8-14v14h4V5h-4z" />
+ <path
+ android:pathData="M0 0h24v24H0z" />
+</vector> \ No newline at end of file
diff --git a/SlicesApp/res/drawable/ic_photo.xml b/SlicesApp/res/drawable/ic_photo.xml
new file mode 100644
index 0000000..782c38c
--- /dev/null
+++ b/SlicesApp/res/drawable/ic_photo.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:fillColor="#000000"
+ android:pathData="M21 19V5c0-1.1-.9-2-2-2H5c-1.1 0-2 .9-2 2v14c0 1.1 .9 2 2 2h14c1.1 0 2-.9
+2-2zM8.5 13.5l2.5 3.01L14.5 12l4.5 6H5l3.5-4.5z" />
+ <path
+ android:pathData="M0 0h24v24H0z" />
+</vector> \ No newline at end of file
diff --git a/SlicesApp/res/drawable/ic_play.xml b/SlicesApp/res/drawable/ic_play.xml
new file mode 100644
index 0000000..7457bac
--- /dev/null
+++ b/SlicesApp/res/drawable/ic_play.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:fillColor="#000000"
+ android:pathData="M8 5v14l11-7z" />
+ <path
+ android:pathData="M0 0h24v24H0z" />
+</vector> \ No newline at end of file
diff --git a/SlicesApp/res/drawable/ic_prev.xml b/SlicesApp/res/drawable/ic_prev.xml
new file mode 100644
index 0000000..3bcca96
--- /dev/null
+++ b/SlicesApp/res/drawable/ic_prev.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:fillColor="#000000"
+ android:pathData="M6 6h2v12H6zm3.5 6l8.5 6V6z" />
+ <path
+ android:pathData="M0 0h24v24H0z" />
+</vector> \ No newline at end of file
diff --git a/SlicesApp/res/drawable/ic_remove.xml b/SlicesApp/res/drawable/ic_remove.xml
new file mode 100644
index 0000000..76bd217
--- /dev/null
+++ b/SlicesApp/res/drawable/ic_remove.xml
@@ -0,0 +1,27 @@
+<!--
+Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24.0dp"
+ android:height="24.0dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M19.0,13.0L5.0,13.0l0.0,-2.0l14.0,0.0l0.0,2.0z"/>
+ <path
+ android:pathData="M0 0h24v24H0z"
+ android:fillColor="#00000000"/>
+</vector>
diff --git a/SlicesApp/res/drawable/ic_reply.xml b/SlicesApp/res/drawable/ic_reply.xml
new file mode 100644
index 0000000..af5643c
--- /dev/null
+++ b/SlicesApp/res/drawable/ic_reply.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:fillColor="#000000"
+ android:pathData="M10 9V5l-7 7 7 7v-4.1c5 0 8.5 1.6 11 5.1-1-5-4-10-11-11z" />
+ <path
+ android:pathData="M0 0h24v24H0z" />
+</vector> \ No newline at end of file
diff --git a/SlicesApp/res/drawable/ic_share.xml b/SlicesApp/res/drawable/ic_share.xml
new file mode 100644
index 0000000..9942c06
--- /dev/null
+++ b/SlicesApp/res/drawable/ic_share.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:pathData="M0 0h24v24H0z" />
+ <path
+ android:fillColor="#000000"
+ android:pathData="M18 16.08c-.76 0-1.44 .3 -1.96 .77 L8.91 12.7c.05-.23 .09 -.46 .09
+-.7s-.04-.47-.09-.7l7.05-4.11c.54 .5 1.25 .81 2.04 .81 1.66 0 3-1.34
+3-3s-1.34-3-3-3-3 1.34-3 3c0 .24 .04 .47 .09 .7L8.04 9.81C7.5 9.31 6.79 9 6
+9c-1.66 0-3 1.34-3 3s1.34 3 3 3c.79 0 1.5-.31 2.04-.81l7.12 4.16c-.05 .21 -.08
+.43 -.08 .65 0 1.61 1.31 2.92 2.92 2.92 1.61 0 2.92-1.31
+2.92-2.92s-1.31-2.92-2.92-2.92z" />
+</vector> \ No newline at end of file
diff --git a/SlicesApp/res/drawable/ic_slice.xml b/SlicesApp/res/drawable/ic_slice.xml
new file mode 100644
index 0000000..ce54529
--- /dev/null
+++ b/SlicesApp/res/drawable/ic_slice.xml
@@ -0,0 +1,9 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:pathData="M12,2C8.43,2 5.23,3.54 3.01,6L12,22l8.99,-16C18.78,3.55 15.57,2 12,2zM7,7c0,-1.1 0.9,-2 2,-2s2,0.9 2,2 -0.9,2 -2,2 -2,-0.9 -2,-2zM12,15c-1.1,0 -2,-0.9 -2,-2s0.9,-2 2,-2 2,0.9 2,2 -0.9,2 -2,2z"
+ android:fillColor="#000000"/>
+</vector>
diff --git a/SlicesApp/res/drawable/ic_up.xml b/SlicesApp/res/drawable/ic_up.xml
new file mode 100644
index 0000000..dc67c88
--- /dev/null
+++ b/SlicesApp/res/drawable/ic_up.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:fillColor="#000000"
+ android:pathData="M7.41 15.41L12 10.83l4.59 4.58L18 14l-6-6-6 6z" />
+ <path
+ android:pathData="M0 0h24v24H0z" />
+</vector> \ No newline at end of file
diff --git a/SlicesApp/res/drawable/ic_video.xml b/SlicesApp/res/drawable/ic_video.xml
new file mode 100644
index 0000000..b19a75d
--- /dev/null
+++ b/SlicesApp/res/drawable/ic_video.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:pathData="M0 0h24v24H0z" />
+ <path
+ android:fillColor="#000000"
+ android:pathData="M17 10.5V7c0-.55-.45-1-1-1H4c-.55 0-1 .45-1 1v10c0 .55 .45 1 1 1h12c.55 0 1-.45
+1-1v-3.5l4 4v-11l-4 4z" />
+</vector> \ No newline at end of file
diff --git a/SlicesApp/res/drawable/ic_voice.xml b/SlicesApp/res/drawable/ic_voice.xml
new file mode 100644
index 0000000..e6c16f2
--- /dev/null
+++ b/SlicesApp/res/drawable/ic_voice.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:fillColor="#000000"
+ android:pathData="M7 24h2v-2H7v2zm5-11c1.66 0 2.99-1.34 2.99-3L15 4c0-1.66-1.34-3-3-3S9 2.34 9
+4v6c0 1.66 1.34 3 3 3zm-1 11h2v-2h-2v2zm4 0h2v-2h-2v2zm4-14h-1.7c0 3-2.54
+5.1-5.3 5.1S6.7 13 6.7 10H5c0 3.41 2.72 6.23 6 6.72V20h2v-3.28c3.28-.49 6-3.31
+6-6.72z" />
+ <path
+ android:pathData="M0 0h24v24H0z" />
+</vector> \ No newline at end of file
diff --git a/SlicesApp/res/drawable/ic_work.xml b/SlicesApp/res/drawable/ic_work.xml
new file mode 100644
index 0000000..2017fd2
--- /dev/null
+++ b/SlicesApp/res/drawable/ic_work.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:pathData="M0 0h24v24H0z" />
+ <path
+ android:fillColor="#000000"
+ android:pathData="M20 6h-4V4c0-1.11-.89-2-2-2h-4c-1.11 0-2 .89-2 2v2H4c-1.11 0-1.99 .89 -1.99 2L2
+19c0 1.11 .89 2 2 2h16c1.11 0 2-.89 2-2V8c0-1.11-.89-2-2-2zm-6 0h-4V4h4v2z" />
+</vector> \ No newline at end of file
diff --git a/SlicesApp/res/drawable/mady.jpg b/SlicesApp/res/drawable/mady.jpg
new file mode 100644
index 0000000..8b61f1b
--- /dev/null
+++ b/SlicesApp/res/drawable/mady.jpg
Binary files differ
diff --git a/SlicesApp/res/drawable/weather_1.png b/SlicesApp/res/drawable/weather_1.png
new file mode 100644
index 0000000..7c4034e
--- /dev/null
+++ b/SlicesApp/res/drawable/weather_1.png
Binary files differ
diff --git a/SlicesApp/res/drawable/weather_2.png b/SlicesApp/res/drawable/weather_2.png
new file mode 100644
index 0000000..f1b6672
--- /dev/null
+++ b/SlicesApp/res/drawable/weather_2.png
Binary files differ
diff --git a/SlicesApp/res/drawable/weather_3.png b/SlicesApp/res/drawable/weather_3.png
new file mode 100644
index 0000000..a5db683
--- /dev/null
+++ b/SlicesApp/res/drawable/weather_3.png
Binary files differ
diff --git a/SlicesApp/res/drawable/weather_4.png b/SlicesApp/res/drawable/weather_4.png
new file mode 100644
index 0000000..0b7f3b0
--- /dev/null
+++ b/SlicesApp/res/drawable/weather_4.png
Binary files differ
diff --git a/SlicesApp/res/layout/activity_layout.xml b/SlicesApp/res/layout/activity_layout.xml
new file mode 100644
index 0000000..d57f605
--- /dev/null
+++ b/SlicesApp/res/layout/activity_layout.xml
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:gravity="center">
+
+ <FrameLayout
+ android:id="@+id/slice_preview"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"/>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:paddingBottom="16dp"
+ android:gravity="center">
+
+ <Button
+ android:id="@+id/subtract"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="-"/>
+
+ <TextView android:id="@+id/summary"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:padding="48dp"
+ android:textAppearance="?android:attr/textAppearanceLarge" />
+
+ <Button
+ android:id="@+id/add"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="+"/>
+
+ </LinearLayout>
+
+ <Spinner
+ android:id="@+id/spinner"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+ <CheckBox
+ android:id="@+id/header"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Show header" />
+
+ <CheckBox
+ android:id="@+id/sub_header"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Show sub header" />
+
+ <CheckBox
+ android:id="@+id/show_action_row"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Show action row" />
+
+ </LinearLayout>
+</LinearLayout>
+
diff --git a/SlicesApp/res/values/strings.xml b/SlicesApp/res/values/strings.xml
new file mode 100644
index 0000000..ff364c5
--- /dev/null
+++ b/SlicesApp/res/values/strings.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_label">Slices Client</string>
+</resources>
diff --git a/SlicesApp/src/com/android/experimental/slicesapp/SlicesActivity.java b/SlicesApp/src/com/android/experimental/slicesapp/SlicesActivity.java
new file mode 100644
index 0000000..1690f6b
--- /dev/null
+++ b/SlicesApp/src/com/android/experimental/slicesapp/SlicesActivity.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.experimental.slicesapp;
+
+import android.app.Activity;
+import android.app.slice.widget.SliceView;
+import android.content.ContentResolver;
+import android.content.SharedPreferences;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemSelectedListener;
+import android.widget.ArrayAdapter;
+import android.widget.CheckBox;
+import android.widget.Spinner;
+import android.widget.TextView;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class SlicesActivity extends Activity {
+
+ private static final String TAG = "SlicesActivity";
+
+ private boolean SHOW_PREVIEW = false;
+
+ private int mState;
+ private ViewGroup mSlicePreviewFrame;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ SharedPreferences state = getSharedPreferences("slice", 0);
+ mState = 0;
+ if (state != null) {
+ mState = Integer.parseInt(state.getString(getUri().toString(), "0"));
+ }
+ setContentView(R.layout.activity_layout);
+ mSlicePreviewFrame = (ViewGroup) findViewById(R.id.slice_preview);
+ findViewById(R.id.subtract).setOnClickListener(v -> {
+ mState--;
+ state.edit().putString(getUri().toString(), String.valueOf(mState)).commit();
+ updateState();
+ getContentResolver().notifyChange(getUri(), null);
+ });
+ findViewById(R.id.add).setOnClickListener(v -> {
+ mState++;
+ state.edit().putString(getUri().toString(), String.valueOf(mState)).commit();
+ updateState();
+ getContentResolver().notifyChange(getUri(), null);
+ });
+
+ Spinner spinner = findViewById(R.id.spinner);
+ List<String> list = new ArrayList<>();
+ list.add("Default");
+ list.add("Single-line");
+ list.add("Single-line action");
+ list.add("Two-line");
+ list.add("Two-line action");
+ list.add("Grid");
+ list.add("Weather");
+ list.add("Messaging");
+ list.add("Shortcut");
+ list.add("Keep actions");
+ list.add("Maps multi");
+ ArrayAdapter<String> adapter = new ArrayAdapter<>(this,
+ android.R.layout.simple_spinner_item, list);
+ adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+ spinner.setAdapter(adapter);
+ spinner.setSelection(list.indexOf(state.getString("slice_type", "Default")));
+ spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
+ @Override
+ public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
+ state.edit().putString("slice_type", list.get(position)).commit();
+ getContentResolver().notifyChange(getUri(), null);
+ updateSlice(getUri());
+ }
+
+ @Override
+ public void onNothingSelected(AdapterView<?> parent) {
+ }
+ });
+
+ bindCheckbox(R.id.header, state, "show_header");
+ bindCheckbox(R.id.sub_header, state, "show_sub_header");
+ bindCheckbox(R.id.show_action_row, state, "show_action_row");
+
+ updateState();
+ }
+
+ private void bindCheckbox(int id, SharedPreferences state, String key) {
+ CheckBox checkbox = findViewById(id);
+ checkbox.setChecked(state.getBoolean(key, false));
+ checkbox.setOnCheckedChangeListener((v, isChecked) -> {
+ state.edit().putBoolean(key, isChecked).commit();
+ getContentResolver().notifyChange(getUri(), null);
+ updateSlice(getUri());
+ });
+ }
+
+ private void updateState() {
+ ((TextView) findViewById(R.id.summary)).setText(String.valueOf(mState));
+ }
+
+ public Uri getUri() {
+ return new Uri.Builder()
+ .scheme(ContentResolver.SCHEME_CONTENT)
+ .authority(getPackageName())
+ .appendPath("main").build();
+ }
+
+ private void updateSlice(Uri uri) {
+ if (SHOW_PREVIEW) {
+ mSlicePreviewFrame.removeAllViews();
+ SliceView v = new SliceView(this);
+ v.setMode(SliceView.MODE_LARGE);
+ v.setSlice(uri);
+ mSlicePreviewFrame.addView(v);
+ }
+ }
+}
diff --git a/SlicesApp/src/com/android/experimental/slicesapp/SlicesProvider.java b/SlicesApp/src/com/android/experimental/slicesapp/SlicesProvider.java
new file mode 100644
index 0000000..32a6704
--- /dev/null
+++ b/SlicesApp/src/com/android/experimental/slicesapp/SlicesProvider.java
@@ -0,0 +1,313 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.experimental.slicesapp;
+
+import android.app.PendingIntent;
+import android.app.RemoteInput;
+import android.app.slice.Slice;
+import android.app.slice.Slice.Builder;
+import android.app.slice.SliceProvider;
+import android.content.ContentResolver;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.graphics.Color;
+import android.graphics.drawable.Icon;
+import android.net.Uri;
+import android.text.format.DateUtils;
+import android.util.Log;
+
+import java.util.function.Consumer;
+
+
+public class SlicesProvider extends SliceProvider {
+
+ private static final String TAG = "SliceProvider";
+ private static final String INTENT_ACTION = "android.intent.action.EXAMPLE_ACTION";
+
+ private final int NUM_LIST_ITEMS = 10;
+
+ private SharedPreferences mSharedPrefs;
+
+ @Override
+ public boolean onCreate() {
+ mSharedPrefs = getContext().getSharedPreferences("slice", 0);
+ return true;
+ }
+
+ private Uri getIntentUri() {
+ return new Uri.Builder()
+ .scheme(ContentResolver.SCHEME_CONTENT)
+ .authority(getContext().getPackageName())
+ .appendPath("main").appendPath("intent")
+ .build();
+ }
+
+ //@Override
+ public Uri onMapIntentToUri(Intent intent) {
+ if (intent.getAction().equals(INTENT_ACTION)) {
+ return getIntentUri();
+ }
+ return null;//super.onMapIntentToUri(intent);
+ }
+
+ /**
+ * Overriding onBindSlice will generate one Slice for all modes.
+ * @param sliceUri
+ */
+ @Override
+ public Slice onBindSlice(Uri sliceUri) {
+ Log.w(TAG, "onBindSlice uri: " + sliceUri);
+ String type = mSharedPrefs.getString("slice_type", "Default");
+ if ("Default".equals(type)) {
+ return null;
+ }
+ Slice.Builder b = new Builder(sliceUri);
+ if (mSharedPrefs.getBoolean("show_header", false)) {
+ b.addText("Header", Slice.HINT_TITLE);
+ if (mSharedPrefs.getBoolean("show_sub_header", false)) {
+ b.addText("Sub-header");
+ }
+ }
+ if (sliceUri.equals(getIntentUri())) {
+ type = "Intent";
+ }
+ switch (type) {
+ case "Shortcut":
+ b.addColor(Color.CYAN).addIcon(
+ Icon.createWithResource(getContext(), R.drawable.mady),
+ Slice.HINT_LARGE);
+ break;
+ case "Single-line":
+ b.addSubSlice(makeList(new Slice.Builder(b), this::makeSingleLine,
+ this::addIcon));
+ addColorIcon(b);
+ break;
+ case "Single-line action":
+ b.addSubSlice(makeList(new Slice.Builder(b), this::makeSingleLine,
+ this::addAltActions));
+ addColorIcon(b);
+ break;
+ case "Two-line":
+ b.addSubSlice(makeList(new Slice.Builder(b), this::makeTwoLine,
+ this::addIcon));
+ addColorIcon(b);
+ break;
+ case "Two-line action":
+ b.addSubSlice(makeList(new Slice.Builder(b), this::makeTwoLine,
+ this::addAltActions));
+ addColorIcon(b);
+ break;
+ case "Grid":
+ case "Weather":
+ b.addSubSlice(createWeather(new Slice.Builder(b)));
+ break;
+ case "Messaging":
+ b.addSubSlice(createConversation(new Slice.Builder(b)));
+ break;
+ case "Keep actions":
+ b.addSubSlice(createKeepNote(new Slice.Builder(b)));
+ break;
+ case "Maps multi":
+ b.addSubSlice(createMapsMulti(new Slice.Builder(b)));
+ break;
+ case "Intent":
+ b.addSubSlice(createIntentSlice(new Slice.Builder(b)));
+ break;
+ }
+ if (mSharedPrefs.getBoolean("show_action_row", false)) {
+ Intent intent = new Intent(getContext(), SlicesActivity.class);
+ PendingIntent pendingIntent = PendingIntent.getActivity(getContext(), 0, intent, 0);
+ b.addSubSlice(new Slice.Builder(b).addHints(Slice.HINT_ACTIONS)
+ .addAction(pendingIntent, new Slice.Builder(b)
+ .addText("Action1")
+ .addIcon(Icon.createWithResource(getContext(), R.drawable.ic_add))
+ .build())
+ .addAction(pendingIntent, new Slice.Builder(b)
+ .addText("Action2")
+ .addIcon(Icon.createWithResource(getContext(), R.drawable.ic_remove))
+ .build())
+ .addAction(pendingIntent, new Slice.Builder(b)
+ .addText("Action3")
+ .addIcon(Icon.createWithResource(getContext(), R.drawable.ic_add))
+ .build())
+ .build());
+ }
+ return b.build();
+ }
+
+ private Slice createWeather(Builder grid) {
+ grid.addHints(Slice.HINT_HORIZONTAL);
+ grid.addSubSlice(new Slice.Builder(grid)
+ .addIcon(Icon.createWithResource(getContext(), R.drawable.weather_1))
+ .addText("MON")
+ .addText("69\u00B0", Slice.HINT_LARGE).build());
+ grid.addSubSlice(new Slice.Builder(grid)
+ .addIcon(Icon.createWithResource(getContext(), R.drawable.weather_2))
+ .addText("TUE")
+ .addText("71\u00B0", Slice.HINT_LARGE).build());
+ grid.addSubSlice(new Slice.Builder(grid)
+ .addIcon(Icon.createWithResource(getContext(), R.drawable.weather_3))
+ .addText("WED")
+ .addText("76\u00B0", Slice.HINT_LARGE).build());
+ grid.addSubSlice(new Slice.Builder(grid)
+ .addIcon(Icon.createWithResource(getContext(), R.drawable.weather_4))
+ .addText("THU")
+ .addText("69\u00B0", Slice.HINT_LARGE).build());
+ grid.addSubSlice(new Slice.Builder(grid)
+ .addIcon(Icon.createWithResource(getContext(), R.drawable.weather_2))
+ .addText("FRI")
+ .addText("71\u00B0", Slice.HINT_LARGE).build());
+ return grid.build();
+ }
+
+ private Slice createConversation(Builder b2) {
+ b2.addHints(Slice.HINT_LIST);
+ b2.addSubSlice(new Slice.Builder(b2)
+ .addHints(Slice.HINT_MESSAGE)
+ .addText("yo home \uD83C\uDF55, I emailed you the info")
+ .addTimestamp(System.currentTimeMillis() - 20 * DateUtils.MINUTE_IN_MILLIS)
+ .addIcon(Icon.createWithResource(getContext(), R.drawable.mady), Slice.HINT_SOURCE)
+ .build());
+ b2.addSubSlice(new Builder(b2)
+ .addHints(Slice.HINT_MESSAGE)
+ .addText("just bought my tickets")
+ .addTimestamp(System.currentTimeMillis() - 10 * DateUtils.MINUTE_IN_MILLIS)
+ .build());
+ b2.addSubSlice(new Builder(b2)
+ .addHints(Slice.HINT_MESSAGE)
+ .addText("yay! can't wait for getContext() weekend!\n"
+ + "\uD83D\uDE00")
+ .addTimestamp(System.currentTimeMillis() - 5 * DateUtils.MINUTE_IN_MILLIS)
+ .addIcon(Icon.createWithResource(getContext(), R.drawable.mady), Slice.HINT_SOURCE)
+ .build());
+ RemoteInput ri = new RemoteInput.Builder("someKey").setLabel("someLabel")
+ .setAllowFreeFormInput(true).build();
+ b2.addRemoteInput(ri);
+ return b2.build();
+ }
+
+ private Slice addIcon(Builder b) {
+ b.addIcon(Icon.createWithResource(getContext(), R.drawable.ic_add));
+ return b.build();
+ }
+
+ private void addAltActions(Builder builder) {
+ Intent intent = new Intent(getContext(), SlicesActivity.class);
+ PendingIntent pendingIntent = PendingIntent.getActivity(getContext(), 0, intent, 0);
+ builder.addSubSlice(new Slice.Builder(builder).addHints(Slice.HINT_ACTIONS)
+ .addAction(pendingIntent, new Slice.Builder(builder)
+ .addText("Alt1")
+ .addIcon(Icon.createWithResource(getContext(), R.drawable.ic_add)).build())
+ .addAction(pendingIntent, new Slice.Builder(builder)
+ .addText("Alt2")
+ .addIcon(Icon.createWithResource(getContext(), R.drawable.ic_remove))
+ .build())
+ .build());
+ }
+
+ private void makeSingleLine(Builder b) {
+ b.addText("Single-line list item text", Slice.HINT_TITLE);
+ }
+
+ private void makeTwoLine(Builder b) {
+ b.addText("Two-line list item text", Slice.HINT_TITLE);
+ b.addText("Secondary text");
+ }
+
+ private void addColorIcon(Builder b) {
+ b.addColor(0xFFFF5722);
+ b.addIcon(Icon.createWithResource(getContext(), R.drawable.ic_slice));
+ }
+
+ private Slice makeList(Builder list, Consumer<Builder> lineCreator,
+ Consumer<Builder> lineHandler) {
+ list.addHints(Slice.HINT_LIST);
+ for (int i = 0; i < NUM_LIST_ITEMS; i++) {
+ Builder b = new Builder(list);
+ lineCreator.accept(b);
+ lineHandler.accept(b);
+ list.addSubSlice(b.build());
+ }
+ return list.build();
+ }
+
+ private Slice createKeepNote(Builder b) {
+ Intent intent = new Intent(getContext(), SlicesActivity.class);
+ PendingIntent pi = PendingIntent.getActivity(getContext(), 0, intent, 0);
+ RemoteInput ri = new RemoteInput.Builder("someKey").setLabel("someLabel")
+ .setAllowFreeFormInput(true).build();
+ return b.addText("Create new note", Slice.HINT_TITLE).addText("with keep")
+ .addColor(0xffffc107)
+ .addAction(pi, new Slice.Builder(b)
+ .addText("List")
+ .addIcon(Icon.createWithResource(getContext(), R.drawable.ic_list))
+ .build())
+ .addAction(pi, new Slice.Builder(b)
+ .addText("Voice note")
+ .addIcon(Icon.createWithResource(getContext(), R.drawable.ic_voice))
+ .build())
+ .addAction(pi, new Slice.Builder(b)
+ .addText("Camera")
+ .addIcon(Icon.createWithResource(getContext(), R.drawable.ic_camera))
+ .build())
+ .addIcon(Icon.createWithResource(getContext(), R.drawable.ic_create))
+ .addRemoteInput(ri)
+ .build();
+ }
+
+ private Slice createMapsMulti(Builder b) {
+ Intent intent = new Intent(getContext(), SlicesActivity.class);
+ PendingIntent pi = PendingIntent.getActivity(getContext(), 0, intent, 0);
+
+ b.addHints(Slice.HINT_HORIZONTAL, Slice.HINT_LIST).addColor(0xff0B8043);
+ b.addSubSlice(new Slice.Builder(b)
+ .addAction(pi, new Slice.Builder(b)
+ .addIcon(Icon.createWithResource(getContext(), R.drawable.ic_home)).build())
+ .addText("Home", Slice.HINT_LARGE)
+ .addText("25 min").build());
+ b.addSubSlice(new Slice.Builder(b)
+ .addAction(pi, new Slice.Builder(b)
+ .addIcon(Icon.createWithResource(getContext(), R.drawable.ic_work)).build())
+ .addText("Work", Slice.HINT_LARGE)
+ .addText("1 hour 23 min").build());
+ b.addSubSlice(new Slice.Builder(b)
+ .addAction(pi, new Slice.Builder(b)
+ .addIcon(Icon.createWithResource(getContext(), R.drawable.ic_home)).build())
+ .addText("Mom's", Slice.HINT_LARGE)
+ .addText("37 min").build());
+ return b.build();
+ }
+
+ private Slice createIntentSlice(Builder b) {
+ Intent intent = new Intent(getContext(), SlicesActivity.class);
+
+ PendingIntent pi = PendingIntent.getActivity(getContext(), 0, intent, 0);
+
+ b.addHints(Slice.HINT_HORIZONTAL, Slice.HINT_LIST).addColor(0xff0B8043);
+ b.addSubSlice(new Slice.Builder(b)
+ .addAction(pi, new Slice.Builder(b)
+ .addIcon(Icon.createWithResource(getContext(), R.drawable.ic_next)).build())
+ .addText("Next", Slice.HINT_LARGE).build());
+ b.addSubSlice(new Slice.Builder(b)
+ .addAction(pi, new Slice.Builder(b)
+ .addIcon(Icon.createWithResource(getContext(), R.drawable.ic_play)).build())
+ .addText("Play", Slice.HINT_LARGE).build());
+ b.addSubSlice(new Slice.Builder(b)
+ .addAction(pi, new Slice.Builder(b)
+ .addIcon(Icon.createWithResource(getContext(), R.drawable.ic_prev)).build())
+ .addText("Previous", Slice.HINT_LARGE).build());
+ return b.build();
+ }
+}