【问题标题】:how to use queryIntentActivityOptions() method如何使用 queryIntentActivityOptions() 方法
【发布时间】:2015-12-15 08:28:26
【问题描述】:

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

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));
    }
}

【问题讨论】:

  • 您的代码运行良好。
  • @tinysunlight 我有问题理解queryIntentActivityOptions()。特别是第二和第三个参数。你明白吗?

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


【解决方案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

【讨论】:

    【解决方案2】:
    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);
    

    【讨论】:

    • 你能详细说明一下这个@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().
    • 我认为@return 更重要。
    【解决方案3】:

    首先,你需要对PackageManager类的queryIntentActivityOptions()方法有一个很好的理解。

    QueryIntentActivityOptions(ComponentName 调用者,Intent[] 细节,Intent 意图,int 标志)

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

    • 细节 - 这是您希望首先解决的一系列意图。对于您的情况,您可以放置​​您拥有的两个意图中的任何一个。即photoPickerIntenttakePictureIntent 这样

      new Intent[] {takePicture}

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

    • intent - 在这里放置您想要的意图。即在您拥有的两个意图之间,您决定不将其放入数组中,因为您认为它是最重要的一个

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

    • flags - 这就像一个过滤器或您希望被包含在此方法返回的任何已解决活动中的过滤器或附加功能。

      • 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));
    }
    }
    

    【讨论】:

      猜你喜欢
      • 2016-03-21
      • 2019-04-07
      • 2013-09-19
      • 2012-03-10
      • 2012-08-31
      • 2019-08-17
      • 1970-01-01
      • 2019-09-08
      • 2020-11-21
      相关资源
      最近更新 更多