diff options
author | Jason Monk <jmonk@google.com> | 2017-09-26 15:00:52 -0400 |
---|---|---|
committer | Jason Monk <jmonk@google.com> | 2017-10-30 11:12:22 -0400 |
commit | 4aa13147dc5a0b12e15b8bc91a44bedc8f4ee121 (patch) | |
tree | cd893f4a69b91aa6e2392988f175a6b059a8ea80 | |
parent | 4cb0d34ba8edb5affdd0bcf76905571b8624c68c (diff) | |
download | experimental-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
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 Binary files differnew file mode 100644 index 0000000..8b61f1b --- /dev/null +++ b/SlicesApp/res/drawable/mady.jpg diff --git a/SlicesApp/res/drawable/weather_1.png b/SlicesApp/res/drawable/weather_1.png Binary files differnew file mode 100644 index 0000000..7c4034e --- /dev/null +++ b/SlicesApp/res/drawable/weather_1.png diff --git a/SlicesApp/res/drawable/weather_2.png b/SlicesApp/res/drawable/weather_2.png Binary files differnew file mode 100644 index 0000000..f1b6672 --- /dev/null +++ b/SlicesApp/res/drawable/weather_2.png diff --git a/SlicesApp/res/drawable/weather_3.png b/SlicesApp/res/drawable/weather_3.png Binary files differnew file mode 100644 index 0000000..a5db683 --- /dev/null +++ b/SlicesApp/res/drawable/weather_3.png diff --git a/SlicesApp/res/drawable/weather_4.png b/SlicesApp/res/drawable/weather_4.png Binary files differnew file mode 100644 index 0000000..0b7f3b0 --- /dev/null +++ b/SlicesApp/res/drawable/weather_4.png 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(); + } +} |