我希望打开应用中的所有链接时都具有特定意图

时间:2018-06-27 13:50:49

标签: android android-intent webview deep-linking

所以在我的应用程序中,我创建了一个仅包含webview的活动,该活动任务是禁止用户打开webview中除打开的链接以外的任何其他链接。

该应用程序仅应使用此Webview活动打开应用程序中的所有链接。

当前,当我在应用程序中打开任何链接时,意图选择器似乎可以在其他Web浏览器和我的活动之间进行选择

我如何做到这一点,以使我的应用程序中的任何链接自动在webview活动中打开,而无需提示用户在浏览器之间进行选择,就像Facebook Messenger在其中打开链接的方式一样,它会在com下的称为BrowserLiteActivity的活动中打开链接。 facebook.browser.lite。

我的意图过滤器

<activity
        android:name=".InternalWebView.InternalWebviewActivity"
        android:label="@string/title_activity_internal_webview"
        android:theme="@style/AppTheme">
        <intent-filter
            android:autoVerify="true"
            android:label="someLabel">
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />
            <data android:scheme="https"/>
            <data android:scheme="http"/>
            <data android:scheme=" "/>
        </intent-filter>
</activity>

编辑:更清楚地说,这里是与该问题相关的所有内容

InternalWebViewActivity.java

package com.example.example.InternalWebView;

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.webkit.WebView;

import com.example.example.R;

import java.util.concurrent.TimeUnit;

import butterknife.BindView;
import butterknife.ButterKnife;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;

public class InternalWebviewActivity extends AppCompatActivity {

    @BindView(R.id.webview)
    WebView wv;
    private io.reactivex.Observable timer = io.reactivex.Observable.interval(500, TimeUnit.MILLISECONDS);

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.webview_activity);
        ButterKnife.bind(this);
        Intent intent = getIntent();
        final String data = intent.getData().toString();
        InternalWebViewClient internalWebViewClient = new InternalWebViewClient(data);

        wv.getSettings().setJavaScriptEnabled(true);
        wv.setWebViewClient(internalWebViewClient);
        this.timer
                .subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe((mSec) -> {
                        String wvURL = wv.getUrl();
                        if (!wvURL.contains(internalWebViewClient.url))
                            wv.loadUrl(data);
                });


        wv.loadUrl(data);
    }
}

InternalWebClient.java

package com.example.example.InternalWebView;

import android.webkit.WebView;
import android.webkit.WebViewClient;

import java.net.MalformedURLException;
import java.net.URL;

public class InternalWebViewClient extends WebViewClient {
    public String url;
    public InternalWebViewClient(String url){
        URL u = null;
        try {
            u = new URL(url);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
        this.url = url.substring(url.indexOf(u.getHost()));
        this.url = this.url.substring(this.url.indexOf(".")+1);

    }

    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
        if(url.contains(this.url)){
            view.loadUrl(url);
        }
        return true;
    }
}

只是为了了解活动的外观

webview_activity.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <WebView
        android:id="@+id/webview"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>

注意:Facebook Messenger不需要更改计划即可在其活动中打开链接。

1 个答案:

答案 0 :(得分:1)

更新:如果您不想像我现在这样更改方案,此答案还不能令人满意。

正如@NSimon在问题评论中提到的,他的解决方案效果很好

以下是通过API发送到应用程序的示例链接:“ example://www.stackoverflow.com”

代码如下:

AndroidManifist.xml中的活动部分

<activity
    android:name=".InternalWebView.InternalWebviewActivity"
    android:label="@string/title_activity_internal_webview"
    android:theme="@style/AppTheme">
    <intent-filter
        android:autoVerify="true"
        android:label="somelable">
            <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"/>
     </intent-filter>
</activity>

InternalWebViewActivity.java

package com.example.example.InternalWebView;

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.webkit.WebView;

import com.example.example.R;

import java.util.concurrent.TimeUnit;

import butterknife.BindView;
import butterknife.ButterKnife;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;

public class InternalWebviewActivity extends AppCompatActivity {

    @BindView(R.id.webview)
    WebView wv;
    private io.reactivex.Observable timer = io.reactivex.Observable.interval(500, TimeUnit.MILLISECONDS);

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.webview_activity);
        ButterKnife.bind(this);
        Intent intent = getIntent();
        final String data = intent.getData().toString().replace("example://","http://");
        InternalWebViewClient internalWebViewClient = new InternalWebViewClient(data);

        wv.getSettings().setJavaScriptEnabled(true);
        wv.setWebViewClient(internalWebViewClient);

        //lazy and efficient method to handle url changed using javascript only
        this.timer
                .subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe((mSec) -> {
                        String wvURL = wv.getUrl();
                        if (!wvURL.contains(internalWebViewClient.url))
                            wv.loadUrl(data);
                });


        wv.loadUrl(data);
    }
}

InternalWebViewClient.java

package com.example.example.InternalWebView;

import android.webkit.WebView;
import android.webkit.WebViewClient;

import java.net.MalformedURLException;
import java.net.URL;

public class InternalWebViewClient extends WebViewClient {
    public String url;
    public InternalWebViewClient(String url){
        URL u = null;
        try {
            u = new URL(url);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
        //just to ignore stuff like www. being redirected to m. for mobile
        this.url = url.substring(url.indexOf(u.getHost()));
        this.url = this.url.substring(this.url.indexOf(".")+1);

    }

    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
        if(url.contains(this.url)){
            view.loadUrl(url);
        }
        return true;
    }
}

希望这对某人有帮助。