slight cleanups to direct share implementation
This commit is contained in:
parent
2df5d679c3
commit
9273d253fa
4 changed files with 104 additions and 76 deletions
|
@ -113,14 +113,14 @@ public class RecipientLoader extends AsyncTaskLoader<List<Recipient>> {
|
|||
private List<Recipient> cachedRecipients;
|
||||
private ForceLoadContentObserver observerContact, observerKey;
|
||||
|
||||
private RecipientLoader(Context context, String cryptoProvider) {
|
||||
private RecipientLoader(Context context) {
|
||||
super(context);
|
||||
this.query = null;
|
||||
this.lookupKeyUri = null;
|
||||
this.addresses = null;
|
||||
this.contactUri = null;
|
||||
|
||||
this.cryptoProvider = cryptoProvider;
|
||||
this.cryptoProvider = null;
|
||||
this.contentResolver = context.getContentResolver();
|
||||
}
|
||||
|
||||
|
@ -157,14 +157,11 @@ public class RecipientLoader extends AsyncTaskLoader<List<Recipient>> {
|
|||
contentResolver = context.getContentResolver();
|
||||
}
|
||||
|
||||
public static RecipientLoader getMostContactedRecipientLoader(Context context, String cryptoProvider,
|
||||
final int maxRecipients) {
|
||||
return new RecipientLoader(context, cryptoProvider) {
|
||||
public static RecipientLoader getMostContactedRecipientLoader(Context context, final int maxRecipients) {
|
||||
return new RecipientLoader(context) {
|
||||
@Override
|
||||
public List<Recipient> loadInBackground() {
|
||||
Map<String, Recipient> recipientMap = new HashMap<>();
|
||||
List<Recipient> recipients = super.fillContactDataBySortOrder(recipientMap, maxRecipients);
|
||||
return super.fillCryptoStatusData(recipients, recipientMap);
|
||||
return super.fillContactDataBySortOrder(maxRecipients);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -357,7 +354,7 @@ public class RecipientLoader extends AsyncTaskLoader<List<Recipient>> {
|
|||
return hasContact;
|
||||
}
|
||||
|
||||
private List<Recipient> fillContactDataBySortOrder(Map<String, Recipient> recipientMap, Integer maxRecipients) {
|
||||
private List<Recipient> fillContactDataBySortOrder(int maxRecipients) {
|
||||
List<Recipient> recipients = new ArrayList<>();
|
||||
|
||||
Uri queryUri = Email.CONTENT_URI;
|
||||
|
@ -367,7 +364,7 @@ public class RecipientLoader extends AsyncTaskLoader<List<Recipient>> {
|
|||
return recipients;
|
||||
}
|
||||
|
||||
fillContactDataFromCursor(cursor, recipients, recipientMap, null, maxRecipients);
|
||||
fillContactDataFromCursor(cursor, recipients, new HashMap<String, Recipient>(), null, maxRecipients);
|
||||
|
||||
return recipients;
|
||||
}
|
||||
|
|
|
@ -3,21 +3,21 @@ package com.fsck.k9.activity.misc;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Bitmap.CompressFormat;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Paint.Style;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.Icon;
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.VisibleForTesting;
|
||||
import android.support.annotation.WorkerThread;
|
||||
import android.text.TextUtils;
|
||||
import android.widget.ImageView;
|
||||
|
||||
|
@ -34,8 +34,8 @@ import com.bumptech.glide.load.resource.bitmap.BitmapResource;
|
|||
import com.bumptech.glide.load.resource.bitmap.StreamBitmapDecoder;
|
||||
import com.bumptech.glide.load.resource.drawable.GlideDrawable;
|
||||
import com.bumptech.glide.load.resource.file.FileToStreamDecoder;
|
||||
import com.bumptech.glide.load.resource.transcode.BitmapBytesTranscoder;
|
||||
import com.bumptech.glide.load.resource.transcode.BitmapToGlideDrawableTranscoder;
|
||||
import com.bumptech.glide.request.FutureTarget;
|
||||
import com.bumptech.glide.request.RequestListener;
|
||||
import com.bumptech.glide.request.target.Target;
|
||||
import com.fsck.k9.helper.Contacts;
|
||||
|
@ -60,7 +60,7 @@ public class ContactPictureLoader {
|
|||
private static final String FALLBACK_CONTACT_LETTER = "?";
|
||||
|
||||
|
||||
private Resources mResources;
|
||||
private final Context context;
|
||||
private Contacts mContactsHelper;
|
||||
private int mPictureSizeInPx;
|
||||
|
||||
|
@ -106,11 +106,11 @@ public class ContactPictureLoader {
|
|||
* use a dynamically calculated background color.
|
||||
*/
|
||||
public ContactPictureLoader(Context context, int defaultBackgroundColor) {
|
||||
Context appContext = context.getApplicationContext();
|
||||
mResources = appContext.getResources();
|
||||
mContactsHelper = Contacts.getInstance(appContext);
|
||||
this.context = context.getApplicationContext();
|
||||
mContactsHelper = Contacts.getInstance(this.context);
|
||||
|
||||
float scale = mResources.getDisplayMetrics().density;
|
||||
Resources resources = context.getResources();
|
||||
float scale = resources.getDisplayMetrics().density;
|
||||
mPictureSizeInPx = (int) (PICTURE_SIZE * scale);
|
||||
|
||||
mDefaultBackgroundColor = defaultBackgroundColor;
|
||||
|
@ -176,39 +176,35 @@ public class ContactPictureLoader {
|
|||
}
|
||||
}
|
||||
|
||||
public Bitmap loadContactPictureIcon(Context context, Recipient recipient) {
|
||||
return loadContactPicture(context, recipient.photoThumbnailUri, recipient.address);
|
||||
public Bitmap loadContactPictureIcon(Recipient recipient) {
|
||||
return loadContactPicture(recipient.photoThumbnailUri, recipient.address);
|
||||
}
|
||||
|
||||
private Bitmap loadContactPicture(final Context context, Uri photoUri, final Address address) {
|
||||
@WorkerThread
|
||||
private Bitmap loadContactPicture(Uri photoUri, Address address) {
|
||||
FutureTarget<Bitmap> bitmapTarget;
|
||||
if (photoUri != null) {
|
||||
try {
|
||||
return Glide.with(context)
|
||||
.load(photoUri)
|
||||
.asBitmap()
|
||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||
.dontAnimate()
|
||||
.into(mPictureSizeInPx, mPictureSizeInPx)
|
||||
.get();
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
try {
|
||||
return Glide.with(context)
|
||||
bitmapTarget = Glide.with(context)
|
||||
.load(photoUri)
|
||||
.asBitmap()
|
||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||
.dontAnimate()
|
||||
.into(mPictureSizeInPx, mPictureSizeInPx);
|
||||
} else {
|
||||
bitmapTarget = Glide.with(context)
|
||||
.using(new FallbackGlideModelLoader(), FallbackGlideParams.class)
|
||||
.from(FallbackGlideParams.class)
|
||||
.as(Bitmap.class)
|
||||
.decoder(new FallbackGlideBitmapDecoder(context))
|
||||
.encoder(new BitmapEncoder(Bitmap.CompressFormat.PNG, 0))
|
||||
.encoder(new BitmapEncoder(CompressFormat.PNG, 0))
|
||||
.cacheDecoder(new FileToStreamDecoder<>(new StreamBitmapDecoder(context)))
|
||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||
.load(new FallbackGlideParams(address))
|
||||
.dontAnimate()
|
||||
.into(mPictureSizeInPx, mPictureSizeInPx).get();
|
||||
} catch (Exception e) {
|
||||
.into(mPictureSizeInPx, mPictureSizeInPx);
|
||||
}
|
||||
|
||||
return null;
|
||||
return loadIgnoringErors(bitmapTarget);
|
||||
}
|
||||
|
||||
private int calcUnknownContactColor(Address address) {
|
||||
|
@ -310,4 +306,14 @@ public class ContactPictureLoader {
|
|||
}
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
@Nullable
|
||||
private <T> T loadIgnoringErors(FutureTarget<T> target) {
|
||||
try {
|
||||
return target.get();
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
package com.fsck.k9.service;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.graphics.Bitmap;
|
||||
|
@ -11,55 +15,78 @@ import android.os.Build;
|
|||
import android.os.Bundle;
|
||||
import android.service.chooser.ChooserTarget;
|
||||
import android.service.chooser.ChooserTargetService;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import com.fsck.k9.activity.MessageCompose;
|
||||
import com.fsck.k9.activity.compose.RecipientLoader;
|
||||
import com.fsck.k9.activity.misc.ContactPictureLoader;
|
||||
import com.fsck.k9.helper.ContactPicture;
|
||||
import com.fsck.k9.view.RecipientSelectView;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import com.fsck.k9.view.RecipientSelectView.Recipient;
|
||||
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.M)
|
||||
public class K9ChooserTargetService extends ChooserTargetService {
|
||||
private static final int MAX_TARGETS = 5;
|
||||
|
||||
private final int MAX_TARGETS = 5;
|
||||
private RecipientLoader recipientLoader;
|
||||
private ContactPictureLoader contactPictureLoader;
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
|
||||
Context applicationContext = getApplicationContext();
|
||||
recipientLoader = RecipientLoader.getMostContactedRecipientLoader(applicationContext, MAX_TARGETS);
|
||||
contactPictureLoader = ContactPicture.getContactPictureLoader(applicationContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ChooserTarget> onGetChooserTargets(ComponentName targetActivityName, IntentFilter matchedFilter) {
|
||||
final List<ChooserTarget> targets = new ArrayList<>();
|
||||
final ComponentName componentName = new ComponentName(this, MessageCompose.class);
|
||||
List<Recipient> recipients = recipientLoader.loadInBackground();
|
||||
|
||||
String cryptoProvider = null;//TODO please check, cryptoProvider necessary?
|
||||
RecipientLoader recipientLoader = RecipientLoader
|
||||
.getMostContactedRecipientLoader(this.getApplicationContext(), cryptoProvider, MAX_TARGETS);
|
||||
List<RecipientSelectView.Recipient> recipients = recipientLoader.loadInBackground();
|
||||
return createChooserTargets(recipients);
|
||||
}
|
||||
|
||||
// Ranking score for target between 0.0f and 1.0f
|
||||
@NonNull
|
||||
private List<ChooserTarget> createChooserTargets(List<Recipient> recipients) {
|
||||
float score = 1.0f;
|
||||
|
||||
for (RecipientSelectView.Recipient recipient : recipients) {
|
||||
List<ChooserTarget> targets = new ArrayList<>();
|
||||
ComponentName componentName = new ComponentName(this, MessageCompose.class);
|
||||
for (Recipient recipient : recipients) {
|
||||
Bundle intentExtras = prepareIntentExtras(recipient);
|
||||
Icon icon = loadRecipientIcon(recipient);
|
||||
|
||||
ChooserTarget chooserTarget =
|
||||
new ChooserTarget(recipient.getDisplayNameOrAddress(), icon, score, componentName, intentExtras);
|
||||
targets.add(chooserTarget);
|
||||
|
||||
final Bundle extras = new Bundle();
|
||||
extras.putString("uuid", recipient.getDisplayNameOrAddress());
|
||||
String address = recipient.address.getAddress();
|
||||
extras.putStringArray(Intent.EXTRA_EMAIL,
|
||||
new String[] { recipient.getDisplayNameOrAddress() + "<" + address + ">" });
|
||||
|
||||
Icon icon = null;
|
||||
Bitmap bitmap = ContactPicture.getContactPictureLoader(getApplicationContext())
|
||||
.loadContactPictureIcon(getApplicationContext(), recipient);
|
||||
if (bitmap != null) {
|
||||
icon = Icon.createWithBitmap(bitmap);
|
||||
}
|
||||
|
||||
targets.add(new ChooserTarget(recipient.getDisplayNameOrAddress(), icon, score, componentName, extras));
|
||||
score -= 0.1;
|
||||
}
|
||||
|
||||
return targets;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private Bundle prepareIntentExtras(Recipient recipient) {
|
||||
String address = recipient.address.getAddress();
|
||||
String displayNameOrAddress = recipient.getDisplayNameOrAddress();
|
||||
|
||||
Bundle extras = new Bundle();
|
||||
extras.putString("uuid", displayNameOrAddress);
|
||||
extras.putStringArray(Intent.EXTRA_EMAIL, new String[] { displayNameOrAddress + "<" + address + ">" });
|
||||
return extras;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Icon loadRecipientIcon(Recipient recipient) {
|
||||
Bitmap bitmap = contactPictureLoader.loadContactPictureIcon(recipient);
|
||||
if (bitmap == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return Icon.createWithBitmap(bitmap);
|
||||
}
|
||||
|
||||
}
|
|
@ -256,38 +256,36 @@ public class RecipientLoaderTest {
|
|||
int maxTargets = 1;
|
||||
setupContactProvider(CONTACT_1, CONTACT_2);
|
||||
|
||||
RecipientLoader recipientLoader = RecipientLoader.getMostContactedRecipientLoader(context, CRYPTO_PROVIDER,
|
||||
maxTargets);
|
||||
RecipientLoader recipientLoader = RecipientLoader.getMostContactedRecipientLoader(context, maxTargets);
|
||||
List<Recipient> recipients = recipientLoader.loadInBackground();
|
||||
|
||||
assertEquals(maxTargets, recipients.size());
|
||||
assertEquals("bob@host.com", recipients.get(0).address.getAddress());
|
||||
assertEquals(RecipientCryptoStatus.UNAVAILABLE, recipients.get(0).getCryptoStatus());
|
||||
assertEquals(RecipientCryptoStatus.UNDEFINED, recipients.get(0).getCryptoStatus());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getMostContactedFoundLess() throws Exception {
|
||||
int maxTargets = 5;
|
||||
setupContactProvider(CONTACT_1, CONTACT_2);
|
||||
|
||||
|
||||
RecipientLoader recipientLoader = RecipientLoader.getMostContactedRecipientLoader(context, CRYPTO_PROVIDER,
|
||||
maxTargets);
|
||||
RecipientLoader recipientLoader = RecipientLoader.getMostContactedRecipientLoader(context, maxTargets);
|
||||
List<Recipient> recipients = recipientLoader.loadInBackground();
|
||||
|
||||
assertEquals(2, recipients.size());
|
||||
assertEquals("bob@host.com", recipients.get(0).address.getAddress());
|
||||
assertEquals(RecipientCryptoStatus.UNAVAILABLE, recipients.get(0).getCryptoStatus());
|
||||
assertEquals(RecipientCryptoStatus.UNDEFINED, recipients.get(0).getCryptoStatus());
|
||||
assertEquals("bob2@host.com", recipients.get(1).address.getAddress());
|
||||
assertEquals(RecipientCryptoStatus.UNAVAILABLE, recipients.get(1).getCryptoStatus());
|
||||
assertEquals(RecipientCryptoStatus.UNDEFINED, recipients.get(1).getCryptoStatus());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getMostContactedFoundNothing() throws Exception {
|
||||
int maxTargets = 5;
|
||||
setupContactProvider();
|
||||
|
||||
|
||||
RecipientLoader recipientLoader = RecipientLoader.getMostContactedRecipientLoader(context, CRYPTO_PROVIDER,
|
||||
maxTargets);
|
||||
RecipientLoader recipientLoader = RecipientLoader.getMostContactedRecipientLoader(context, maxTargets);
|
||||
List<Recipient> recipients = recipientLoader.loadInBackground();
|
||||
|
||||
assertEquals(0, recipients.size());
|
||||
|
|
Loading…
Reference in a new issue