简体   繁体   中英

Launching an Android Application from the Browser

I have looked at several Stack Overflow questions with similar titles to mine. Each is answered, and the original author seems satisfied, but when I try to replicate their results I come up empty handed. Obviously I'm doing something horribly wrong, but I can't seem to figure it out.

For reference, these are the questions that I've been looking at:

Ultimately, I want to use this to restart my application once the user has performed an OAuth authentication request. However, my real application is a bit too large to post here. For this question, I've put together a simple application, to show you what I've done. I have two activities. This is mostly because every example I've seen uses an activity using the VIEW action. I'd prefer to use the MAIN action, but I've used both here to show that I tried both.

AndroidManifest.xml (Original; see edited version below)

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="org.example" android:versionCode="1" android:versionName="1.0-SNAPSHOT">
<application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="true">
    <activity android:name=".HelloAndroidActivity">
        <intent-filter>
            <data android:scheme="ex1"/>
            <action android:name="android.intent.action.MAIN"/>
            <category android:name="android.intent.category.LAUNCHER"/>
        </intent-filter>
    </activity>
    <activity android:name=".CallbackActivity">
        <intent-filter>
            <data android:scheme="ex2"/>
            <action android:name="android.intent.action.VIEW"/>
        </intent-filter>
    </activity>
</application>

AndroidManifest.xml (Edited in response to comment)

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="org.example" android:versionCode="1" android:versionName="1.0-SNAPSHOT">
<application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="true">
    <activity android:name=".HelloAndroidActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN"/>
            <category android:name="android.intent.category.LAUNCHER"/>
        </intent-filter>
    </activity>
    <activity android:name=".CallbackActivity">
        <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:host="www.this-so-does-not-exist.com" android:scheme="http" />
        </intent-filter>
    </activity>
</application>

main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>

HelloAndroidActivity.java

package org.example;

import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.widget.TextView;

public class HelloAndroidActivity extends Activity {

    private TextView textView;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        textView = (TextView) findViewById(R.id.textView);
    }

    @Override
    public void onResume() {
        super.onResume();
        Intent intent = getIntent();
        Uri data = intent.getData();
        if (data != null) {
            textView.setText("Hello Web!");
        }
    }

}

CallbackActivity.java

package org.example;

import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.widget.TextView;

public class CallbackActivity extends Activity {

    private TextView textView;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        textView = (TextView) findViewById(R.id.textView);
    }

    @Override
    public void onResume() {
        super.onResume();
        Intent intent = getIntent();
        Uri data = intent.getData();
        if (data != null) {
            textView.setText("Hello Web!");
        }
    }

}

This builds happily enough. Then, inside the browser, if I enter ex1://helloworld or ex2://helloworld I get different results depending upon how it is done. If I enter it in the url bar I get a google search for ex1://helloworld. If I do it via a redirect, I get "Web page not available". If I try to start the intent directly with something similar to:

    Intent intent = new Intent(Intent.ACTION_MAIN);
    ComponentName componentName = new ComponentName(
            "org.example",
            "org.example.HelloAndroidActivity");
    intent.setComponent(componentName);
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    intent.setData(Uri.parse("ex1://helloworld"));
    intent.addCategory(Intent.CATEGORY_BROWSABLE);
    startActivity(intent);

I get the default "Hello my-example.". I'm not sure what I'm doing incorrectly? Any insights?

You cannot use MAIN -- URLs in Android are only VIEW ed from the browser or WebView .

Also, none of your Intent filters include the BROWSABLE category, so they will never work with the browser.

It is not recommended to invent your own schemes. You can use a regular HTTP scheme, for some domain that you control. This sample project demonstrates this. In particular, you can follow the pattern shown by this filter:

<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:host="www.this-so-does-not-exist.com" android:scheme="http" />
</intent-filter>

replacing www.this-so-does-not-exist.com with something you own, and perhaps adding in a path to narrow the filter's scope. You can also see this technique used by the Barcode Scanner app from ZXing .

Try this, if you want to start your application from browser I've done this yesterday

1) On localhost make the html page

<html>
<head>
</head>
<body>
<a href="yourownscheme://example.com/">Test link</a>
</body>
</html>

2) make a class

   import org.xml.sax.Parser;

import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;

public class URLHandler extends Activity {
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);



    TextView uri=(TextView)findViewById(R.id.uri);
    TextView uri2=(TextView)findViewById(R.id.uri);


    if (Intent.ACTION_MAIN.equals(getIntent().getAction())) {
      String intentUri=(new Intent("yourownscheme://example.com/")).toUri(Intent.URI_INTENT_SCHEME).toString();



      uri.setText(intentUri);

    }
   }
  }

3) The manifest is below

<?xml version="1.0" encoding="utf-8"?>
<manifest android:versionCode="1"
          android:versionName="1.0"
          package="yourpackage name"
          xmlns:android="http://schemas.android.com/apk/res/android">

  <supports-screens android:largeScreens="true"
                    android:normalScreens="true"
                    android:smallScreens="false" />
  <application android:icon="@drawable/cw"
               android:label="@string/app_name">



      <activity
        android:name=".URLHandler"
        android:label="@string/app_name" 
        android:exported="true">
        <intent-filter>

            <data  android:scheme="yourownscheme://example.com/" />

            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.BROWSABLE" />
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    </activity>


  </application>
</manifest>

4) When you installed you'r application on emulator, open browser and go to localhost tap the link and your application, if it's installed gonna launch, othervice it would be error

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM