package com.mcxiaoke.next.support.v7;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.Resources;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.view.ActionProvider;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SubMenu;
import android.view.View;
import android.widget.Toast;
import com.mcxiaoke.next.extras.BuildConfig;
import com.mcxiaoke.next.extras.R;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
/**
* User: mcxiaoke
* Date: 13-10-22
* Time: 下午4:00
*
* 添加自定义ShareTarget支持,Updated: 2013-12-24
*/
/**
* 高级版的ShareActionProvider
* 支持自定义优先显示的分享目标
*/
public class AdvancedShareActionProvider extends ActionProvider implements MenuItem.OnMenuItemClickListener {
public static final boolean DEBUG = BuildConfig.DEBUG;
public static final String TAG = AdvancedShareActionProvider.class.getSimpleName();
public static final int WEIGHT_MAX = Integer.MAX_VALUE;
public static final int WEIGHT_DEFAULT = 0;
/**
* 默认显示的分享目标数量
*/
public static final int DEFAULT_LIST_LENGTH = 4;
private final Object mLock = new Object();
private int mDefaultLength;
private CharSequence mExpandLabel;
private volatile int mWeightCounter;
private Context mContext;
private PackageManager mPackageManager;
private Intent mIntent;
private MenuItem.OnMenuItemClickListener mOnMenuItemClickListener;
private List<String> mExtraPackages = new ArrayList<String>();
private List<String> mToRemovePackages = new ArrayList<String>();
private List<ShareTarget> mExtraTargets = new ArrayList<ShareTarget>();
private List<ShareTarget> mShareTargets = new ArrayList<ShareTarget>();
public AdvancedShareActionProvider(Context context) {
super(context);
mContext = context;
mPackageManager = context.getPackageManager();
mWeightCounter = WEIGHT_MAX;
mDefaultLength = DEFAULT_LIST_LENGTH;
mExpandLabel = mContext.getString(R.string.share_action_provider_expand_label);
}
/**
* 设置MenuItem的点击事件
*
* @param listener
*/
public void setOnMenuItemClickListener(MenuItem.OnMenuItemClickListener listener) {
mOnMenuItemClickListener = listener;
}
/**
* 添加自定义的分享目标(不会重新排序)
* 注意:必须在setShareIntent之前调用
*
* @param pkg 包名
*/
public void addCustomPackage(String pkg) {
if (!mExtraPackages.contains(pkg)) {
mExtraPackages.add(pkg);
}
}
/**
* 添加自定义的分享目标(不会重新排序)
* 注意:必须在setShareIntent之前调用
*
* @param pkgs 包名集合
*/
public void addCustomPackages(Collection<String> pkgs) {
for (String pkg : pkgs) {
addCustomPackage(pkg);
}
}
/**
* 清空自定义的分享目标
*/
public void clearCustomPackages() {
mExtraPackages.clear();
}
/**
* 从分享列表移除指定的app
* 注意:必须在setShareIntent之前调用
*
* @param pkg
*/
public void removePackage(String pkg) {
mToRemovePackages.add(pkg);
}
/**
* 添加自定义的分享目标t
* 注意:必须在setShareIntent之前调用
*
* @param target
*/
public void addShareTarget(ShareTarget target) {
target.weight = --mWeightCounter;
mExtraTargets.add(target);
}
/**
* 设置默认显示的分享目标数量
*
* @param length 数量
*/
public void setDefaultLength(int length) {
mDefaultLength = length;
}
public int getDefaultLength() {
return mDefaultLength;
}
public void setExpandLabel(CharSequence label) {
mExpandLabel = label;
}
/**
* 设置分享Intent
* 设置Intent会同时重新加载分享目标列表
*
* @param intent Intent
*/
public void setShareIntent(Intent intent) {
mIntent = intent;
reloadActivities();
}
/**
* 设置Intent Extras
* 注意:必须在setShareIntent之后调用
*
* @param extras Bundle
*/
public void setIntentExtras(Bundle extras) {
mIntent.replaceExtras(extras);
}
/**
* 添加额外的参数到Intent
* 注意:必须在setShareIntent之后调用
*
* @param extras Bundle
*/
public void addIntentExtras(Bundle extras) {
mIntent.putExtras(extras);
}
/**
* 添加额外的参数到Intent
* 注意:必须在setShareIntent之后调用
*
* @param subject Intent.EXTRA_SUBJECT
* @param text Intent.EXTRA_TEXT
*/
public void setIntentExtras(String subject, String text) {
setIntentExtras(subject, text, null);
}
/**
* 添加额外的参数到Intent
* 注意:必须在setShareIntent之后调用
*
* @param imageUri Intent.EXTRA_STREAM
*/
public void setIntentExtras(Uri imageUri) {
setIntentExtras(null, null, imageUri);
}
/**
* 添加额外的参数到Intent
* 注意:必须在setShareIntent之后调用
*
* @param subject Intent.EXTRA_SUBJECT
* @param text Intent.EXTRA_TEXT
* @param imageUri Intent.EXTRA_STREAM
*/
public void setIntentExtras(String subject, String text, Uri imageUri) {
if (DEBUG) {
Log.v(TAG, "setIntentExtras() subject=" + subject);
Log.v(TAG, "setIntentExtras() text=" + text);
Log.v(TAG, "setIntentExtras() imageUri=" + imageUri);
}
mIntent.putExtra(Intent.EXTRA_SUBJECT, subject);
mIntent.putExtra(Intent.EXTRA_TEXT, text);
if (imageUri != null) {
mIntent.putExtra(Intent.EXTRA_STREAM, imageUri);
}
}
public List<ShareTarget> getShareTargets() {
return mShareTargets;
}
public List<ShareTarget> getDefaultShareTargets() {
int length = Math.min(mDefaultLength, mShareTargets.size());
return mShareTargets.subList(0, length);
}
/**
* 重新加载目标Activity列表
*/
private void reloadActivities() {
loadShareTargets();
sortShareTargets();
}
private void loadShareTargets() {
if (mIntent != null) {
mShareTargets.clear();
List<ResolveInfo> activities =
mPackageManager.queryIntentActivities(mIntent, PackageManager.MATCH_DEFAULT_ONLY);
if (activities == null || activities.isEmpty()) {
return;
}
for (ResolveInfo resolveInfo : activities) {
ShareTarget target = toShareTarget(resolveInfo);
mShareTargets.add(target);
}
}
}
private void sortShareTargets() {
if (mShareTargets.size() > 0) {
if (DEBUG) {
Log.v(TAG, "sortShareTargets() mShareTargets size=" + mShareTargets.size());
Log.v(TAG, "sortShareTargets() mExtraPackages size=" + mExtraPackages.size());
}
for (String pkg : mExtraPackages) {
ShareTarget target = findShareTarget(pkg);
if (target != null) {
target.weight = --mWeightCounter;
}
}
for (String pkg : mToRemovePackages) {
ShareTarget target = findShareTarget(pkg);
if (target != null) {
mShareTargets.remove(target);
}
}
mShareTargets.addAll(mExtraTargets);
Collections.sort(mShareTargets);
mExtraTargets.clear();
mExtraPackages.clear();
mToRemovePackages.clear();
final int size = mShareTargets.size();
for (int i = 0; i < size; i++) {
mShareTargets.get(i).id = i;
}
}
}
/**
* 根据报名查找某个ShareTarget
*
* @param pkg 包名
* @return index
*/
private ShareTarget findShareTarget(String pkg) {
for (ShareTarget target : mShareTargets) {
if (pkg.equals(target.packageName)) {
return target;
}
}
return null;
}
/**
* 根据ResolveInfo生成ShareTarget
*
* @param resolveInfo ResolveInfo
* @return ShareTarget
*/
private ShareTarget toShareTarget(ResolveInfo resolveInfo) {
if (resolveInfo == null || resolveInfo.activityInfo == null) {
return null;
}
ActivityInfo info = resolveInfo.activityInfo;
ShareTarget target = new ShareTarget(info.loadLabel(mPackageManager), info.loadIcon(mPackageManager), null);
target.packageName = info.packageName;
target.className = info.name;
return target;
}
@Override
public View onCreateActionView() {
return null;
}
@Override
public boolean hasSubMenu() {
return true;
}
/**
* 根据Activity列表生成PopupMenu
*
* @param subMenu SubMenu that will be displayed
*/
@Override
public void onPrepareSubMenu(SubMenu subMenu) {
subMenu.clear();
if (DEBUG) {
Log.v(TAG, "onPrepareSubMenu() mDefaultLength=" + mDefaultLength + " mShareTargets.size()=" + mShareTargets.size());
}
int length = Math.min(mDefaultLength, mShareTargets.size());
Resources res = mContext.getResources();
for (int i = 0; i < length; i++) {
ShareTarget target = mShareTargets.get(i);
subMenu.add(0, i, i, target.title).setIcon(target.icon).setOnMenuItemClickListener(this);
}
if (mDefaultLength < mShareTargets.size()) {
subMenu = subMenu.addSubMenu(Menu.NONE, mDefaultLength, mDefaultLength, mExpandLabel);
for (int i = 0; i < mShareTargets.size(); i++) {
ShareTarget target = mShareTargets.get(i);
subMenu.add(0, i, i, target.title).setIcon(target.icon).setOnMenuItemClickListener(this);
}
}
}
/**
* 按顺序处理,如果某一阶段返回true,忽略后续的处理
*
* @param item
* @return
*/
@Override
public boolean onMenuItemClick(MenuItem item) {
boolean handled = false;
ShareTarget target = mShareTargets.get(item.getItemId());
// 首先响应target自带的listener
if (target.listener != null) {
handled = target.listener.onMenuItemClick(item);
}
if (handled) {
return true;
}
// 其次响应外部设置的listener
if (mOnMenuItemClickListener != null) {
handled = mOnMenuItemClickListener.onMenuItemClick(item);
}
if (handled) {
return true;
}
if (target.packageName == null || target.className == null) {
return true;
}
// 最后响应默认的intent
ComponentName chosenName = new ComponentName(
target.packageName,
target.className);
Intent intent = new Intent(mIntent);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setComponent(chosenName);
if (DEBUG) {
Log.v(TAG, "onMenuItemClick() target=" + chosenName);
}
try {
mContext.startActivity(intent);
} catch (Exception e) {
Log.e(TAG, "onMenuItemClick() error: " + e);
Toast.makeText(mContext, R.string.share_action_provider_target_not_found, Toast.LENGTH_SHORT).show();
}
return true;
}
}