How to pass Android intent to anyone but my own ap

2019-02-13 21:47发布

I have a certain intent (NDEF_DISCOVERED), some of which I cannot handle correctly, so I want to redirect those to android's default nfc handler.

So i take the intent, setComponent(null), and then startActivity(intent)

But.. it always comes back to my app in an infinite loop of intent throwing.

Is there a way I can send off an intent to anyone but my app? Or send it to android's default nfc handler?

EDIT: So I used vikram's answer to query the packagemanager for possible activities to handle my intent, then looped thru and found the activity with the highest priority (who isn't me) and sent an explicit intent to them.

2条回答
你好瞎i
2楼-- · 2019-02-13 22:15

there is also another option than to do a own chooser here ( different looking chooser might confuse the user )

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

I am using it - and it works fine - just do not like this magic constant 250 - but do not yet see another way.

查看更多
霸刀☆藐视天下
3楼-- · 2019-02-13 22:21

A custom chooser dialog/popup will be better for you in this case. Instead of launching an intent, use the PackageManager to queryIntentActivities(Intent, int). From the List<ResolveInfo> that queryIntentActivities(Intent, int) returns, filter out your own app using the packageName:

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

    packageName = resInfo.activityInfo.applicationInfo.packageName;

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

}

Edit 1:

The following code will create and show a PopupWindow whenever showList() is called. The xml layout file used to return popupView contains nothing but a 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>

This code is just a simple demonstration. For it to be anything close to usable, you will probably need to add a ListView with a custom adapter to this PopupWindow. In the OnClickListener for the ListView, you will retrieve the package name of the Application that the user clicks on, and generate an intent to start that activity. As of now, the code only displays how to filter out your own application using a custom chooser. In the if block, replace "com.example.my.package.name" with your app's 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);
}
查看更多
登录 后发表回答