I'm working on an activity which other 3rd parties want to use in their own apps, via intents.
Right now this activity is catching urls via an intent filter, like this:
<activity android:name=".MyActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW"></action>
<category android:name="android.intent.category.DEFAULT"></category>
<category android:name="android.intent.category.BROWSABLE"></category>
<data android:host="www.mysite.com" android:pathPrefix="/test/" android:scheme="http"></data>
</intent-filter>
</activity>
The above works, whenever a user clicks a link in my app like:
"mysite.com/test/blah.html"
my app comes up as a choice, along with the browser, to open the link.
Now if a third party wants to use my app, I think they can use the above like this:
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://mysite.com/test/somedata"));
startActivity(intent);
While this would work, this probably won't give them the desired effect of jumping directly to my activity from theirs - the android chooser dialog will appear, asking if they want to open the intent data with the browser, or my app.
How can I let 3rd parties call my activity directly without broadcasting the intent like this? I'd like to make them still pass the same exact data scheme to me, but just let them open my activity directly.
Thank you
You would most likely need for them to call your activity directly
Class yourClass = Class.forName("com.yourdomain.yourapp.YourClass");
Intent intent = new Intent(this, yourClass);
If they don't have a jar to link against. Otherwise, they could just use
Intent intent = new Intent(this, YourClass.class);
And then put some extras in there. The whole concept of the browsable intent (along with the others) is to provide users with a choice of how they would like to view/use something. This is similar to what happens when you click "share" from the media viewer. The whole concept is to give them choice. If somebody wants to just start your activity, they will need to explicitly call it.
Edit: My reflection example above won't directly work unless the Dalvik class loader knows about your class (which it probably won't). You will actually need to specifically tell the VM to load a class from a foreign package. You can do that with the following code
Context foreignContext = createPackageContext("com.yourdomain.yourapp", Context.CONTEXT_IGNORE_SECURITY | Context.CONTEXT_INCLUDE_CODE);
Class<?> yourClass = foreignContext.getClassLoader().loadClass("com.yourdomain.yourapp.YourClass");
Now that they have the class object, they can then fire the intent like before. So the complete code is something like
Context foreignContext = createPackageContext("com.yourdomain.yourapp", Context.CONTEXT_IGNORE_SECURITY | Context.CONTEXT_INCLUDE_CODE);
Class<?> yourClass = foreignContext.getClassLoader().loadClass("com.yourdomain.yourapp.YourClass");
Intent intent = new Intent(this, yourClass);
startActivity(intent);
The solution described above by Chris Thompson didn't work for me. This one did: Android: Starting An Activity For A Different Third Party App
Just in case anyone runs into the same problem as I did.
Related
Ok lets say there are 3 different applications which are using zxing lib on the phone. Whenever I want to open zxing with my own application android asks me whether to complete action using app 1 or app 2 or my own app. How do I force it to run only through my app without any dialog? Is there any chance to do it?
EDIT
In Additional to CommonsWare, you can do that if you want to handle barcode result on the
other activity.
step 1: jump to method called handleDecode in Capture Activity. Add these lines after handleDecodeInternally(rawResult, resultHandler, barcode);
Intent intent = new Intent(getIntent().getAction());
intent.putExtra("SCAN_RESULT", rawResult.getText());
setResult(RESULT_OK,intent);
finish();
step 2: Do whatever want to do on the other activity's onActivityResult event.
PS: Thanks again to CommonsWare.
First, there is no "zxing lib". You are supposed to use the Barcode Scanner application, tying it into your application at the activity level, ideally using their IntentIntegrator code. Here is a sample application demonstrating this. The creators of ZXing specifically do not support or endorse baking the Barcode Scanner source code into another application.
However, given your symptoms, I have to assume that you are trying to add the Barcode Scanner source code to your own application.
You presumably have something like this in your manifest on the scanning activity's element:
<intent-filter >
<action android:name="com.google.zxing.client.android.SCAN" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
You are not Barcode Scanner. Yet, this <intent-filter> claims that you are Barcode Scanner.
You need to remove this <intent-filter>, modify your copy of the Barcode Scanner source code to not require it, and then start up the scanning activity using the component-based Intent constructor (e.g., new Intent(this, ThisIsYourRevisedScanningActivity.class)).
Just include this,this has done the needed for me..
Intent intent = new Intent("com.google.zxing.client.android.SCAN");
intent.setPackage(getPackageName());
intent.putExtra("SCAN_MODE", "QR_CODE_MODE");
startActivityForResult(intent, 0);
Android does not allow you to set this on your own. Only a user can set the default application for an action. If on your phone, you want your app to handle that event, then check the Use as default box before selecting your app in the picker.
For security reasons, Android does not allow you to set your app as the default without user interaction as then a malicious app could tie itself as the default to various events.
Actually you need to remove intent-filter like CommonsWare said, so it must be as follows:
<activity
android:name="com.google.zxing.client.android.CaptureActivity"
android:screenOrientation="landscape"
android:configChanges="orientation|keyboardHidden"
android:theme="#android:style/Theme.NoTitleBar.Fullscreen"
android:windowSoftInputMode="stateAlwaysHidden">
</activity>
and instead of calling via external intent you should call zxing like:
private final static int ACTION_ZXING_SCANNER = 0x0000c0de; //IntentIntegrator.REQUEST_CODE
private void startZxingScanner() {
final Intent intent = new Intent(this, com.google.zxing.client.android.CaptureActivity.class);
intent.setAction(Intents.Scan.ACTION);
startActivityForResult(intent, ACTION_ZXING_SCANNER);
}
and then process result in onActivityResult() using request code ACTION_ZXING_SCANNER. The import string if needed:
import com.google.zxing.client.android.Intents;
note: this works for me and I added zxing project as a lib to my project so here it is - the "zxing lib" :)
I am looking to start an activity in my app using a custom action. I have found a few answers but everything I try it throws java.lang.RuntimeException saying No Activity found to handle Intent { act=com.example.foo.bar.YOUR_ACTION }.
This is the activity in my manifest file:
<activity
android:name=".FeedbackActivity" >
<intent-filter>
<action android:name="com.example.foo.bar.YOUR_ACTION" />
</intent-filter>
</activity>
And this is how I'm starting the activity:
Intent intent = new Intent("com.example.foo.bar.YOUR_ACTION");
startActivity(intent);
Any help would be greatly appreciated.
I think what you need is to add a default category to your intent-filter,
eg.
<activity
android:name=".FeedbackActivity" >
<intent-filter>
<action android:name="com.example.foo.bar.YOUR_ACTION" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
see this answer for more info.
I think you are creating your intent wrong. Try like this:
String CUSTOM_ACTION = "com.example.foo.bar.YOUR_ACTION";
//Intent i = new Intent(this, FeedBackActivity.class); // <--- You might need to do it this way.
Intent i = new Intent();
i.setAction(CUSTOM_ACTION);
startActivity(i);
Just add and intent-filter category as Default.
Implicit intent works perfectly and in many cases its better to use a implicit intent with Intent-action to call a service/Activity than using class-name.
Before startActivty() / startService() with proper context you cane use this method 'queryIntentActivities(Intent intent, int flags)' from package manager class.
It helps the ActivityManager (responsible for launching activities) to check whether the Android system is getting any match with you Intent.
If it doesn't it returns a list size 0 or else >0.
By this you can also check if your app is getting the call,and in this case even if your app is not installed / has got some problem, it will not crash but will throw a warning in Log. Users will face no big trouble apart from app not being launched.
(users will never forgive you if tour app crashes).
Hope this will help !!!
Happy Coding. :)
I faced the same problem when trying to launch the activity residing in the dynamic feature module and starting through action String as the Activity is not resolvable by name at compile time.
So I set the action but the activity crashes every time (No Activity found to handle intent bla bla.. ) until I set the correct package name.
Context c = getApplicationContext();// flag would be require Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag
Intent i = new Intent(action_string);
i.setPackage(context.getPackageName());//this did the trick actually
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
In the Manifest : add catrgory default to the intent filters
from google docs:
<category android:name="android.intent.category.DEFAULT"/>
Note: In order to receive implicit intents, you must include the CATEGORY_DEFAULT category in the intent filter. The methods startActivity() and startActivityForResult() treat all intents as if they declared the CATEGORY_DEFAULT category. If you do not declare it in your intent filter, no implicit intents will resolve to your activity.
In my application I have an option to start navigation to selected POI. Basically what I want is to launch a turn-by-turn navigator from my application. The thing is I don't know which (if any) navigator is installed.
So, the question is how to start an intent by showing a list of suitable activities for navigation to the user first, letting him choose which one he would like to use? Also would be nice to find a way to pass extra parameters to selected activity (this sounds like an issue to me, since different navigation apps use different names for their extras, I guess).
In case it's not clear: I'm looking for a way to DISPLAY A LIST OF SUITABLE APPLICATIONS FOR NAVIGATION WITH THE OPTION TO MAKE ONE DEFAULT.
EDIT: Find here the implementation http://datamoil.blogspot.com/2011/04/android-universal-intent-to-start.html
The bad news is, there isn't a standard Intent URI for navigation.
Yes, google.navigation URIs exist, and an app may choose to support it.
The best solution I can think of is to:
Explicitly check for known apps
Implicitly check for apps hooking google.navigation: and perhaps geo: (but then you also get map apps)
You can enumerate the possible implicit targets using PackageManage.queryIntentActivities
Try:
Intent intent = new Intent(Intent.ACTION_VIEW,
Uri.parse("google.navigation:q=New+York+NY"));
startActivity(intent);
First I used in my onTap method inside the button's listener:
Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse("google.navigation:q=New+York+NY"));
mContext.startActivity(i);
Then in manifest simply use:
<activity android:name=".LaunchGPS" android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
This will open any Navigator App your phone has such as VZ Navigagtor, Google or whatever the phone is loaded with. Worked for me the first time perfectly. Hope this solves your problem.
I found more advantages using this code (just for to show available navigator apps)
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("geo:"));
if (intent.resolveActivity(getActivity().getPackageManager()) != null) {
startActivityForResult(Intent.createChooser(intent, "Continues with:", CHOOSE_NAVIGATOR_ID);
} else {
// Handle failure...
}
I wanna to redirect to the Android Activity from java class..
here my code
class A {
getContext().startActivity(
new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.google.com")));
}
from the code,it's redirected to webview instead i need it to redirect it into Android Activity something like this..
getContext().startActivity(
new Intent(A.this,My.class));
IF you want to start an activity, and send and url to it, you can do something like this:
Intent myIntent = new Intent(this, YourActivityName.class);
Bundle sendInfo = new Bundle();
sendInfo.putString("YOUR.IDENTIFIER.YOURURL","http://www.google.com");
myIntent.putExtras(sendInfo);
this.startActivity(myIntent);
Now if you want to do this from outside, like your activity catching url intents, you should add an intent-filter to your manifest, so you can handle those (after you get the "which program do you want to use to open this dialog). That would look something like this:.
<activity android:name=".YourActivityName">
<intent-filter>
<action android:name="android.intent.action.VIEW"></action>
<category android:name="android.intent.category.DEFAULT"></category>
<category android:name="android.intent.category.BROWSABLE"></category>
<data android:scheme ="http"
android:host ="www.hosttofilter.tld"
android:pathPrefix="/view">
</data>
</intent-filter>
This wil open all url requests for "http://www.hosttofilter.tld" with your app
To address your question about how to start a specific Activity check out this article. It provides several examples of exactly what you want to do. The second question is where are you calling this code? Is it from an Activity class or is it from some plain old java object? Hint: the code you posted won't work from a POJO.
Maybe Extra will fit your need:
Intent myIntent = new Intent(this,myActivity.class);
myIntent.putExtra("URL","www.google.de");
startActivity(myIntent);
In myActivity you would do:
String url = getIntent().getExtras().getString("URL");
Cheers.
guys. I am trying to build a voip app for android. I want to make use of the built-in android phone dialer. Can you guys give me some reference to it. I have been googling with no luck. Thanks
What you need to do is setup an Intent filter on the Activity you want to make the call. You do this inside your AndroidManifest.xml file. Modify your activity definition to include this intent filter:
<intent-filter>
<action android:name="android.intent.action.CALL" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="tel" />
</intent-filter>
Note: there are some alternative ways to call people (which can be seeing in the AndroidManifest.xml of the source I linked bellow, however this is the main one
Adding this will give the user the option to use your app when making a call, and this can be set as the default app if the user wishes.
You can then get the phone number by adding something like this code to your onCreate() method of your activity:
final Intent i = getIntent();
final Uri phoneUri = i.getData();
phoneUri now contains tel:00000000000 and you can easily get the number out of the Uri object
If you have problems in to future take a look at the android source. I got these bits of code from the phone app source if you want to take a look.
This should open the dialer with new special permissions:
Intent i = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:0000000000"));
startActivity(i);
That should open the dialer with the required telephone number already inserted.