Merge "Remove ShortcutManager samples from nyc-dev" into nyc-dev

This commit is contained in:
Makoto Onuki
2016-05-12 16:32:55 +00:00
committed by Android (Google) Code Review
25 changed files with 0 additions and 1368 deletions

View File

@@ -1,17 +0,0 @@
# Copyright (C) 2016 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 $(call all-makefiles-under, $(LOCAL_PATH))

View File

@@ -1,67 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2016 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="wrap_content"
android:orientation="horizontal"
>
<ImageView
android:id="@+id/image"
android:layout_width="48dip"
android:layout_height="48dip"
android:layout_marginBottom="8dip"
/>
<LinearLayout
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_gravity="center_vertical"
android:orientation="vertical"
android:paddingLeft="8dip"
>
<TextView
android:id="@+id/line1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#000000"
android:textSize="16sp"
/>
<TextView
android:id="@+id/line2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#444444"
/>
</LinearLayout>
<Button
android:id="@+id/action2"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center"
android:gravity="center"
android:visibility="gone"
style="@android:style/Widget.Material.Button.Borderless"/>
<Button
android:id="@+id/launch"
android:text="@string/launch"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center"
android:gravity="center"
android:visibility="gone"
style="@android:style/Widget.Material.Button.Borderless"/>
</LinearLayout>

View File

@@ -1,20 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2016 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">
<add-resource type="string" name="launch"/>
<string name="launch">Launch</string>
</resources>

View File

@@ -1,47 +0,0 @@
/*
* Copyright (C) 2016 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.example.android.pm.shortcutdemo;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.util.ArrayMap;
public class AppLabelCache {
private final Context mContext;
private ArrayMap<String, String> mAppNames = new ArrayMap<>();
public AppLabelCache(Context context) {
mContext = context;
}
public String getAppLabel(String packageName) {
String name = mAppNames.get(packageName);
if (name != null) {
return name;
}
PackageManager pm = mContext.getPackageManager();
try {
final ApplicationInfo ai = pm.getApplicationInfo(packageName, 0);
name = pm.getApplicationLabel(ai).toString();
} catch (NameNotFoundException e) {
return packageName;
}
mAppNames.put(packageName, name);
return name;
}
}

View File

@@ -1,215 +0,0 @@
/*
* Copyright (C) 2016 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.example.android.pm.shortcutdemo;
import android.content.Context;
import android.content.pm.LauncherApps;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ShortcutInfo;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.ParcelFileDescriptor;
import android.os.Process;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import java.io.IOException;
import java.util.List;
public abstract class ShortcutAdapter extends BaseAdapter implements OnClickListener {
public static final String TAG = "ShortcutDemo";
private final Context mContext;
private final LayoutInflater mInflater;
private LauncherApps mLauncherApps;
private final AppLabelCache mAppLabelCache;
private List<ShortcutInfo> mShortcuts;
public ShortcutAdapter(Context context) {
mContext = context;
mAppLabelCache = new AppLabelCache(mContext);
mInflater = mContext.getSystemService(LayoutInflater.class);
mLauncherApps = mContext.getSystemService(LauncherApps.class);
}
protected abstract int getLayoutId();
protected abstract int getText1Id();
protected abstract int getText2Id();
protected abstract int getImageId();
protected abstract int getLaunchId();
protected abstract int getAction2Id();
protected boolean showLaunch(ShortcutInfo si) {
return false;
}
protected boolean showAction2(ShortcutInfo si) {
return false;
}
protected String getAction2Text(ShortcutInfo si) {
return "Action2";
}
protected void onLaunchClicked(ShortcutInfo si) {
}
protected void onAction2Clicked(ShortcutInfo si) {
}
public void setShortcuts(List<ShortcutInfo> shortcuts) {
mShortcuts = shortcuts;
notifyDataSetChanged();
}
public List<ShortcutInfo> getShortcuts() {
return mShortcuts;
}
@Override
public int getCount() {
return mShortcuts == null ? 0 : mShortcuts.size();
}
@Override
public Object getItem(int position) {
return mShortcuts.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public boolean hasStableIds() {
return false;
}
@Override
public boolean areAllItemsEnabled() {
return true;
}
@Override
public boolean isEnabled(int position) {
return true;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final View view;
if (convertView != null) {
view = convertView;
} else {
view = mInflater.inflate(getLayoutId(), null);
}
bindView(view, position, mShortcuts.get(position));
return view;
}
public void bindView(View view, int position, ShortcutInfo si) {
{
final View v = view.findViewById(getLaunchId());
v.setVisibility(View.GONE);
if (showLaunch(si)) {
v.setOnClickListener(this);
v.setVisibility(View.VISIBLE);
}
}
{
final Button v = (Button) view.findViewById(getAction2Id());
v.setVisibility(View.GONE);
if (showAction2(si)) {
v.setOnClickListener(this);
v.setVisibility(View.VISIBLE);
v.setText(getAction2Text(si));
}
}
final TextView line1 = (TextView) view.findViewById(getText1Id());
final TextView line2 = (TextView) view.findViewById(getText2Id());
view.setTag(si);
line1.setText(si.getTitle());
line2.setText(
si.getId() + (si.isDynamic() ? " [dynamic]" : "")
+ (si.isPinned() ? " [pinned]" : "") + "\n"
+ mAppLabelCache.getAppLabel(si.getPackageName()));
// view.setBackgroundColor(si.isPinned() ? Color.rgb(255, 255, 192) : Color.WHITE);
// TODO Do it on worker thread
final ImageView image = (ImageView) view.findViewById(getImageId());
if (!mLauncherApps.hasShortcutHostPermission()) {
image.setVisibility(View.GONE);
} else {
image.setVisibility(View.VISIBLE);
Bitmap icon = null;
if (si.hasIconResource()) {
try {
final Resources res = mContext.getPackageManager().getResourcesForApplication(
si.getPackageName());
icon = BitmapFactory.decodeResource(res, si.getIconResourceId());
} catch (NameNotFoundException e) {
Log.w(TAG, "Unable to load icon from " + si.getPackageName(), e);
}
} else if (si.hasIconFile()) {
icon = pfdToBitmap(mLauncherApps.getShortcutIconFd(si));
}
image.setImageBitmap(icon);
}
}
private Bitmap pfdToBitmap(ParcelFileDescriptor pfd) {
if (pfd == null) {
return null;
}
try {
final Bitmap bmp = BitmapFactory.decodeFileDescriptor(pfd.getFileDescriptor());
if (bmp == null) {
Log.w(TAG, "Failed to decode icon");
}
return bmp;
} finally {
try {
pfd.close();
} catch (IOException e) {
}
}
}
@Override
public void onClick(View v) {
final ShortcutInfo si = (ShortcutInfo)(((View) v.getParent()).getTag());
if (v.getId() == getLaunchId()) {
onLaunchClicked(si);
} else if (v.getId() == getAction2Id()) {
onAction2Clicked(si);
}
}
}

View File

@@ -1,59 +0,0 @@
#
# Copyright (C) 2016 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.
#
# We build two apps from the same source
LOCAL_PATH:= $(call my-dir)
# === App 1 ===
include $(CLEAR_VARS)
LOCAL_PACKAGE_NAME := ShortcutLauncherDemo
LOCAL_MODULE_TAGS := samples tests
LOCAL_AAPT_FLAGS += --rename-manifest-package com.example.android.pm.shortcutlauncherdemo
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_SRC_FILES += $(call all-java-files-under, ../common/src)
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
LOCAL_RESOURCE_DIR += $(LOCAL_PATH)/../common/res
LOCAL_RESOURCE_DIR += $(LOCAL_PATH)/res1
LOCAL_SDK_VERSION := current
include $(BUILD_PACKAGE)
# === App 2 ===
include $(CLEAR_VARS)
LOCAL_PACKAGE_NAME := ShortcutLauncherDemo2
LOCAL_MODULE_TAGS := samples tests
LOCAL_AAPT_FLAGS += --rename-manifest-package com.example.android.pm.shortcutlauncherdemo2
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_SRC_FILES += $(call all-java-files-under, ../common/src)
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
LOCAL_RESOURCE_DIR += $(LOCAL_PATH)/../common/res
LOCAL_RESOURCE_DIR += $(LOCAL_PATH)/res2
LOCAL_SDK_VERSION := current
include $(BUILD_PACKAGE)

View File

@@ -1,33 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2016 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.example.android.pm.shortcutlauncherdemo">
<uses-sdk android:minSdkVersion="24" />
<application android:label="@string/app_title"
android:resizeableActivity="true">
<activity android:name="ShortcutLauncher">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.HOME" />
</intent-filter>
</activity>
</application>
</manifest>

View File

@@ -1,29 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2016 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:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ListView
android:id="@android:id/list"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1"
android:enabled="true"
/>
</LinearLayout>

View File

@@ -1,18 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2016 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">
</resources>

View File

@@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2016 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_title">[L1] Shortcuts Launcher Demo</string>
</resources>

View File

@@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2016 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_title">[L2] Shortcuts Launcher Demo</string>
</resources>

View File

@@ -1,241 +0,0 @@
/*
* Copyright (C) 2016 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.example.android.pm.shortcutlauncherdemo;
import android.app.ListActivity;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.LauncherApps;
import android.content.pm.LauncherApps.ShortcutQuery;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ShortcutInfo;
import android.os.Bundle;
import android.os.Process;
import android.os.UserHandle;
import android.util.ArrayMap;
import android.util.Log;
import android.widget.Toast;
import com.example.android.pm.shortcutdemo.ShortcutAdapter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class ShortcutLauncher extends ListActivity {
public static final String TAG = "ShortcutLauncherDemo";
private LauncherApps mLauncherApps;
private MyAdapter mAdapter;
private ArrayMap<String, String> mAppNames = new ArrayMap<>();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mLauncherApps = getSystemService(LauncherApps.class);
mLauncherApps.registerCallback(mLauncherCallback);
if (mLauncherApps.hasShortcutHostPermission()) {
mAdapter = new MyAdapter(this);
setListAdapter(mAdapter);
} else {
showToast("Please make this app as the default launcher.");
finish();
}
}
private void showToast(String message) {
Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
}
@Override
protected void onResume() {
super.onResume();
refreshList();
}
@Override
protected void onDestroy() {
mLauncherApps.unregisterCallback(mLauncherCallback);
super.onDestroy();
}
private void togglePin(ShortcutInfo selected) {
final String packageName = selected.getPackageName();
final List<String> pinned = new ArrayList<>();
for (ShortcutInfo si : mAdapter.getShortcuts()) {
if (si.isPinned() && si.getPackageName().equals(packageName)) {
pinned.add(si.getId());
}
}
if (selected.isPinned()) {
pinned.remove(selected.getId());
} else {
pinned.add(selected.getId());
}
mLauncherApps.pinShortcuts(packageName, pinned, Process.myUserHandle());
}
private void launch(ShortcutInfo si) {
mLauncherApps.startShortcut(si.getPackageName(), si.getId(), null, null,
Process.myUserHandle());
}
private String getAppLabel(String packageName) {
String name = mAppNames.get(packageName);
if (name != null) {
return name;
}
PackageManager pm = getPackageManager();
try {
final ApplicationInfo ai = pm.getApplicationInfo(packageName, 0);
return pm.getApplicationLabel(ai).toString();
} catch (NameNotFoundException e) {
return packageName;
}
}
private void refreshList() {
final ShortcutQuery q = new ShortcutQuery();
q.setQueryFlags(ShortcutQuery.FLAG_GET_DYNAMIC | ShortcutQuery.FLAG_GET_PINNED);
final List<ShortcutInfo> list = mLauncherApps.getShortcuts(q, Process.myUserHandle());
Collections.sort(list, mShortcutComparator);
Log.i(TAG, "All shortcuts:");
for (ShortcutInfo si : list) {
Log.i(TAG, si.toString());
}
mAdapter.setShortcuts(list);
}
private final Comparator<ShortcutInfo> mShortcutComparator =
(ShortcutInfo s1, ShortcutInfo s2) -> {
int ret = 0;
ret = getAppLabel(s1.getPackageName()).compareTo(getAppLabel(s2.getPackageName()));
if (ret != 0) return ret;
ret = s1.getId().compareTo(s2.getId());
if (ret != 0) return ret;
return 0;
};
private final LauncherApps.Callback mLauncherCallback = new LauncherApps.Callback() {
@Override
public void onPackageRemoved(String packageName, UserHandle user) {
}
@Override
public void onPackageAdded(String packageName, UserHandle user) {
}
@Override
public void onPackageChanged(String packageName, UserHandle user) {
}
@Override
public void onPackagesAvailable(String[] packageNames, UserHandle user, boolean replacing) {
}
@Override
public void onPackagesUnavailable(String[] packageNames, UserHandle user,
boolean replacing) {
}
@Override
public void onShortcutsChanged(String packageName,
List<ShortcutInfo> shortcuts, UserHandle user) {
Log.w(TAG, "onShortcutsChanged: user=" + user + " package=" + packageName);
for (ShortcutInfo si : shortcuts) {
Log.i(TAG, si.toString());
}
refreshList();
}
};
class MyAdapter extends ShortcutAdapter {
public MyAdapter(Context context) {
super(context);
}
@Override
protected int getLayoutId() {
return R.layout.list_item;
}
@Override
protected int getText1Id() {
return R.id.line1;
}
@Override
protected int getText2Id() {
return R.id.line2;
}
@Override
protected int getImageId() {
return R.id.image;
}
@Override
protected int getLaunchId() {
return R.id.launch;
}
@Override
protected int getAction2Id() {
return R.id.action2;
}
@Override
protected boolean showLaunch(ShortcutInfo si) {
return true;
}
@Override
protected boolean showAction2(ShortcutInfo si) {
return true;
}
@Override
protected String getAction2Text(ShortcutInfo si) {
return si.isPinned() ? "Unpin" : "Pin";
}
@Override
protected void onLaunchClicked(ShortcutInfo si) {
launch(si);
}
@Override
protected void onAction2Clicked(ShortcutInfo si) {
togglePin(si);
}
}
}

View File

@@ -1,59 +0,0 @@
#
# Copyright (C) 2016 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.
#
# We build two apps from the same source
LOCAL_PATH:= $(call my-dir)
# === App 1 ===
include $(CLEAR_VARS)
LOCAL_PACKAGE_NAME := ShortcutDemo
LOCAL_MODULE_TAGS := samples tests
LOCAL_AAPT_FLAGS += --rename-manifest-package com.example.android.pm.shortcutdemo
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_SRC_FILES += $(call all-java-files-under, ../common/src)
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
LOCAL_RESOURCE_DIR += $(LOCAL_PATH)/../common/res
LOCAL_RESOURCE_DIR += $(LOCAL_PATH)/res1
LOCAL_SDK_VERSION := current
include $(BUILD_PACKAGE)
# === App 2 ===
include $(CLEAR_VARS)
LOCAL_PACKAGE_NAME := ShortcutDemo2
LOCAL_MODULE_TAGS := samples tests
LOCAL_AAPT_FLAGS += --rename-manifest-package com.example.android.pm.shortcutdemo2
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_SRC_FILES += $(call all-java-files-under, ../common/src)
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
LOCAL_RESOURCE_DIR += $(LOCAL_PATH)/../common/res
LOCAL_RESOURCE_DIR += $(LOCAL_PATH)/res2
LOCAL_SDK_VERSION := current
include $(BUILD_PACKAGE)

View File

@@ -1,40 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2016 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.example.android.pm.shortcutdemo">
<uses-sdk android:minSdkVersion="24" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application android:label="@string/app_title"
android:resizeableActivity="true">
<activity android:name="ShortcutPublisher">
<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>
<service android:name="ShortcutPublishingService">
<intent-filter>
<action android:name="com.example.android.pm.shortcutdemo.ADD" />
</intent-filter>
</service>
</application>
</manifest>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 131 KiB

View File

@@ -1,53 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2016 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:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<Button
android:id="@+id/publish"
android:text="@string/publish"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:onClick="onPublishPressed"/>
<Button
android:id="@+id/add_shortcut"
android:text="@string/add_shortcut"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:onClick="onAddPressed"/>
<Button
android:id="@+id/update_shortcuts"
android:text="@string/update_shortcuts"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:onClick="onUpdatePressed"/>
<Button
android:id="@+id/delete_all"
android:text="@string/delete_all"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:onClick="onDeleteAllPressed"/>
<ListView
android:id="@android:id/list"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1"
android:enabled="true"
/>
</LinearLayout>

View File

@@ -1,29 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2016 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">
<add-resource type="string" name="publish"/>
<string name="publish">Publish shortcuts</string>
<add-resource type="string" name="add_shortcut"/>
<string name="add_shortcut">Add shortcut</string>
<add-resource type="string" name="update_shortcuts"/>
<string name="update_shortcuts">Update shortcuts</string>
<add-resource type="string" name="delete_all"/>
<string name="delete_all">Delete all dynamic shortcuts</string>
</resources>

View File

@@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2016 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_title">[P1] Shortcuts Demo</string>
</resources>

View File

@@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2016 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_title">[P2] Shortcuts Demo</string>
</resources>

View File

@@ -1,308 +0,0 @@
/*
* Copyright (C) 2016 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.example.android.pm.shortcutdemo;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ShortcutInfo;
import android.content.pm.ShortcutManager;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Icon;
import android.net.Uri;
import android.os.Bundle;
import android.text.format.Time;
import android.util.ArrayMap;
import android.util.Log;
import android.util.Pair;
import android.view.View;
import android.widget.ListView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.function.BooleanSupplier;
public class ShortcutPublisher extends Activity {
public static final String TAG = "ShortcutDemo";
private static final String SETUP_SHORTCUT_ID = "setup";
private ShortcutManager mShortcutManager;
private ListView mList;
private MyAdapter mAdapter;
private static final Random sRandom = new Random();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mShortcutManager = getSystemService(ShortcutManager.class);
mList = (ListView) findViewById(android.R.id.list);
mAdapter = new MyAdapter(this);
mList.setAdapter(mAdapter);
Log.d(TAG, "extras=" + getIntent().getExtras());
}
@Override
protected void onResume() {
super.onResume();
refreshList();
}
@Override
protected void onDestroy() {
super.onDestroy();
}
private List<ShortcutInfo> getAllShortcuts() {
final Map<String, ShortcutInfo> map = new ArrayMap<>();
for (ShortcutInfo si : mShortcutManager.getDynamicShortcuts()) {
if (!map.containsKey(si.getId())) {
map.put(si.getId(), si);
}
}
for (ShortcutInfo si : mShortcutManager.getPinnedShortcuts()) {
if (!map.containsKey(si.getId())) {
map.put(si.getId(), si);
}
}
return new ArrayList<>(map.values());
}
private void refreshList() {
final List<ShortcutInfo> list = getAllShortcuts();
Collections.sort(list, mShortcutComparator);
mAdapter.setShortcuts(list);
}
private final Comparator<ShortcutInfo> mShortcutComparator =
(ShortcutInfo s1, ShortcutInfo s2) -> {
int ret = 0;
ret = (s1.isDynamic() ? 0 : 1) - (s2.isDynamic() ? 0 : 1);
if (ret != 0) return ret;
ret = s1.getId().compareTo(s2.getId());
if (ret != 0) return ret;
return 0;
};
private void dumpCurrentShortcuts() {
Log.d(TAG, "Dynamic shortcuts:");
for (ShortcutInfo si : mShortcutManager.getDynamicShortcuts()) {
Log.d(TAG, " " + si.toString());
}
Log.d(TAG, "Pinned shortcuts:");
for (ShortcutInfo si : mShortcutManager.getPinnedShortcuts()) {
Log.d(TAG, " " + si.toString());
}
}
private static void showToast(Context context, String message) {
Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
}
private static void showThrottledToast(Context context) {
showToast(context,
"Throttled, use \"adb shell cmd shortcut reset-throttling\" to reset counters");
}
public static void callApi(Context context, BooleanSupplier call) {
try {
if (!call.getAsBoolean()) {
showThrottledToast(context);
}
} catch (RuntimeException r) {
Log.w(TAG, r.getMessage(), r);
showToast(context, r.getMessage());
}
}
private static List<Pair<String, String>> sIntentList = Arrays.asList(
Pair.create("Google Search", "http://www.google.com"),
Pair.create("Google Mail", "http://mail.google.com"),
Pair.create("Google Maps", "http://maps.google.com"),
Pair.create("Google Drive", "http://drive.google.com"),
Pair.create("Google Photos", "http://photos.google.com"),
Pair.create("Google Hangouts", "http://hangouts.google.com"),
Pair.create("Google+", "http://plus.google.com")
);
public static ShortcutInfo.Builder addRandomIntents(Context context, ShortcutInfo.Builder b) {
final int i = sRandom.nextInt(sIntentList.size());
b.setTitle(sIntentList.get(i).first);
b.setIntent(new Intent(Intent.ACTION_VIEW, Uri.parse(sIntentList.get(i).second)));
b.setIcon(Icon.createWithResource(context, R.drawable.icon2));
return b;
}
public void onPublishPressed(View view) {
dumpCurrentShortcuts();
final Icon icon2 = Icon.createWithBitmap(BitmapFactory.decodeResource(getResources(),
R.drawable.icon_large_2));
final Icon icon3 = Icon.createWithResource(this, R.drawable.icon_large_3);
final Intent intent2 = new Intent(Intent.ACTION_VIEW);
intent2.setClass(this, ShortcutPublisher.class);
final Intent intent3 = new Intent(Intent.ACTION_VIEW);
intent3.setClass(this, ShortcutPublisher.class);
intent3.putExtra("str", "str-value");
intent3.putExtra("nest", new Bundle());
intent3.getBundleExtra("nest").putInt("int", 123);
final ShortcutInfo si1 = addRandomIntents(this, new ShortcutInfo.Builder(this)
.setId("shortcut1")
.setWeight(10)).build();
final ShortcutInfo si2 = new ShortcutInfo.Builder(this)
.setId(SETUP_SHORTCUT_ID)
.setTitle("Shortcut Demo Main")
.setIcon(icon2)
.setWeight(5)
.setIntent(intent2)
.build();
final ShortcutInfo si3 = new ShortcutInfo.Builder(this)
.setId("shortcut3")
.setTitle("Shortcut Demo Main with extras")
.setIcon(icon3)
.setWeight(15)
.setIntent(intent3)
.build();
callApi(this, () -> mShortcutManager.setDynamicShortcuts(Arrays.asList(si1, si2, si3)));
refreshList();
}
public void onDeleteAllPressed(View view) {
callApi(this, () -> {
mShortcutManager.removeAllDynamicShortcuts();
return true;
});
refreshList();
}
static String formatTime(long time) {
Time tobj = new Time();
tobj.set(time);
return tobj.format("%Y-%m-%d %H:%M:%S");
}
public void onAddPressed(View view) {
final ShortcutInfo si = addRandomIntents(this, new ShortcutInfo.Builder(this)
.setId("shortcut-" + formatTime(System.currentTimeMillis()))
.setWeight(10)).build();
callApi(this, () -> mShortcutManager.addDynamicShortcuts(Arrays.asList(si)));
refreshList();
}
public void onUpdatePressed(View view) {
final List updateList = new ArrayList<>();
for (ShortcutInfo si : getAllShortcuts()) {
if (SETUP_SHORTCUT_ID.equals(si.getId())) continue;
updateList.add(addRandomIntents(this, new ShortcutInfo.Builder(this)
.setId(si.getId()))
.build());
}
callApi(this, () -> mShortcutManager.updateShortcuts(updateList));
refreshList();
}
void launch(ShortcutInfo si) {
startActivity(si.getIntent());
}
void deleteDynamic(ShortcutInfo si) {
mShortcutManager.removeDynamicShortcuts(Arrays.asList(si.getId()));
refreshList();
}
class MyAdapter extends ShortcutAdapter {
public MyAdapter(Context context) {
super(context);
}
@Override
protected int getLayoutId() {
return R.layout.list_item;
}
@Override
protected int getText1Id() {
return R.id.line1;
}
@Override
protected int getText2Id() {
return R.id.line2;
}
@Override
protected int getImageId() {
return R.id.image;
}
@Override
protected int getLaunchId() {
return R.id.launch;
}
@Override
protected int getAction2Id() {
return R.id.action2;
}
@Override
protected boolean showLaunch(ShortcutInfo si) {
return true;
}
@Override
protected boolean showAction2(ShortcutInfo si) {
return si.isDynamic();
}
@Override
protected String getAction2Text(ShortcutInfo si) {
return "Delete";
}
@Override
protected void onLaunchClicked(ShortcutInfo si) {
launch(si);
}
@Override
protected void onAction2Clicked(ShortcutInfo si) {
deleteDynamic(si);
}
}
}

View File

@@ -1,57 +0,0 @@
/*
* Copyright (C) 2016 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.example.android.pm.shortcutdemo;
import android.app.IntentService;
import android.content.Intent;
import android.content.pm.ShortcutInfo;
import android.content.pm.ShortcutManager;
import java.util.Arrays;
/**
* This allows to create a shortcut in background.
*
* Usage:
adb shell am startservice -a com.example.android.pm.shortcutdemo.ADD \
com.example.android.pm.shortcutdemo/com.example.android.pm.shortcutdemo.ShortcutPublishingService
* Or for package 2,
adb shell am startservice -a com.example.android.pm.shortcutdemo.ADD \
com.example.android.pm.shortcutdemo2/com.example.android.pm.shortcutdemo.ShortcutPublishingService
*/
public class ShortcutPublishingService extends IntentService {
public ShortcutPublishingService() {
super("ShortcutPublishingService");
}
@Override
protected void onHandleIntent(Intent intent) {
if (intent.getAction().endsWith(".ADD")) {
addShortcut();
return;
}
}
private void addShortcut() {
final ShortcutInfo si1 = ShortcutPublisher.addRandomIntents(
this, new ShortcutInfo.Builder(this)
.setId("shortcut-" + System.currentTimeMillis())
.setWeight(10)).build();
ShortcutPublisher.callApi(this, () ->
getSystemService(ShortcutManager.class).addDynamicShortcuts(Arrays.asList(si1)));
}
}