Перечислите интенции действий и начните при необходимости - PullRequest
2 голосов
/ 16 декабря 2011

Я хотел бы создать какой-то пользовательский «выбор намерений», такой как Intent.createChooser (намерение).вещь.

Поэтому мне нужно сначала перечислить все действия, которые соответствуют заданному намерению, которое предоставляет дополнительные данные, такие как EXTRA_TEXT или EXTRA_STREAM.См. Комментарий в коде для актуальной проблемы.В основном это 1) Возвращенные намерения часто перечисляются, но имеют значение null (не используется). 2) Данные переданного намерения (конструктора) не принимаются, поэтому новое намерение запускается без каких-либо дополнительных / флагов / и т.д.*

public class IntentChooserDialog extends Dialog implements OnItemClickListener {

    private ListView mListView;
    private ResolveInfo[] mResolveInfos;
    private Bundle mIntentBundle;
    private Activity mActivity;

    public IntentChooserDialog(Activity activity, Intent intent, int theme) {
        super(activity, theme);
        setContentView(R.layout.dlg_intentchooser);

        mIntentBundle = intent.getExtras();
        mActivity = activity;

        mListView = (ListView) findViewById(R.id.dlg_intentchooser_list);
        mListView.setOnItemClickListener(this);

        enumerateApps(activity, intent);

    }

    private void enumerateApps(Context context, Intent intent) {
        final PackageManager packageManager = context.getPackageManager();
        final List<ResolveInfo> entries = packageManager.queryIntentActivities(intent, 0);
        mResolveInfos = entries.toArray(new ResolveInfo[] {});

        ArrayList<String> appNames = new ArrayList<String>(entries.size());

        final int entriesSize = entries.size();
        for (int i = 0; i < entriesSize; ++i) {
            // We only add an item if it's executable
            final Intent launchIntent = packageManager.getLaunchIntentForPackage(mResolveInfos[i].activityInfo.packageName);
            if (launchIntent != null) {
                final String appName = mResolveInfos[i].activityInfo.applicationInfo.loadLabel(packageManager).toString();
                appNames.add(appName);
            }
        }

        final ArrayAdapter<String> adapter = new ArrayAdapter<String>(context, R.layout.dlg_intentchooser_list_item, appNames);
        mListView.setAdapter(adapter);
    }
rride
    public void onItemClick(AdapterView<?> adapter, View view, int position, long id) {
        final PackageManager packageManager = getContext().getPackageManager();
        final Intent intent = packageManager.getLaunchIntentForPackage(mResolveInfos[position].activityInfo.packageName);

        // intent often is still null! -> NullPointerException; but why, Im testing it when adding them into the mResolveInfo
                // I need to provide ALL information passed to the intent we get in the constructor. So things like "addFlags" and "setType" etc. must be passed too somehow!
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.putExtras(mIntentBundle); // extras are not added, as the intents are opened as if no extras were added. The "foreign" apps are just opened as if I opened them in the Launcher.

        getContext().startActivity(intent);

    }

}

В конструкторе, переданном в Intent, используется любое другое намерение, переданное Intent.createChooser, например:

Intent shareIntent = new Intent(Intent.ACTION_SEND);
        shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        shareIntent.setType("text/plain");
        shareIntent.putExtra(Intent.EXTRA_SUBJECT, mActivity.getString(R.string.action_openin_extraSubject));
        shareIntent.putExtra(Intent.EXTRA_TEXT, mActivity.getString(R.string.action_openin_extraText));
        shareIntent.setType("image/*");
        shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://" + fileName));

 new IntentChooserDialog(this, shareIntent, 0).show();
...