Handling URL scheme on Android?

I am still stuck with the latest stable build, (i.e. one build before the intent filter has been added :)), is there a way that I launch the app after I detected it is installed with the described workaround?

Best regards,
Martin

Unfortunately, I can’t think of any other way to make it work with our release version’s APIs.

The closest equivalent that I can think of is to show your app in the app store, which if already purchased, will give you the option to launch the app the end-user has already bought.  You can do this via our native.showPopup(“appStore”) API…

   http://docs.coronalabs.com/api/library/native/showPopup.html

Probably not what you want, but the next best thing that I can think of.

Hmm, thanks.

We will consider upgrading or adding the functionality after the first release. Is there already a way to handle the URL via the intent filter? How does one access the data from the caputred intent?

Thanks in advance!

Best regards,
Martin

You can capture the URL and Android intent that opened your app via:

  • The launch arguments “…” on application startup.

  • The “applicationOpen” system event when your app is resumed via an intent/url.
     
    It’s easier to describe how this works by observing the following sample code on an Android device.  The below code will create a local/scheduled notification.  When you tap on the notification in the status bar, it will launch your app with an Android intent.  The below code will print the entire contents of the launch arguments and applicationOpen event.

    – Prints all contents of a Lua table to the log. local function printTable(table, stringPrefix) if not stringPrefix then stringPrefix = “### " end if type(table) == “table” then for key, value in pairs(table) do if type(value) == “table” then print(stringPrefix … tostring(key)) print(stringPrefix … “{”) printTable(value, stringPrefix … " “) print(stringPrefix … “}”) else print(stringPrefix … tostring(key) … “: " … tostring(value)) end end end end – Prints all launch arguments local launchArguments = … if launchArguments then print(”### — Launch Arguments —”) printTable(launchArguments) end – Prints the event table when an “applicationOpen” event occurs. local function onSystemEvent(event) if event.type == “applicationOpen” then print(”### — Application Open —") printTable(event) end end Runtime:addEventListener(“system”, onSystemEvent) – Tap the screen to schedule a local notification. local function onTap(event) local settings = { body = “This is a test.” } system.scheduleNotification(1, settings) end Runtime:addEventListener(“tap”, onTap)

 
 
I hope this helps!

Thanks, I will try out.

Best regards,
Martin

I’ve noticed that this forum thread is attracting more followers.  So, here are some additional details on how to handle a received Android intent in Corona.  This information is more for developers who understand how Android intents work on the Java side.
 
Both the “main.lua” launch arguments and the “applicationOpen” event will have an “androidIntent” Lua table which is only made available on Android.  The “androidIntent” table will have the following fields…

-- Provides the URI returned by the Java Intent.getData() method. androidIntent.url -- Provides the action string returned by the Intent.getAction() method. androidIntent.action -- A Lua string array matching the collection returned by the Intent.getCategories() method. androidIntent.categories -- A Lua table matching the Bundle returned by the Intent.getExtras() method. -- The keys are strings and the values are Lua types that best match the Java value types. -- Note that this does support nested tables/bundles. androidIntent.extras 

You’ll need to make sure to do if checks on each of the above fields in the “androidIntent” table before attempting to access its data.  If the Java equivalent Intent methods return null, then they will be set to nil on the Lua side.

Information about the Android “Intent” Java class can be found here…

   http://developer.android.com/reference/android/content/Intent.html

I’ve noticed that this forum thread is attracting more followers.  So, here are some additional details on how to handle a received Android intent in Corona.  This information is more for developers who understand how Android intents work on the Java side.
 
Both the “main.lua” launch arguments and the “applicationOpen” event will have an “androidIntent” Lua table which is only made available on Android.  The “androidIntent” table will have the following fields…

-- Provides the URI returned by the Java Intent.getData() method. androidIntent.url -- Provides the action string returned by the Intent.getAction() method. androidIntent.action -- A Lua string array matching the collection returned by the Intent.getCategories() method. androidIntent.categories -- A Lua table matching the Bundle returned by the Intent.getExtras() method. -- The keys are strings and the values are Lua types that best match the Java value types. -- Note that this does support nested tables/bundles. androidIntent.extras 

You’ll need to make sure to do if checks on each of the above fields in the “androidIntent” table before attempting to access its data.  If the Java equivalent Intent methods return null, then they will be set to nil on the Lua side.

Information about the Android “Intent” Java class can be found here…

   http://developer.android.com/reference/android/content/Intent.html

I think in this forum I will get exact answer which I want

as Joshua has explained how to use URLScheme in android I m having one problem in this i want to open my application named “try”. what changes I have to do in it.

Thanks in advance 

What you need to do is set up your “try” app with an intent-filter as I’ve shown up above.  You can either give it a custom URL scheme or a the domain of your website.  You would then launch your “try” app from your other app via Corona’s system.openURL() function.  So, for the example I provided above which uses a “corona://” custom URL scheme, you would launch it like this…

   system.openURL(“corona://test”)

Of course, you should use “corona” as your custom URL scheme.  It should be unique to your app.

That said, I actually recommend that you do it by your website’s domain name instead in case the app you’re trying to launch is not installed.  That way it’ll launch the device’s browser app instead and show a web page on your site telling the end-user to download your other app.  Something along those lines.  You would do this via the “data” tag’s “host” attribute instead of using the scheme “attribute” as documented by Google here…

   http://developer.android.com/guide/topics/manifest/data-element.html

if I have to open my app than URL will be in which form

system.openURL(“corona://try”)

or

system.openURL(“try://”).

And I want this URLScheme in ios also

You can set up your own “try://” custom URL scheme in the “build.settings” file as follows…

settings = { android = { intentFilters = { { label = "Your Title Goes Here", actions = { "android.intent.action.VIEW" }, categories = { "android.intent.category.DEFAULT", "android.intent.category.BROWSABLE", }, data = { scheme = "try" }, }, }, }, }

And then you can open your “try” app from your other app using the following function call…

system.openURL("try://your\_arguments\_go\_here")

Thnks Joshua for your fast reply

If you have set up the URL handler like that, you can even launch it from the stock browser or Chrome. I have used it in several applications for some time now and it works entirely as expected. Thanks for making it possible.

I can launch one app from another with the method described here, but it does not seem to work if I want to launch the app from a browser or the email system. Is that supported?

Thanks

Are you sure you have the category “android.intent.category.BROWSABLE” added to your filter, because this is required so that browser and e-mail will consider the intent-filter.

Yes.

I just copied the build.settings code above and changed my scheme name.

It works between apps but not in email and browser.

Does that work for you?

Hmm, I thought it did, but upon new try right now, it didn’t. Sorry, I had that wrongly in mind, because I only use it for bouncing between different apps, and I was pretty sure I also tested it with the settings, but I seem to have recalled that wrongly.

It works in the default Browser app for me.  But it might not work for all 3rd party browser apps… or 3rd party apps in general.  This is because it’s up to the 3rd party app to turn the URL into an Android “intent”, query if there are any activities on the device that support that URL scheme via PackageManager.queryIntentActivities() in Java, and then launching that activity.  If the app does not do this and simply attempt to do an HTTP connection with your custom URL scheme, then of course it will fail.  There is nothing you can do within your app to force another app to handle your custom URL scheme.  Not even if you’ve coded your Android app natively.

So, this is why I’ve suggested up above to use your website’s domain instead of a custom URL scheme.  That way, if the app doesn’t handle custom URL schemes or if your app is not installed, then at least it will take the end-user to your website.  You would do this by setting the “host” part of the intent-filter as described here…

   http://developer.android.com/guide/topics/manifest/data-element.html

Thanks Joshua. That makes sense.

But the strange thing is that I tested it with the default browser and as a link in the default email app and none of these seems to work. I would think that when calling system.openURL(“myapp://“) it also calls the default browser to launch the app right?

When you call system.openURL(“myapp://”), then what we do is turn that URL into an Android intent and then have the Android OS launch the default activity for that URL by calling the Java Activity.startActivity() method…

   http://developer.android.com/reference/android/content/Context.html#startActivity(android.content.Intent

The above is how you can get your app to launch another app via it’s intent-filter.  If no app on the device has a matching intent-filter for that URL, then the OS defaults to the Browser app.

Now, if the app blindly passes your URL to the Java WebView.loadUrl() method on Android, then it will ignore all app intent-filters on the device and attempt to do an HTTP request to a server that doesn’t exist.  In your case, you’ll get a 404 error.

   http://developer.android.com/reference/android/webkit/WebView.html#loadUrl(java.lang.String