Merge "ShortcutManager sample update:" into nyc-dev
am: cb84ec875e
* commit 'cb84ec875e1d15575726adfb4592d27522eea070':
ShortcutManager sample update:
Change-Id: I55ebc36f70e1021988f9cb8cee83bd501cefe8f8
This commit is contained in:
@@ -25,7 +25,6 @@ LOCAL_PACKAGE_NAME := ShortcutDemo
|
|||||||
|
|
||||||
LOCAL_MODULE_TAGS := samples tests
|
LOCAL_MODULE_TAGS := samples tests
|
||||||
|
|
||||||
LOCAL_MANIFEST_FILE := manifest1/AndroidManifest.xml
|
|
||||||
LOCAL_AAPT_FLAGS += --rename-manifest-package com.example.android.pm.shortcutdemo
|
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, src)
|
||||||
@@ -46,7 +45,6 @@ LOCAL_PACKAGE_NAME := ShortcutDemo2
|
|||||||
|
|
||||||
LOCAL_MODULE_TAGS := samples tests
|
LOCAL_MODULE_TAGS := samples tests
|
||||||
|
|
||||||
LOCAL_MANIFEST_FILE := manifest2/AndroidManifest.xml
|
|
||||||
LOCAL_AAPT_FLAGS += --rename-manifest-package com.example.android.pm.shortcutdemo2
|
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, src)
|
||||||
|
|||||||
@@ -31,7 +31,10 @@
|
|||||||
<category android:name="android.intent.category.LAUNCHER" />
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
<provider android:authorities="com.example.android.pm.shortcutdemo"
|
<service android:name="ShortcutPublishingService">
|
||||||
android:name="IconProvider"/>
|
<intent-filter>
|
||||||
|
<action android:name="com.example.android.pm.shortcutdemo.ADD" />
|
||||||
|
</intent-filter>
|
||||||
|
</service>
|
||||||
</application>
|
</application>
|
||||||
</manifest>
|
</manifest>
|
||||||
@@ -1,37 +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>
|
|
||||||
<provider android:authorities="com.example.android.pm.shortcutdemo2"
|
|
||||||
android:name="IconProvider"/>
|
|
||||||
</application>
|
|
||||||
</manifest>
|
|
||||||
@@ -1,102 +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.ContentProvider;
|
|
||||||
import android.content.ContentProvider.PipeDataWriter;
|
|
||||||
import android.content.ContentValues;
|
|
||||||
import android.database.Cursor;
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.os.ParcelFileDescriptor;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
|
|
||||||
public class IconProvider extends ContentProvider implements PipeDataWriter<InputStream> {
|
|
||||||
@Override
|
|
||||||
public boolean onCreate() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Cursor query(Uri uri, String[] projection, String selection,
|
|
||||||
String[] selectionArgs, String sortOrder) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getType(Uri uri) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Uri insert(Uri uri, ContentValues values) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int delete(Uri uri, String selection,
|
|
||||||
String[] selectionArgs) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int update(Uri uri, ContentValues values, String selection,
|
|
||||||
String[] selectionArgs) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
|
|
||||||
if (!"r".equals(mode)) {
|
|
||||||
throw new IllegalArgumentException("Only read is supported");
|
|
||||||
}
|
|
||||||
final int resId = Integer.parseInt(uri.getPath().substring(1) /* to remove the slash */);
|
|
||||||
|
|
||||||
// Try to open an asset with the given name.
|
|
||||||
try {
|
|
||||||
return new ParcelFileDescriptor(openPipeHelper(uri, null, null,
|
|
||||||
getContext().getResources().openRawResource(resId), this));
|
|
||||||
} catch (IOException e) {
|
|
||||||
FileNotFoundException fnf = new FileNotFoundException("Unable to open " + uri);
|
|
||||||
throw fnf;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void writeDataToPipe(ParcelFileDescriptor output, Uri uri, String mimeType,
|
|
||||||
Bundle opts, InputStream args) {
|
|
||||||
// Transfer data from the asset to the pipe the client is reading.
|
|
||||||
byte[] buffer = new byte[8192];
|
|
||||||
int n;
|
|
||||||
try (FileOutputStream fout = new FileOutputStream(output.getFileDescriptor())) {
|
|
||||||
while ((n=args.read(buffer)) >= 0) {
|
|
||||||
fout.write(buffer, 0, n);
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
Log.i("IconProvider", "Failed transferring", e);
|
|
||||||
} finally {
|
|
||||||
try {
|
|
||||||
args.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -51,7 +51,7 @@ public class ShortcutPublisher extends Activity {
|
|||||||
private ListView mList;
|
private ListView mList;
|
||||||
private MyAdapter mAdapter;
|
private MyAdapter mAdapter;
|
||||||
|
|
||||||
private final Random mRandom = new Random();
|
private static final Random sRandom = new Random();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
@@ -124,27 +124,27 @@ public class ShortcutPublisher extends Activity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showToast(String message) {
|
private static void showToast(Context context, String message) {
|
||||||
Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
|
Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showThrottledToast() {
|
private static void showThrottledToast(Context context) {
|
||||||
showToast("Throttled, use \"adb shell cmd shortcut reset-throttling\" to reset counters");
|
showToast(context,
|
||||||
|
"Throttled, use \"adb shell cmd shortcut reset-throttling\" to reset counters");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void callApi(BooleanSupplier call) {
|
public static void callApi(Context context, BooleanSupplier call) {
|
||||||
try {
|
try {
|
||||||
if (!call.getAsBoolean()) {
|
if (!call.getAsBoolean()) {
|
||||||
showThrottledToast();
|
showThrottledToast(context);
|
||||||
}
|
}
|
||||||
refreshList();
|
|
||||||
} catch (RuntimeException r) {
|
} catch (RuntimeException r) {
|
||||||
Log.w(TAG, r.getMessage(), r);
|
Log.w(TAG, r.getMessage(), r);
|
||||||
showToast(r.getMessage());
|
showToast(context, r.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Pair<String, String>> mIntentList = Arrays.asList(
|
private static List<Pair<String, String>> sIntentList = Arrays.asList(
|
||||||
Pair.create("Google Search", "http://www.google.com"),
|
Pair.create("Google Search", "http://www.google.com"),
|
||||||
Pair.create("Google Mail", "http://mail.google.com"),
|
Pair.create("Google Mail", "http://mail.google.com"),
|
||||||
Pair.create("Google Maps", "http://maps.google.com"),
|
Pair.create("Google Maps", "http://maps.google.com"),
|
||||||
@@ -154,11 +154,11 @@ public class ShortcutPublisher extends Activity {
|
|||||||
Pair.create("Google+", "http://plus.google.com")
|
Pair.create("Google+", "http://plus.google.com")
|
||||||
);
|
);
|
||||||
|
|
||||||
public ShortcutInfo.Builder addRandomIntents(ShortcutInfo.Builder b) {
|
public static ShortcutInfo.Builder addRandomIntents(Context context, ShortcutInfo.Builder b) {
|
||||||
final int i = mRandom.nextInt(mIntentList.size());
|
final int i = sRandom.nextInt(sIntentList.size());
|
||||||
b.setTitle(mIntentList.get(i).first);
|
b.setTitle(sIntentList.get(i).first);
|
||||||
b.setIntent(new Intent(Intent.ACTION_VIEW, Uri.parse(mIntentList.get(i).second)));
|
b.setIntent(new Intent(Intent.ACTION_VIEW, Uri.parse(sIntentList.get(i).second)));
|
||||||
b.setIcon(Icon.createWithResource(this, R.drawable.icon2));
|
b.setIcon(Icon.createWithResource(context, R.drawable.icon2));
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -166,8 +166,7 @@ public class ShortcutPublisher extends Activity {
|
|||||||
dumpCurrentShortcuts();
|
dumpCurrentShortcuts();
|
||||||
final Icon icon2 = Icon.createWithBitmap(BitmapFactory.decodeResource(getResources(),
|
final Icon icon2 = Icon.createWithBitmap(BitmapFactory.decodeResource(getResources(),
|
||||||
R.drawable.icon_large_2));
|
R.drawable.icon_large_2));
|
||||||
final Icon icon3 = Icon.createWithContentUri(
|
final Icon icon3 = Icon.createWithResource(this, R.drawable.icon_large_3);
|
||||||
Uri.parse("content://" + getPackageName() + "/" + R.drawable.icon_large_3));
|
|
||||||
|
|
||||||
final Intent intent2 = new Intent(Intent.ACTION_VIEW);
|
final Intent intent2 = new Intent(Intent.ACTION_VIEW);
|
||||||
intent2.setClass(this, ShortcutPublisher.class);
|
intent2.setClass(this, ShortcutPublisher.class);
|
||||||
@@ -178,7 +177,7 @@ public class ShortcutPublisher extends Activity {
|
|||||||
intent3.putExtra("nest", new Bundle());
|
intent3.putExtra("nest", new Bundle());
|
||||||
intent3.getBundleExtra("nest").putInt("int", 123);
|
intent3.getBundleExtra("nest").putInt("int", 123);
|
||||||
|
|
||||||
final ShortcutInfo si1 = addRandomIntents(new ShortcutInfo.Builder(this)
|
final ShortcutInfo si1 = addRandomIntents(this, new ShortcutInfo.Builder(this)
|
||||||
.setId("shortcut1")
|
.setId("shortcut1")
|
||||||
.setWeight(10)).build();
|
.setWeight(10)).build();
|
||||||
|
|
||||||
@@ -198,22 +197,16 @@ public class ShortcutPublisher extends Activity {
|
|||||||
.setIntent(intent3)
|
.setIntent(intent3)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
callApi(new BooleanSupplier() {
|
callApi(this, () -> mShortcutManager.setDynamicShortcuts(Arrays.asList(si1, si2, si3)));
|
||||||
@Override
|
refreshList();
|
||||||
public boolean getAsBoolean() {
|
|
||||||
return mShortcutManager.setDynamicShortcuts(Arrays.asList(si1, si2, si3));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onDeleteAllPressed(View view) {
|
public void onDeleteAllPressed(View view) {
|
||||||
callApi(new BooleanSupplier() {
|
callApi(this, () -> {
|
||||||
@Override
|
mShortcutManager.removeAllDynamicShortcuts();
|
||||||
public boolean getAsBoolean() {
|
return true;
|
||||||
mShortcutManager.removeAllDynamicShortcuts();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
refreshList();
|
||||||
}
|
}
|
||||||
|
|
||||||
static String formatTime(long time) {
|
static String formatTime(long time) {
|
||||||
@@ -223,15 +216,11 @@ public class ShortcutPublisher extends Activity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void onAddPressed(View view) {
|
public void onAddPressed(View view) {
|
||||||
final ShortcutInfo si = addRandomIntents(new ShortcutInfo.Builder(this)
|
final ShortcutInfo si = addRandomIntents(this, new ShortcutInfo.Builder(this)
|
||||||
.setId("shortcut-" + formatTime(System.currentTimeMillis()))
|
.setId("shortcut-" + formatTime(System.currentTimeMillis()))
|
||||||
.setWeight(10)).build();
|
.setWeight(10)).build();
|
||||||
callApi(new BooleanSupplier() {
|
callApi(this, () -> mShortcutManager.addDynamicShortcuts(Arrays.asList(si)));
|
||||||
@Override
|
refreshList();
|
||||||
public boolean getAsBoolean() {
|
|
||||||
return mShortcutManager.addDynamicShortcuts(Arrays.asList(si));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onUpdatePressed(View view) {
|
public void onUpdatePressed(View view) {
|
||||||
@@ -239,16 +228,12 @@ public class ShortcutPublisher extends Activity {
|
|||||||
|
|
||||||
for (ShortcutInfo si : getAllShortcuts()) {
|
for (ShortcutInfo si : getAllShortcuts()) {
|
||||||
if (SETUP_SHORTCUT_ID.equals(si.getId())) continue;
|
if (SETUP_SHORTCUT_ID.equals(si.getId())) continue;
|
||||||
updateList.add(addRandomIntents(new ShortcutInfo.Builder(this)
|
updateList.add(addRandomIntents(this, new ShortcutInfo.Builder(this)
|
||||||
.setId(si.getId()))
|
.setId(si.getId()))
|
||||||
.build());
|
.build());
|
||||||
}
|
}
|
||||||
callApi(new BooleanSupplier() {
|
callApi(this, () -> mShortcutManager.updateShortcuts(updateList));
|
||||||
@Override
|
refreshList();
|
||||||
public boolean getAsBoolean() {
|
|
||||||
return mShortcutManager.updateShortcuts(updateList);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void launch(ShortcutInfo si) {
|
void launch(ShortcutInfo si) {
|
||||||
|
|||||||
@@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* 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)));
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user