In my application I've got a WebView which might be used to display www.youtube.com or m.youtube.com content. I've got the following code in the onLoadResource callback:
#Override
public void onLoadResource (WebView view, String url)
{
if(matchYouTubeWatchUrl(url))
{
invokeYouTubePlayer(m_context,url);
}
}
The invokeYouTubePlayer function looks like this:
private static void invokeYouTubePlayer(Context c, String url)
{
try
{
Uri uri = Uri.parse(url);
String videoId = uri.getQueryParameter("v");
if(videoId != null)
{
Intent youtubeIntent = new Intent(Intent.ACTION_VIEW);
youtubeIntent.setData(Uri.parse("vnd.youtube://"+videoId));
try
{
c.startActivity(youtubeIntent);
}
catch(ActivityNotFoundException e)
{
Log.e(TAG,"No handler for native youtube - expanding scope");
// Try an alternate approach if there's no youtube app installed
youtubeIntent = new Intent(Intent.ACTION_VIEW);
youtubeIntent.setData(Uri.parse("http://www.youtube.com/watch?v="+videoId));
try
{
c.startActivity(youtubeIntent);
}
catch(ActivityNotFoundException e2)
{
e2.printStackTrace();
}
}
}
}
catch(NullPointerException e)
{
e.printStackTrace();
}
}
What I'm finding is that on most Android devices the first startActivity call invokes the YouTube application, however on KF what I'm seeing is that it invokes the browser which then invokes a video player application.
Not having a KF myself what I'd like to find out is whether there's a URI that can be passed to startActivity which will directly invoke the video player on Kindle Fire without having to pass through the browser as an intermediate step.
Just a observation. There is a better way to detect if a Intent can be called
private boolean isCallable(Intent intent) {
List<ResolveInfo> list = getPackageManager().queryIntentActivities(intent,
PackageManager.MATCH_DEFAULT_ONLY);
return list.size() > 0;
}
Ok just to be clear on KF it never fires first activity then it fires second and then KF takes over and takes you to the YouTube app.
If so all i can think is that your details in first Intent is not correct or for KF its not the same as in other phones/tab
Related
I HAVE ALREADY TRIED How to handle intent:// on a webView URL?
This solution just opens up a Google Play Store Web Page in my WebView, what I want is on the click, another app should open whose intent is provided as happens in Chrome.
My app has a WebView that works fine. At one stage, the WebView requests access to the following(an external payment app):
intent://pay/?pa=digitalshowroom1.payu#indus&pn=DOTPE%20PRIVATE%20LIMITED&tr=13261664955&tid=CX0FOrvSrHzDh7gP&am=1.00&cu=INR&tn=OrderId-CX0FOrvSrHzDh7gP
When I use the same website that my WebView is using in Chrome, it opens the external payment app successfully, i.e. Chrome is able to handle that intent, how can my app handle the same intent.
I seem to know I have to use
public boolean shouldOverrideUrlLoading(WebView view, String url)
for this, and I'm using it as follows:
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (url != null && (url.startsWith("whatsapp://") || url.startsWith("tel") || url.startsWith("market"))) {
view.getContext().startActivity(
new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
return true;
}
else {
return false;
}
Now, this piece of code is handling the intents like opening WhatsApp, Calling app, etc. fine as they start with whatsapp or tel, so I'm able to leverage the url.startsWith() method.
How can I handle the links that request access to external apps and start with intent://?
Thanks in advance!
I tried something similar and found you have to build the URI like this and handle all URL parameters and call the build method. I did it for a UPI payments app. Call this method in shouldOverrideUrlLoading().
public void openPaymentApp(final String url)
{
try {
String pa= url.substring(url.indexOf("pa=")+3,url.indexOf("&pn"));
String pn=url.substring(url.indexOf("pn=")+3,url.indexOf("&tr"));
String tr=url.substring(url.indexOf("tr=")+3,url.indexOf("&tid"));
String tid=url.substring(url.indexOf("tid=")+4,url.indexOf("&am"));
String am=url.substring(url.indexOf("am=")+3,url.indexOf("&cu"));
String cu=url.substring(url.indexOf("cu=")+3,url.indexOf("&tn"));
String tn=url.substring(url.indexOf("tn=")+3,url.indexOf("#Intent"));
Uri uri =
new Uri.Builder()
.scheme("upi")
.authority("pay")
.appendQueryParameter("pa",pa)
.appendQueryParameter("pn",pn)
.appendQueryParameter("tr",tr)
.appendQueryParameter("tid",tid)
.appendQueryParameter("am",am)
.appendQueryParameter("cu",cu)
.appendQueryParameter("tn",tn)
.build();
Intent launchIntent = getPackageManager()
.getLaunchIntentForPackage( "com.package.name");
launchIntent.setData(uri);
startActivity( launchIntent );
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(),"Coudln't open", Toast.LENGTH_SHORT).show();
}
}
Use below code:
Uri uri = Uri.parse(url);
if (uri.getScheme().equals("intent")) {
String appPackage = getAppPackageFromUri(uri);
if (appPackage != null) {
PackageManager manager = getContext().getPackageManager();
Intent appIntent = manager.getLaunchIntentForPackage(appPackage);
if (appIntent != null) {
getActivity().startActivity(appIntent);
} else {
// open external website
}
}
}
Please use code if any issue let me know
Happy coding!
I want to know if it is possible to open my s health application (of my android smartphone), from another my application (android) that I'm building now.
But I want besides open the app, also set some data to this app, for example I want to set the aims, or any data. It is possible to do this?
It is possible to do this?
Yes!!
If you know the package name of the other app, here is an example which is tested and working!!!!!
(This demonstrates how to send a simple String value,modify params as you want )
openApp(yourActivity.this,"other.app.package.name","Hey I am coming catch me");
`
public static boolean openApp(Context context, String packageName,String dataNeedToPass) {
PackageManager manager = context.getPackageManager();
try {
Intent i = manager.getLaunchIntentForPackage(packageName);
if (i == null) {
return false;
//pkg Name Not Found
}
i.addCategory(Intent.CATEGORY_LAUNCHER);
i.putExtra("KEY", dataNeedToPass);
context.startActivity(i);
return true;
} catch (Exception e) {
return false;
}
}
and in the launcher activity of the other side/app get the bundle
Bundle bundle = getIntent().getExtras();
if(bundle !=null){
String myString = bundle.getString("KEY");
}
p.s : If you want to send data make sure also the other app is modified and ready to catch!
I have a new app and I'm trying to implement it to "Call to Action" facebook page button, but I have no idea what I shall write in the "App link" text box.
They put an example link of: example://location/123456
But I have no idea what it's refering to or what's the App Link of my app.
Tried to find anything about it on the Internet but couldn't find any helpful solution since I have no app links in my app (no products etc)
My goal is that when the user clicks on Facebook "Use App", it will redirect him to the app or the google play store app page if it's not installed..
I'm not talking about open app in my app, im talking about open my app in my facebook page
You can use the next code from the wiki:
/** Open another app.
* #param context current Context, like Activity, App, or Service
* #param packageName the full package name of the app to open
* #return true if likely successful, false if unsuccessful
*/
public static boolean openApp(Context context, String packageName) {
PackageManager manager = context.getPackageManager();
try {
Intent i = manager.getLaunchIntentForPackage(packageName);
if (i == null) {
return false;
//throw new PackageManager.NameNotFoundException();
}
i.addCategory(Intent.CATEGORY_LAUNCHER);
context.startActivity(i);
return true;
} catch (PackageManager.NameNotFoundException e) {
return false;
}
}
Example usage:
openApp(this, "com.google.android.maps.mytracks");
You can read it from here
To post a message in FB, see the next post, maybe it will be useful How to open the Facebook Write Post with some pre defined text and image
You should use Try/Catch. if user have Facebook app, fb://page/12345 link will open in app. Else, Catch code will run.
#Override
public void onClick(View v) {
try {
startActivity(new Intent(Intent.ACTION_VIEW, Uri
.parse("fb://page/12345"))); //12345 is Facebook page number
} catch (Exception e) {
//open play link in browser
startActivity(new Intent(Intent.ACTION_VIEW, Uri
.parse("http://play.google.com/etc")));
}
}
I've been developing hybrid apps for many companies with mobile websites.
And as a matter of fact, there are some websites made with using jsp.
I already had the knowledge that iframes and javascripts xhr requests will not fire webViewClient's shouldOverrideUrlLoading override function. I'm fine with that.
But today I learned that SOME actions such as:
JSP Page Redirects
Link Clicks within a JSP page
JSP/JS induced URL Loads
will not ALWAYS fire this function.
Hence, shouldOverrideUrlLoading() does not fire, when the webView is asked to load a page that it cannot load(i.e. "intent://...",) it shows an error page.
Has anyone encountered this kind of behaviour and is there any solution to work around it ?
Below is the code I'm using to invoke activities, where urls with 'intent:' protocol (which will fail because this function never gets called when above actions are performed)
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// ... omitted ...
if ( url.startsWith("intent:") ) {
Intent intent = null;
try {
intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME);
// The following flags launch the app outside the current app
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
try {
getActivity().startActivity(intent);
} catch (ActivityNotFoundException e) {
e.printStackTrace();
}
} catch (URISyntaxException e) {
e.printStackTrace();
}
return true;
}
}
ps. please notice that every other websites' page loads will perfectly call shouldOverrideUrlLoading().
I couldn't find any JSP related bugs on android webViews so I'm asking one.
ps. I am happily willing to provide sample websites that some gracious readers will try on.. but the website's written in Korean so I doubt it will help.
Thank you!
Your problem might not related to JSP, the real problem may be shouldOverrideUrlLoading() itself. In this case, using shouldOverrideUrlLoading() may not be a good idea, so why not try another perspective?
I've encountered many problems when using
shouldOverrideUrlLoading() loading XmlHttpRequest. At the end, I
came up with the idea using onProgressChanged() and it solved all
my problems. I've written a similar answer here.
I tried adding your code into my own webview project and tested it with some JSP sites, and looks like it always work. I also added loadUrl() after other activities are invoked, so after pressing the back button, the loading error page will not be displayed again. So try this one :
First declare a global variable to store last URL.
String strLastUrl = null;
Then override onProgressChanged(WebView view, int progress)
mWebView.setWebChromeClient(new MyWebChromeClient(){
#Override
public void onProgressChanged(WebView view, int progress) {
if (progress == 100) {
//A fully loaded url will come here
String StrNewUrl = view.getUrl();
if(TextUtils.equals(StrNewUrl,strLastUrl)){
//same page was reloaded, not doing anything
}else{
String strOldUrl = null;
//save old url to variable strOldUrl before overwriting it
strOldURL = strLastUrl;
//a new page was loaded,overwrite this new url to variable
strLastUrl = StrNewUrl;
if ( strLastUrl.startsWith("intent:") ) {
Log.d("TAG", "intent triggered");
Intent intent = null;
try {
intent = Intent.parseUri(strLastUrl, Intent.URI_INTENT_SCHEME);
// The following flags launch the app outside the current app
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
try {
startActivity(intent);
} catch (ActivityNotFoundException e) {
e.printStackTrace();
}
//reload the page before invoking other activities
view.loadUrl(strOldURL);
} catch (URISyntaxException e) {
e.printStackTrace();
}
}
}
}
super.onProgressChanged(view, progress);
}
});
Okay so I am creating a twitter clone, the only problem I am having right now is that the callback URL is getting me back to the app but instead giving me a page not found error.
I saw some similar questions here in stackoverflow and followed the steps.
I am getting the Authentication URL using the code:
public String beginAuthorization(){
try{
if(null==currentRequestToken){
currentRequestToken = twitter.getOAuthRequestToken(TWITTER_CALLBACK_URL);
}
return currentRequestToken.getAuthenticationURL();
}catch (TwitterException te){
te.printStackTrace();
}
return null; }
Next I am retrieving the Access Token using the code:
public void setAccessToken(Uri uri) {
if (uri != null && uri.toString().startsWith(TWITTER_CALLBACK_URL)) {
String verifier = uri.getQueryParameter("oauth_token");
try {
AccessToken accessToken = twitter.getOAuthAccessToken(app.currentRequestToken, verifier);
//shared prefs
SharedPreferences.Editor e = yambaSharedPrefs.edit();
e.putString(PREF_KEY_OAUTH_TOKEN, accessToken.getToken());
e.putString(PREF_KEY_OAUTH_SECRET, accessToken.getTokenSecret());
//store log in status
e.putBoolean(PrefSharedTwitterLoggedIn, true);
e.apply();
Intent intent = new Intent(this, StatusActivity.class);
startActivity(intent);
} catch (TwitterException e) {
e.printStackTrace();
}
} }
My Callback URL looks like this:
public static final String OAUTH_CALLBACK_SCHEME = "twitter4j-MiYAMBA";public static final String OAUTH_CALLBACK_HOST = "callback";public static final String TWITTER_CALLBACK_URL = OAUTH_CALLBACK_SCHEME + "://" + OAUTH_CALLBACK_HOST;
I have also added the callback URL in the intent filter, like:
data android:host="callback" android:scheme="twitter4j-MiYAMBA"
Now I am not sure where the problem might be.
Also here is how the control flows through out the app:
StatusActivity is launched when the app is run, it checks if AccessToken are set or not using a function isAuthorised() which is defined in an Android application class named YAMBAapp, if it is defined then it begins the setup of layout, that is making buttons and stuff visible else it passes the control to a function beginAuthorization(), which starts an Activity named AuthorizationActivity, which gets the Authentication URL and passes it to the WebView, all of this is done in the function onResume, in this function I call another function setAccessToken and pass the 'uri' that has has data using:
uri = getIntent().getData();
setAccessToken(uri);
I have pasted the code for setAccessToken above.
Also in the manifest I have defined the "data" item in the intent filter of "AuthorizationActivity" and not the "StatusActivity", though it has no effect what so ever.
Please help, I really am stuck for few days now :)
First thing first, when you launch twitter authentication using default web browser, you will never return back to your main application, once access tokens are received and hence page not found, as url being invalid.
What you need is to load authenticaton using a web view through your own app, now you can override few functioanlities here like when being redirected. here you need to do final processing and terminate web view, which will result into control coming back to your own application rather then seeing page not found in browser.
Example: Here is how you oveerride an webview mechanism, now you create an actvity with theme like dialog or whatever, and load this webview in it with twitter auth url, once user authtenticate himself shouldOverrideUrlLoading will be called, here you retrive back verifier and quit..
webView.setWebViewClient( new WebViewClient()
{
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url)
{
// your url pattern here
if( url.contains("callback://twitter4j-MiYAMBA"))
{
Uri uri = Uri.parse( url );
// you get the verifier here
String oauthVerifier = uri.getQueryParameter( "oauth_verifier" );
// Do whateever u want here
..oauthVerifier.
//
// Finish this task, so you return back to activity from where it started
finish();
return true;
}
return false;
}
});
I guess this would be enough to finish rest of implementation. more info here '
http://daiwei.lu/2014/01/22/twitter-oauth-flow-on-android/