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.
Intent shareIntent = Intent. createChooser(sendIntent, null); startActivity(shareIntent); Optionally, you can add extras to include more information, such as email recipients ( EXTRA_EMAIL , EXTRA_CC , EXTRA_BCC ), the email subject ( EXTRA_SUBJECT ), and so on.
Using intents even allows your app to start an activity that is contained in a separate app. An Intent can be explicit in order to start a specific component (a specific Activity instance) or implicit in order to start any component that can handle the intended action (such as "capture a photo").
In android, we can lunch other applications using packing name. This example demonstrate about How to Launch an application from another application on Android. Step 1 − Create a new project in Android Studio, go to File ⇒ New Project and fill all required details to create a new project.
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);
}
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With