Shortcut launcher demo:
- Listen to work profile broadcasts and refresh the screen. - Fix the bug about mixing up user 0 and user 10. - Add a "user has any shortcuts or not" test to detect user unlock races. Change-Id: I4c5ae34317b669dd8fcda466a960074b22e88d5a
This commit is contained in:
@@ -23,6 +23,7 @@ import android.content.pm.LauncherApps.ShortcutQuery;
|
|||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
|
import android.os.UserManager;
|
||||||
import android.util.DisplayMetrics;
|
import android.util.DisplayMetrics;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
@@ -82,12 +83,14 @@ public class AppListFragment extends MyBaseListFragment {
|
|||||||
public class AppAdapter extends BaseAdapter implements OnClickListener {
|
public class AppAdapter extends BaseAdapter implements OnClickListener {
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
private final LayoutInflater mInflater;
|
private final LayoutInflater mInflater;
|
||||||
private LauncherApps mLauncherApps;
|
private final UserManager mUserManager;
|
||||||
|
private final LauncherApps mLauncherApps;
|
||||||
private List<LauncherActivityInfo> mList;
|
private List<LauncherActivityInfo> mList;
|
||||||
|
|
||||||
public AppAdapter(Context context) {
|
public AppAdapter(Context context) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
mInflater = mContext.getSystemService(LayoutInflater.class);
|
mInflater = mContext.getSystemService(LayoutInflater.class);
|
||||||
|
mUserManager = mContext.getSystemService(UserManager.class);
|
||||||
mLauncherApps = mContext.getSystemService(LauncherApps.class);
|
mLauncherApps = mContext.getSystemService(LauncherApps.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,7 +159,8 @@ public class AppListFragment extends MyBaseListFragment {
|
|||||||
|
|
||||||
v.setVisibility(View.INVISIBLE);
|
v.setVisibility(View.INVISIBLE);
|
||||||
try {
|
try {
|
||||||
if (mLauncherApps.hasShortcutHostPermission()) {
|
if (mUserManager.isUserUnlocked(ai.getUser())
|
||||||
|
&& mLauncherApps.hasShortcutHostPermission()) {
|
||||||
mQuery.setPackage(ai.getComponentName().getPackageName());
|
mQuery.setPackage(ai.getComponentName().getPackageName());
|
||||||
mQuery.setQueryFlags(ShortcutQuery.FLAG_MATCH_DYNAMIC
|
mQuery.setQueryFlags(ShortcutQuery.FLAG_MATCH_DYNAMIC
|
||||||
| ShortcutQuery.FLAG_MATCH_PINNED
|
| ShortcutQuery.FLAG_MATCH_PINNED
|
||||||
|
|||||||
@@ -16,6 +16,10 @@
|
|||||||
package com.example.android.pm.shortcutlauncherdemo;
|
package com.example.android.pm.shortcutlauncherdemo;
|
||||||
|
|
||||||
import android.app.ListFragment;
|
import android.app.ListFragment;
|
||||||
|
import android.content.BroadcastReceiver;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.IntentFilter;
|
||||||
import android.content.pm.ApplicationInfo;
|
import android.content.pm.ApplicationInfo;
|
||||||
import android.content.pm.LauncherApps;
|
import android.content.pm.LauncherApps;
|
||||||
import android.content.pm.LauncherApps.ShortcutQuery;
|
import android.content.pm.LauncherApps.ShortcutQuery;
|
||||||
@@ -39,6 +43,23 @@ public abstract class MyBaseListFragment extends ListFragment {
|
|||||||
|
|
||||||
protected final ShortcutQuery mQuery = new ShortcutQuery();
|
protected final ShortcutQuery mQuery = new ShortcutQuery();
|
||||||
|
|
||||||
|
public final static IntentFilter sProfileFilter = new IntentFilter();
|
||||||
|
|
||||||
|
static {
|
||||||
|
sProfileFilter.addAction(Intent.ACTION_MANAGED_PROFILE_ADDED);
|
||||||
|
sProfileFilter.addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE);
|
||||||
|
sProfileFilter.addAction(Intent.ACTION_MANAGED_PROFILE_REMOVED);
|
||||||
|
sProfileFilter.addAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE);
|
||||||
|
sProfileFilter.addAction(Intent.ACTION_MANAGED_PROFILE_UNLOCKED);
|
||||||
|
}
|
||||||
|
|
||||||
|
private final BroadcastReceiver mProfileReceiver = new BroadcastReceiver() {
|
||||||
|
@Override
|
||||||
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
refreshList();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
@@ -48,20 +69,24 @@ public abstract class MyBaseListFragment extends ListFragment {
|
|||||||
mLauncherApps.registerCallback(mLauncherCallback);
|
mLauncherApps.registerCallback(mLauncherCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStart() {
|
|
||||||
super.onStart();
|
|
||||||
|
|
||||||
Log.d(Global.TAG, "Started");
|
|
||||||
|
|
||||||
refreshList();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onResume() {
|
public void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
|
|
||||||
|
Log.d(Global.TAG, "Resumed");
|
||||||
|
|
||||||
showPermissionWarningToastWhenNeeded();
|
showPermissionWarningToastWhenNeeded();
|
||||||
|
|
||||||
|
refreshList();
|
||||||
|
|
||||||
|
getActivity().registerReceiver(mProfileReceiver, sProfileFilter);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPause() {
|
||||||
|
getActivity().unregisterReceiver(mProfileReceiver);
|
||||||
|
|
||||||
|
super.onPause();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ import android.app.Activity;
|
|||||||
import android.app.Fragment;
|
import android.app.Fragment;
|
||||||
import android.app.FragmentManager;
|
import android.app.FragmentManager;
|
||||||
import android.app.FragmentTransaction;
|
import android.app.FragmentTransaction;
|
||||||
import android.content.pm.LauncherApps;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.v13.app.FragmentStatePagerAdapter;
|
import android.support.v13.app.FragmentStatePagerAdapter;
|
||||||
import android.support.v4.view.PagerAdapter;
|
import android.support.v4.view.PagerAdapter;
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ import android.content.pm.ShortcutInfo;
|
|||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.os.UserManager;
|
import android.os.UserManager;
|
||||||
import android.text.TextUtils;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
@@ -93,6 +92,7 @@ public class ShortcutListFragment extends MyBaseListFragment {
|
|||||||
|
|
||||||
private void togglePin(ShortcutInfo selected) {
|
private void togglePin(ShortcutInfo selected) {
|
||||||
final String packageName = selected.getPackage();
|
final String packageName = selected.getPackage();
|
||||||
|
final UserHandle user = selected.getUserHandle();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final ShortcutQuery q = new ShortcutQuery()
|
final ShortcutQuery q = new ShortcutQuery()
|
||||||
@@ -101,7 +101,7 @@ public class ShortcutListFragment extends MyBaseListFragment {
|
|||||||
;
|
;
|
||||||
|
|
||||||
final List<String> pinned = new ArrayList<>();
|
final List<String> pinned = new ArrayList<>();
|
||||||
for (ShortcutInfo si : mLauncherApps.getShortcuts(q, android.os.Process.myUserHandle())) {
|
for (ShortcutInfo si : mLauncherApps.getShortcuts(q, user)) {
|
||||||
pinned.add(si.getId());
|
pinned.add(si.getId());
|
||||||
}
|
}
|
||||||
if (selected.isPinned()) {
|
if (selected.isPinned()) {
|
||||||
@@ -126,6 +126,7 @@ public class ShortcutListFragment extends MyBaseListFragment {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void refreshList() {
|
protected void refreshList() {
|
||||||
|
Log.i(TAG, "Refreshing shortcuts");
|
||||||
try {
|
try {
|
||||||
if (!mLauncherApps.hasShortcutHostPermission()) {
|
if (!mLauncherApps.hasShortcutHostPermission()) {
|
||||||
return;
|
return;
|
||||||
@@ -134,6 +135,25 @@ public class ShortcutListFragment extends MyBaseListFragment {
|
|||||||
final List<ShortcutInfo> list = new ArrayList<>();
|
final List<ShortcutInfo> list = new ArrayList<>();
|
||||||
|
|
||||||
for (UserHandle user : getTargetUsers()) {
|
for (UserHandle user : getTargetUsers()) {
|
||||||
|
if (!mUserManager.isUserUnlocked(user)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// To detect a race condition, first fetch all shortcuts and report if none found.
|
||||||
|
mQuery.setQueryFlags(
|
||||||
|
ShortcutQuery.FLAG_MATCH_PINNED | ShortcutQuery.FLAG_MATCH_DYNAMIC
|
||||||
|
| ShortcutQuery.FLAG_MATCH_MANIFEST
|
||||||
|
| ShortcutQuery.FLAG_GET_KEY_FIELDS_ONLY);
|
||||||
|
mQuery.setPackage(null);
|
||||||
|
mQuery.setActivity(null);
|
||||||
|
mQuery.setChangedSince(0);
|
||||||
|
final int numShortcuts = mLauncherApps.getShortcuts(mQuery, user).size();
|
||||||
|
if (numShortcuts == 0) {
|
||||||
|
final String message = "No shortcut found for " + user;
|
||||||
|
Log.e(TAG, message);
|
||||||
|
Global.showToast(getContext(), message);
|
||||||
|
}
|
||||||
|
|
||||||
final Bundle b = getArguments();
|
final Bundle b = getArguments();
|
||||||
mQuery.setQueryFlags(
|
mQuery.setQueryFlags(
|
||||||
(b.getBoolean(ARG_INCLUDE_DYNAMIC) ? ShortcutQuery.FLAG_MATCH_DYNAMIC : 0) |
|
(b.getBoolean(ARG_INCLUDE_DYNAMIC) ? ShortcutQuery.FLAG_MATCH_DYNAMIC : 0) |
|
||||||
|
|||||||
Reference in New Issue
Block a user