如何使用queryIntentActivityOptions()方法

时间:2015-12-15 08:28:26

标签: android android-intent android-camera android-gallery android-package-managers

尝试创建一个对话框,显示用户手机中的所有应用程序,可用于从存储中选择图片或使用相机拍摄图片。以下是我计划使用的两个意图。

Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
    photoPickerIntent.setType("image/*");

Intent takePicture = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

我发现在我的自定义对话框中使用可以执行上述操作的应用程序填充我的列表视图的最佳方法是使用queryIntentActivityOptions()方法但是被卡住了。

  • 我之前从未使用过它,我也不知道是否采用了正确的方法

  • 我不知道如何用queryIntentActivityOptions()方法填充我的列表视图。

  • 如何在我的自定义对话框中的列表视图中实现onItemClickListener

这是包含对话框的方法。 我已经研究过但是没有找到一个很好的教程来指导我如何实施 queryIntentActivityOptions()

private void acquirePicture(){
    Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
    photoPickerIntent.setType("image/*");

    Intent takePicture = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    startActivityForResult(photoPickerIntent, 1);

    final Dialog dialog = new Dialog(this);
    dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
    WindowManager.LayoutParams WMLP = dialog.getWindow().getAttributes();
    WMLP.gravity = Gravity.CENTER;
    dialog.getWindow().setAttributes(WMLP);
    dialog.getWindow().setBackgroundDrawable(
            new ColorDrawable(android.graphics.Color.TRANSPARENT));
    dialog.setCanceledOnTouchOutside(true);
    dialog.setContentView(R.layout.about_dialog);
    dialog.setCancelable(true);
    ListView lv=(ListView)dialog.findViewById(R.id.listView1);
    PackageManager pm=getPackageManager();

    List<ResolveInfo> launchables=pm.queryIntentActivityOptions(
this.getComponentName(),new Intent[]{photoPickerIntent,takePicture},
null,PackageManager.MATCH_DEFAULT_ONLY);

    Collections.sort(launchables,
            new ResolveInfo.DisplayNameComparator(pm));

    appAdapter=new AppAdapter(pm, launchables);

    lv.setAdapter(adapter);
    lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> arg0, View arg1, int position,
                                long arg3) {
            // TODO Auto-generated method stub
            ResolveInfo launchable=appAdapter.getItem(position);
            ActivityInfo activity=launchable.activityInfo;
            ComponentName name=new ComponentName(activity.applicationInfo.packageName,
                    activity.name);
            //I DON'T KNOW WHAT TO DO NEXT OR WHETHER AM DOING IT
             THE CORRECT WAY
        }
    });

    dialog.show();
}

class AppAdapter extends ArrayAdapter<ResolveInfo> {
    private PackageManager pm=null;

    AppAdapter(PackageManager pm, List<ResolveInfo> apps) {
        super(Custom_chooser.this, R.layout.row, apps);
        this.pm=pm;
    }

    @Override
    public View getView(int position, View convertView,
                        ViewGroup parent) {
        if (convertView==null) {
            convertView=newView(parent);
        }

        bindView(position, convertView);

        return(convertView);
    }

    private View newView(ViewGroup parent) {
        return(getLayoutInflater().inflate(R.layout.row, parent, false));
    }

    private void bindView(int position, View row) {
        TextView label=(TextView)row.findViewById(R.id.label);

        label.setText(getItem(position).loadLabel(pm));

        ImageView icon=(ImageView)row.findViewById(R.id.icon);

        icon.setImageDrawable(getItem(position).loadIcon(pm));
    }
}

3 个答案:

答案 0 :(得分:1)

检查以下工作代码打开,相机并立即浏览图库。

 // Picks Camera first.
final List<Intent> cameraIntents = new ArrayList<Intent>();
final Intent captureIntent = new Intent(
        android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
final PackageManager packageManager = getPackageManager();
final List<ResolveInfo> listCam = packageManager.queryIntentActivities(
        captureIntent, 0);
for (ResolveInfo res : listCam) {
  final String packageName = res.activityInfo.packageName;
  final Intent intent = new Intent(captureIntent);
  intent.setComponent(new ComponentName(res.activityInfo.packageName,
          res.activityInfo.name));
  intent.setPackage(packageName);
  intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
  cameraIntents.add(intent);
}

final Intent galleryIntent = new Intent();
galleryIntent.setType("image/*");
galleryIntent.setAction(Intent.ACTION_PICK);

// Chooser of filesystem options.
final Intent chooserIntent = Intent.createChooser(galleryIntent,
        "Select Image from");

// Add the camera options.
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS,
        cameraIntents.toArray(new Parcelable[]{}));

startActivityForResult(chooserIntent, TAKE_PHOTO_CODE);

这会对你有帮助。!!

参考链接和教程click here

答案 1 :(得分:0)

lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> arg0, View arg1, int position,
                                long arg3) {
            // TODO Auto-generated method stub
            ResolveInfo launchable=appAdapter.getItem(position);
                   String packageName = launchable.activityInfo.packageName;
        String className = launchable.activityInfo.name;
        Intent intent = new Intent(Intent.ACTION_MAIN);
        intent.addCategory(Intent.CATEGORY_LAUNCHER);
        ComponentName cn = new ComponentName(packageName, className);
        intent.setComponent(cn);
        startActivity(intent);
        }
    });



 /**
     * Retrieve a set of activities that should be presented to the user as
     * similar options.  This is like {@link #queryIntentActivities}, except it
     * also allows you to supply a list of more explicit Intents that you would
     * like to resolve to particular options, and takes care of returning the
     * final ResolveInfo list in a reasonable order, with no duplicates, based
     * on those inputs.
     *
     * @param caller The class name of the activity that is making the
     *               request.  This activity will never appear in the output
     *               list.  Can be null.
     * @param specifics An array of Intents that should be resolved to the
     *                  first specific results.  Can be null.
     * @param intent The desired intent as per resolveActivity().
     * @param flags Additional option flags.  The most important is
     * {@link #MATCH_DEFAULT_ONLY}, to limit the resolution to only
     * those activities that support the {@link android.content.Intent#CATEGORY_DEFAULT}.
     *
     * @return A List&lt;ResolveInfo&gt; containing one entry for each matching
     *         Activity. These are ordered first by all of the intents resolved
     *         in <var>specifics</var> and then any additional activities that
     *         can handle <var>intent</var> but did not get included by one of
     *         the <var>specifics</var> intents.  If there are no matching
     *         activities, an empty list is returned.
     *
     * @see #MATCH_DEFAULT_ONLY
     * @see #GET_INTENT_FILTERS
     * @see #GET_RESOLVED_FILTER
     */
    public abstract List<ResolveInfo> queryIntentActivityOptions(
            ComponentName caller, Intent[] specifics, Intent intent, int flags);

答案 2 :(得分:0)

首先,您需要很好地理解类PackageManager的queryIntentActivityOptions()方法。

QueryIntentActivityOptions (ComponentName caller,Intent [] specifics,Intent intent,int flags)

  • 来电者 - 这是您当前正在调用此方法的类的名称。 通常我们使用 this.getComponentName作为此参数的值。

  • 细节 - 这是您想要首先解析的意图数组。对于你的情况,你可以把你拥有的两个意图中的任何一个。即photoPickerIntenttakePictureIntent 就像这样

    new Intent[] {takePicture}

    注意:如果您只有一个意图,则此参数值可以为null。在这种情况下,我认为使用QueryIntentActivities会更好。但对于您的情况,由于您有多个意图,请继续使用此方法。

  • 意图 - 在此您可以放置​​所需的意图。即你所拥有的两个意图之间的,你决定不放入数组的那个意图,因为你是最重要的意图

    注意:此参数值不能为空。将null值抛出将抛出NullPointerException!

  • 标记 - 这类似于您希望在此方法返回的任何已解析活动中包含的过滤器或附加内容。

    • PackageManager.MATCH_DEFAULT_ONLY - 设置此选项将过滤已解决的活动并选择属于设备中默认应用程序的活动。如果ACTION_IMAGE_CAPTURE可由两个人解决应用程序,一个是默认应用程序,另一个是第三方应用程序,例如您下载了它,将默认选择一个

    • PackageManager.GET_INTENT_FILTERS - 此选项返回有关已解析的应用可以处理的所有意图过滤器的信息。例如,您可以拥有一个解决了ACTION_IMAGE_CAPTURE的应用,但它也可以解析ACTION_PICK

    • PackageManager.GET_RESOLVED_FILTER - 此选项返回列表中每个应用已解析的意图过滤器

工作示例

Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);

Intent takePicture = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

photoPickerIntent.setType("image/*");

PackageManager pm=getPackageManager();


List<ResolveInfo> launchables=pm.queryIntentActivityOptions(
 this.getComponentName(),new Intent[]{takePicture},
 photoPickerIntent,PackageManager.GET_RESOLVED_FILTER);

  Collections.sort(launchables,
    new ResolveInfo.DisplayNameComparator(pm));

然后,您可以使用上面的lauchaubles列表填充您的列表视图

 ListView lv=(ListView)dialog.findViewById(R.id.listView1);

 AppAdapter appAdapter=new AppAdapter(pm, launchables);

 lv.setAdapter(adapter);
 lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
 @Override
 public void onItemClick(AdapterView<?> arg0, View arg1, int position,
                        long arg3) {
    // TODO Auto-generated method stub
    ResolveInfo launchable=appAdapter.getItem(position);
    ActivityInfo activity=launchable.activityInfo;
    ComponentName name=new ComponentName(activity.applicationInfo.packageName,
            activity.name);

 IntentFilter filter = launchable.filter;
        if(filter.actionsIterator() != null){
            Iterator<String > actions = filter.actionsIterator();
        }

        int actioncode;
        Intent  intent = new Intent();
        Uri uri;
        if(filter.hasAction(Intent.ACTION_PICK)){
            actioncode = 1;
            uri = android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
            intent.setData(uri);
        }else{
            actioncode = 0;
        }
        intent.setComponent(name);
        startActivityForResult(intent,actioncode);

}
});

 }

class AppAdapter extends ArrayAdapter<ResolveInfo> {

private PackageManager pm=null;

AppAdapter(PackageManager pm, List<ResolveInfo> apps) {
super(Custom_chooser.this, R.layout.row, apps);
this.pm=pm;
}

 @Override
public View getView(int position, View convertView,
                ViewGroup parent) {
if (convertView==null) {
    convertView=newView(parent);
}

bindView(position, convertView);

return(convertView);
}

private View newView(ViewGroup parent) {
return(getLayoutInflater().inflate(R.layout.row, parent, false));
}

private void bindView(int position, View row) {
TextView label=(TextView)row.findViewById(R.id.label);

label.setText(getItem(position).loadLabel(pm));

ImageView icon=(ImageView)row.findViewById(R.id.icon);

icon.setImageDrawable(getItem(position).loadIcon(pm));
}
}