Jump to content

[TOPIC: topicViewTemplate]
[GLOBAL: userSmallPhoto]
Photo

Handling URL scheme on Android?
Started by marcar Jul 11 2013 04:39 AM

47 replies to this topic
[TOPIC CONTROLS]
Page 1 of 2 1 2
This topic has been archived. This means that you cannot reply to this topic.
[/TOPIC CONTROLS]
[modOptionsDropdown]
[/modOptionsDropdown]
[reputationFilter]
[TOPIC: post.html]
#1

marcar

[GLOBAL: userInfoPane.html]
marcar
  • Enthusiast

  • 42 posts
  • Corona SDK

Hi,

 

is it possible to handle URL schemas like in iOS? In iOS, you specify CFBundleURLSchemes in build.settings. I thought, that since some time, this functionality is available for Android as well? Am I mistaken?

 

Thanks in advance!

 

Best regards,
Martin



[TOPIC: post.html]
#2

Rob Miracle

[GLOBAL: userInfoPane.html]
Rob Miracle
  • Moderator

  • 24,569 posts
  • Corona Staff

The URL scheme is an iOS only thing, but Android has something similar by using the app's unique name, I.e com.companyname.appname.

[TOPIC: post.html]
#3

Joshua Quick

[GLOBAL: userInfoPane.html]
Joshua Quick
  • Moderator

  • 3,397 posts
  • Corona Staff

As of the newest daily builds ( build #1138 and higher), we've added Android intent filter support which will allow your app to be launched via URL schemes.  It's currently undocumented because it's in the experimental phase.  Partly because I don't fully understand the proper way to set up an intent filter just yet, since they're kind of complicated on Android... nor do I have the time to experiment with it. But you're welcome to give it a try.
 
Adding the following to your "build.settings" file will set up your app to be launched via a URL scheme from another app...

settings =
{
   android =
   {
      intentFilters =
      {
         {
            label = "Optional Title Goes Here",
            actions = { "android.intent.action.VIEW" },
            categories =
            {
               "android.intent.category.DEFAULT",
               "android.intent.category.BROWSABLE",
            },
            data = { scheme = "corona" },
         },
         -- You can add more intent filters here.
      },
   },
}

 
I've tested the above and it will launch the app via a URL such as "corona://test".  You should change the name of the scheme for your app of course, but this should give you something to work with.
 

Google documents intent filters here...

http://developer.android.com/guide/components/intents-filters.html

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



[TOPIC: post.html]
#4

marcar

[GLOBAL: userInfoPane.html]
marcar
  • Enthusiast

  • 42 posts
  • Corona SDK

The URL scheme is an iOS only thing, but Android has something similar by using the app's unique name, I.e com.companyname.appname.

Hi,

 

do you have any more information on this, I seem to be unable to find how to use this. I just want to launch another app of mine if it is installed, or show the Play Store if it is not installed.

 

Best regards,

Martin



[TOPIC: post.html]
#5

marcar

[GLOBAL: userInfoPane.html]
marcar
  • Enthusiast

  • 42 posts
  • Corona SDK

As of the newest daily builds ( build #1138 and higher), we've added Android intent filter support which will allow your app to be launched via URL schemes.  It's currently undocumented because it's in the experimental phase.  Partly because I don't fully understand the proper way to set up an intent filter just yet, since they're kind of complicated on Android... nor do I have the time to experiment with it. But you're welcome to give it a try.


Hi,

 

thanks, that looks interestig as well. Do you already have a time-plan for the next stable version, as I'd like to avoid daily builds if possible, as we are close to release.

 

Best regards,
Martin



[TOPIC: post.html]
#6

Joshua Quick

[GLOBAL: userInfoPane.html]
Joshua Quick
  • Moderator

  • 3,397 posts
  • Corona Staff

No release date has been set yet.

 

That said, if you want to detect if your other app is installed on Android, then check out the following forum post.

   http://forums.coronalabs.com/topic/33636-my-android-app-needs-to-check-if-another-one-of-my-apps-is-installed-on-the-device-on-ios-i-use-url-schemes/?p=174720

 

And in case you didn't already know, you can show your app in the app store via the following API...

   http://docs.coronalabs.com/daily/api/library/native/showPopup.html#appstore-and-rateapp



[TOPIC: post.html]
#7

emily

[GLOBAL: userInfoPane.html]
emily
  • Observer

  • 28 posts
  • Corona SDK

WOOT!

I wasn't aware that support for Android URL scheme has been added!

 

Thank you so much!

I think I may love you Joshua :D

 

Cheers

Emilia



[TOPIC: post.html]
#8

Joshua Quick

[GLOBAL: userInfoPane.html]
Joshua Quick
  • Moderator

  • 3,397 posts
  • Corona Staff

Happy to help Emilia!



[TOPIC: post.html]
#9

marcar

[GLOBAL: userInfoPane.html]
marcar
  • Enthusiast

  • 42 posts
  • Corona SDK

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



[TOPIC: post.html]
#10

Joshua Quick

[GLOBAL: userInfoPane.html]
Joshua Quick
  • Moderator

  • 3,397 posts
  • Corona Staff

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.



[TOPIC: post.html]
#11

marcar

[GLOBAL: userInfoPane.html]
marcar
  • Enthusiast

  • 42 posts
  • Corona SDK

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



[TOPIC: post.html]
#12

Joshua Quick

[GLOBAL: userInfoPane.html]
Joshua Quick
  • Moderator

  • 3,397 posts
  • Corona Staff

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!



[TOPIC: post.html]
#13

marcar

[GLOBAL: userInfoPane.html]
marcar
  • Enthusiast

  • 42 posts
  • Corona SDK

Thanks, I will try out.

 

Best regards,
Martin



[TOPIC: post.html]
#14

Joshua Quick

[GLOBAL: userInfoPane.html]
Joshua Quick
  • Moderator

  • 3,397 posts
  • Corona Staff

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



[TOPIC: post.html]
#15

pranav.khandelwal

[GLOBAL: userInfoPane.html]
pranav.khandelwal
  • Enthusiast

  • 30 posts
  • Corona SDK

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 



[TOPIC: post.html]
#16

Joshua Quick

[GLOBAL: userInfoPane.html]
Joshua Quick
  • Moderator

  • 3,397 posts
  • Corona Staff

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



[TOPIC: post.html]
#17

pranav.khandelwal

[GLOBAL: userInfoPane.html]
pranav.khandelwal
  • Enthusiast

  • 30 posts
  • Corona SDK

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



[TOPIC: post.html]
#18

Joshua Quick

[GLOBAL: userInfoPane.html]
Joshua Quick
  • Moderator

  • 3,397 posts
  • Corona Staff

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")


[TOPIC: post.html]
#19

pranav.khandelwal

[GLOBAL: userInfoPane.html]
pranav.khandelwal
  • Enthusiast

  • 30 posts
  • Corona SDK

Thnks Joshua for your fast reply



[TOPIC: post.html]
#20

marcar

[GLOBAL: userInfoPane.html]
marcar
  • Enthusiast

  • 42 posts
  • Corona SDK

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.



[TOPIC: post.html]
#21

ojnab

[GLOBAL: userInfoPane.html]
ojnab
  • Contributor

  • 532 posts
  • Corona SDK

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



[TOPIC: post.html]
#22

marcar

[GLOBAL: userInfoPane.html]
marcar
  • Enthusiast

  • 42 posts
  • Corona SDK

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.



[TOPIC: post.html]
#23

ojnab

[GLOBAL: userInfoPane.html]
ojnab
  • Contributor

  • 532 posts
  • Corona SDK

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?



[TOPIC: post.html]
#24

marcar

[GLOBAL: userInfoPane.html]
marcar
  • Enthusiast

  • 42 posts
  • Corona SDK

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.



[TOPIC: post.html]
#25

Joshua Quick

[GLOBAL: userInfoPane.html]
Joshua Quick
  • Moderator

  • 3,397 posts
  • Corona Staff

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




[topic_controls]
Page 1 of 2 1 2
 
[/topic_controls]