From 044ea5c5a954d1b020c72d29f0f19ef04d1cc6b5 Mon Sep 17 00:00:00 2001 From: Ye feng <597231656@qq.com> Date: Wed, 4 Apr 2018 15:33:07 +0800 Subject: [PATCH] support contact shortcuts (#2918) * support contact shortcuts * make ShortcutActivity extends AbstractSearchableListItemActivity * Draw the app icon in the corner of the icon and modify the name of the widget * updated label and icon size --- src/main/AndroidManifest.xml | 10 ++- .../conversations/services/AvatarService.java | 36 +++++++++- .../services/ShortcutService.java | 41 +++++++++-- .../conversations/ui/ShortcutActivity.java | 68 +++++++++++++++++++ src/main/res/values/strings.xml | 2 + 5 files changed, 148 insertions(+), 9 deletions(-) create mode 100644 src/main/java/eu/siacs/conversations/ui/ShortcutActivity.java diff --git a/src/main/AndroidManifest.xml b/src/main/AndroidManifest.xml index 108442be9..a191042a2 100644 --- a/src/main/AndroidManifest.xml +++ b/src/main/AndroidManifest.xml @@ -106,6 +106,9 @@ android:name=".ui.StartConversationActivity" android:label="@string/title_activity_start_conversation" android:launchMode="singleTop"> + + + - + + + + + diff --git a/src/main/java/eu/siacs/conversations/services/AvatarService.java b/src/main/java/eu/siacs/conversations/services/AvatarService.java index 988320579..4a2c5188d 100644 --- a/src/main/java/eu/siacs/conversations/services/AvatarService.java +++ b/src/main/java/eu/siacs/conversations/services/AvatarService.java @@ -1,6 +1,8 @@ package eu.siacs.conversations.services; +import android.content.res.Resources; import android.graphics.Bitmap; +import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.PorterDuff; @@ -21,6 +23,7 @@ import java.util.Locale; import java.util.Set; import eu.siacs.conversations.Config; +import eu.siacs.conversations.R; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Bookmark; import eu.siacs.conversations.entities.Contact; @@ -76,21 +79,48 @@ public class AvatarService implements OnAdvancedStreamFeaturesLoaded { } public Bitmap getRoundedShortcut(final Contact contact) { + return getRoundedShortcut(contact,false); + } + + public Bitmap getRoundedShortcutWithIcon(final Contact contact){ + return getRoundedShortcut(contact,true); + } + + private Bitmap getRoundedShortcut(final Contact contact,boolean withIcon) { DisplayMetrics metrics = mXmppConnectionService.getResources().getDisplayMetrics(); int size = Math.round(metrics.density * 48); Bitmap bitmap = get(contact,size); Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(output); - final Paint paint = new Paint(); - final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()); + drawAvatar(bitmap, canvas, paint); + if(withIcon){ + drawIcon(canvas, paint); + } + return output; + } + + private void drawAvatar(Bitmap bitmap, Canvas canvas, Paint paint) { + final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()); paint.setAntiAlias(true); canvas.drawARGB(0, 0, 0, 0); canvas.drawCircle(bitmap.getWidth() / 2, bitmap.getHeight() / 2, bitmap.getWidth() / 2, paint); paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); canvas.drawBitmap(bitmap, rect, rect, paint); - return output; + } + + private void drawIcon(Canvas canvas, Paint paint) { + BitmapFactory.Options opts = new BitmapFactory.Options(); + opts.inSampleSize = 3; + Resources resources = mXmppConnectionService.getResources(); + Bitmap icon = BitmapFactory.decodeResource(resources, R.drawable.ic_launcher, opts); + paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER)); + + int left = canvas.getWidth() - icon.getWidth(); + int top = canvas.getHeight() - icon.getHeight(); + final Rect rect = new Rect(left, top, left + icon.getWidth(), top + icon.getHeight()); + canvas.drawBitmap(icon, null, rect, paint); } public Bitmap get(final MucOptions.User user, final int size, boolean cachedOnly) { diff --git a/src/main/java/eu/siacs/conversations/services/ShortcutService.java b/src/main/java/eu/siacs/conversations/services/ShortcutService.java index eaa956f4f..dc4f1ce28 100644 --- a/src/main/java/eu/siacs/conversations/services/ShortcutService.java +++ b/src/main/java/eu/siacs/conversations/services/ShortcutService.java @@ -4,9 +4,11 @@ import android.annotation.TargetApi; import android.content.Intent; import android.content.pm.ShortcutInfo; import android.content.pm.ShortcutManager; +import android.graphics.Bitmap; import android.graphics.drawable.Icon; import android.net.Uri; import android.os.Build; +import android.support.annotation.NonNull; import android.util.Log; import java.util.ArrayList; @@ -75,11 +77,7 @@ public class ShortcutService { } List newDynamicShortCuts = new ArrayList<>(); for (Contact contact : contacts) { - ShortcutInfo shortcut = new ShortcutInfo.Builder(xmppConnectionService, getShortcutId(contact)) - .setShortLabel(contact.getDisplayName()) - .setIntent(getShortcutIntent(contact)) - .setIcon(Icon.createWithBitmap(xmppConnectionService.getAvatarService().getRoundedShortcut(contact))) - .build(); + ShortcutInfo shortcut = getShortcutInfo(contact); newDynamicShortCuts.add(shortcut); } if (shortcutManager.setDynamicShortcuts(newDynamicShortCuts)) { @@ -89,6 +87,15 @@ public class ShortcutService { } } + @TargetApi(Build.VERSION_CODES.N_MR1) + private ShortcutInfo getShortcutInfo(Contact contact) { + return new ShortcutInfo.Builder(xmppConnectionService, getShortcutId(contact)) + .setShortLabel(contact.getDisplayName()) + .setIntent(getShortcutIntent(contact)) + .setIcon(Icon.createWithBitmap(xmppConnectionService.getAvatarService().getRoundedShortcut(contact))) + .build(); + } + private static boolean contactsChanged(List needles, List haystack) { for(Contact needle : needles) { if(!contactExists(needle,haystack)) { @@ -120,6 +127,30 @@ public class ShortcutService { return intent; } + @NonNull + public Intent createShortcut(Contact contact) { + Intent intent; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + ShortcutInfo shortcut = getShortcutInfo(contact); + ShortcutManager shortcutManager = xmppConnectionService.getSystemService(ShortcutManager.class); + intent = shortcutManager.createShortcutResultIntent(shortcut); + } else { + intent = createShortcutResultIntent(contact); + } + return intent; + } + + @NonNull + private Intent createShortcutResultIntent(Contact contact) { + Intent intent;AvatarService avatarService = xmppConnectionService.getAvatarService(); + Bitmap icon = avatarService.getRoundedShortcutWithIcon(contact); + intent = new Intent(); + intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, contact.getDisplayName()); + intent.putExtra(Intent.EXTRA_SHORTCUT_ICON, icon); + intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, getShortcutIntent(contact)); + return intent; + } + public static class FrequentContact { private final String account; private final Jid contact; diff --git a/src/main/java/eu/siacs/conversations/ui/ShortcutActivity.java b/src/main/java/eu/siacs/conversations/ui/ShortcutActivity.java new file mode 100644 index 000000000..bfffbdff7 --- /dev/null +++ b/src/main/java/eu/siacs/conversations/ui/ShortcutActivity.java @@ -0,0 +1,68 @@ +package eu.siacs.conversations.ui; + +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.support.v7.app.ActionBar; +import android.view.View; +import android.view.inputmethod.InputMethodManager; + +import java.util.Collections; + +import eu.siacs.conversations.R; +import eu.siacs.conversations.entities.Account; +import eu.siacs.conversations.entities.Contact; +import eu.siacs.conversations.entities.ListItem; + +public class ShortcutActivity extends AbstractSearchableListItemActivity{ + + @Override + protected void refreshUiReal() { + + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getListView().setOnItemClickListener((parent, view, position, id) -> { + final InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + imm.hideSoftInputFromWindow(getSearchEditText().getWindowToken(), InputMethodManager.HIDE_IMPLICIT_ONLY); + + ListItem listItem = getListItems().get(position); + Intent shortcut = xmppConnectionService.getShortcutService().createShortcut(((Contact) listItem)); + setResult(RESULT_OK,shortcut); + finish(); + }); + binding.fab.setVisibility(View.GONE); + } + + @Override + protected void onStart() { + super.onStart(); + ActionBar bar = getSupportActionBar(); + if(bar != null){ + bar.setTitle(R.string.create_shortcut); + } + } + + @Override + protected void filterContacts(String needle) { + getListItems().clear(); + if (xmppConnectionService == null) { + getListItemAdapter().notifyDataSetChanged(); + return; + } + for (final Account account : xmppConnectionService.getAccounts()) { + if (account.getStatus() != Account.State.DISABLED) { + for (final Contact contact : account.getRoster().getContacts()) { + if (contact.showInRoster() + && contact.match(this, needle)) { + getListItems().add(contact); + } + } + } + } + Collections.sort(getListItems()); + getListItemAdapter().notifyDataSetChanged(); + } +} diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index 823f527d3..608c8b9ba 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -49,6 +49,7 @@ Start conversation Invite contact Contacts + Contact Cancel Set Add @@ -739,6 +740,7 @@ OMEMO will always be used for one-on-one and private group chats. OMEMO will be used by default for new conversations. OMEMO will have to be turned on explicitly for new conversations. + Create Shortcut Font Size The relative font size used within the app. On by default