Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to pass a message from an Android browser to an app?

I have a situation where I'd like for some data to be passed from a mobile web site to a native Android app. A complication is that, in the normal case, the native Android app might not be installed when the mobile web site is loaded.

Here's an example:

I am a user of ExampleApp and I want to share a particular piece of data from ExampleApp with you, who has never installed ExampleApp.

I send you an email with a link to a mobile web page that knows what piece of data you want to see when you open the link. But, since the data is only available in the native app, not the mobile web, you're taken to a page that asks you to go to Android Market and install ExampleApp.

You install ExampleApp, and ideally, you'd be taken directly to the piece of data that I shared with you.

The big problem is in the disconnect between viewing the mobile web page and the installation of ExampleApp.

I've thought about a couple solutions, but neither have been successful (that said, I could just be implementing them incorrectly):

  1. Set a cookie on our domain that includes the data when the mobile web page is loaded. Then, when ExampleApp is opened, start a WebView to request a page on the same domain and check the value of the cookie. Use that to determine what piece of data to show in ExampleApp.
  2. Use JavaScript localStorage to store a reference to the piece of data and use a WebView to get a page on that domain and request the content of localStorage from within ExampleApp.

In both these situations, it seems as though the WebView and the Browser are sandbox'd away from each other, so you can't get at the cookies/localStorage between the two.

Is there any other way to "leave a crumbtrail" or set a message that an app installed later can access from the Browser?

EDIT: Given some of the responses, I should mention that I only want you to click once on the link, NOT have to click once, install the app, then click again to open the app to the right place.

like image 502
iseff Avatar asked Feb 25 '11 23:02

iseff


1 Answers

The solution is actually quite simple, I'm a bit astonished that nobody has been able to come up with it for over a year. So here it is:

The basic idea is to use cookies to store the information. The data flow is as follows:

open web page -> set cookie -> redirect to market -> install app -> launch browser with web page -> read cookie -> start custom intent with cookie data -> capture intent and read cookie data

The user visits a webpage (by scanning a QR Tag for example). The url of the webpage holds a reference to the data you want to pass, or holds the data itself. The website sets the data as a cookie and redirects to the Android market (http://market.android.com/details?id=com.yourapp). As soon as your app launches, you open a browser and load the same webpage again. This time however, it detects that the cookie is already set and redirects to a custom URL scheme like example://example.com/installed?id=DATA, instead of the market. Using an intent filter, you launch your activity and extract the information from the intent.

Here is the relevant Activity code:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Intent intent = getIntent();
    if(intent == null || intent.getData() == null || !"example".equals(intent.getData().getScheme())) {
        String url = "http://example.com/yourApp/index.php";
        Intent i = new Intent(Intent.ACTION_VIEW);
        i.setData(Uri.parse(url));
        startActivity(i);
        finish();
        return;
    }else {
        Uri uri = intent.getData();
        if("example".equals(uri.getScheme())) {
            id = uri.getQueryParameter("id");
        }
    }
    ... initialise your activity ...
}

A simple PHP file (the website) for easy demonstration:

<?php
$value = "123";
if(!isset($_COOKIE["TestCookie"])) {
    setcookie("TestCookie", $value, time()+3600);  /* expire in 1 hour */
    header("Location: http://market.android.com/details?id=com.yourapp");
    exit;
}else {
    header("Location: example://example.com/installed?id=".$_COOKIE["TestCookie"]);
    exit;
}
?>

And the intent filter:

<!-- Handle URLs like loyalty://example.com/merchant/123 -->
<intent-filter>
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    <data android:scheme="example" android:host="example.com" />
</intent-filter>

BTW, I have decided to blog about the issue.

like image 73
Florian Avatar answered Sep 27 '22 23:09

Florian