5

我有一定的意图 ( NDEF_DISCOVERED),其中一些我无法正确处理,所以我想将它们重定向到 android 的默认 nfc 处理程序。

所以我采取了意图,setComponent(null)然后startActivity(intent)

但是..它总是以无限循环的意图抛出回到我的应用程序。

有没有办法可以向除我的应用程序之外的任何人发送意图?还是将其发送到android的默认nfc处理程序?

编辑:所以我使用 vikram 的答案来查询 packagemanager 可能的活动来处理我的意图,然后循环并找到具有最高优先级的活动(不是我)并向他们发送明确的意图。

4

2 回答 2

5

在这种情况下,自定义选择器对话框/弹出窗口对您来说会更好。不要启动意图,而是使用PackageManagerto queryIntentActivities(Intent, int)。从返回的List<ResolveInfo>内容中queryIntentActivities(Intent, int),使用以下内容过滤掉您自己的应用程序packageName

String packageName = "";
for(ResolveInfo resInfo : resolvedInfoList) {

    packageName = resInfo.activityInfo.applicationInfo.packageName;

    // Exclude `packageName` from the dialog/popup that you show

}

编辑 1

以下代码将创建并显示一个PopupWindow无论何时showList()被调用。用于返回的 xml 布局文件只popupView包含一个LinearLayout(R.layout.some_popup_view):

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:id="@+id/llPopup"
    android:orientation="vertical" >

</LinearLayout>

这段代码只是一个简单的演示。为了使它接近可用,您可能需要添加一个ListView带有自定义适配器的 this PopupWindow。在OnClickListenerfor 中ListView,您将检索用户单击的应用程序的包名称,并生成启动该活动的意图。截至目前,代码仅显示如何使用自定义选择器过滤掉您自己的应用程序。在if块中,替换"com.example.my.package.name"为您的应用程序包名称。

public void showList() { 

    View popupView = getLayoutInflater().inflate(R.layout.some_popup_view, null);

    PopupWindow popupWindow = new PopupWindow(popupView, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);

    LinearLayout llPopup = (LinearLayout) popupView.findViewById(R.id.llPopup);

    PackageManager pm = getPackageManager();

    Intent intent = new Intent();

    // In my case, NfcAdapter.ACTION_NDEF_DISCOVERED was not returning anything
    //intent.setAction(NfcAdapter.ACTION_NDEF_DISCOVERED);
    intent.setAction(NfcAdapter.ACTION_TECH_DISCOVERED);

    List<ResolveInfo> resolvedInfoList = pm.queryIntentActivities(intent, 0);

    String packageName = "";

    for(ResolveInfo resInfo : resolvedInfoList) {

        packageName = resInfo.activityInfo.applicationInfo.packageName;

        // Exclude `packageName` from the dialog/popup that you show
        if (!packageName.equals("com.example.my.package.name")) {

            TextView tv = new TextView(this);

            tv.setText(packageName);

            llPopup.addView(tv);
        }            

    }

    popupWindow.showAtLocation(popupView, Gravity.CENTER, 0, 0);
}
于 2013-07-25T18:38:23.507 回答
1

除了在这里做一个自己的选择器之外,还有另一种选择(不同的选择器可能会让用户感到困惑)

public void rethrowIntentExcludingSelf() {
    final ComponentName component = new ComponentName(this, getClass());
    this.getPackageManager().setComponentEnabledSetting(component, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);

    final Intent intent = this.getIntent();
    intent.setComponent(null);
    this.startActivity(intent);
    new android.os.Handler().postDelayed(
            new Runnable() {
                @Override
                public void run() {
                    getPackageManager().setComponentEnabledSetting(component, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
                }
            },250);
}

我正在使用它——它工作得很好——只是不喜欢这个神奇的常数 250——但还没有看到其他方法。

于 2014-08-21T10:21:16.087 回答