Как обрабатывать несколько глубоких ссылок для приложения android - PullRequest
0 голосов
/ 28 февраля 2020

Я создал приложение Android. Всякий раз, когда кто-то открывает сайт через приложение, он переходит на точную ссылку. Но если пользователь открывает другую ссылку, приложение все еще находится на предыдущей открытой ссылке. Вы можете проверить приложение здесь: https://play.google.com/store/apps/details?id=app.freeairdrop.io

Отправьте эти 2 ссылки себе на Telegram или WhatsApp:

  1. https://freeairdrop.io/airdrop/morpher.html
  2. https://freeairdrop.io/airdrop/simbcoin.html

Теперь откройте первую ссылку в моем приложении, когда будет предложено выбрать приложение. Вернитесь в Telegram / WhatsApp и нажмите на вторую ссылку. Мое приложение откроется, но оно все еще находится на этой странице (первая ссылка). Ничего не происходит, приложение не может загрузить вторую ссылку, если приложение не закрыто.

MainActivity. java код:

package app.freeairdrop.io;

import...    

public class MainActivity extends Activity{
    private ProgressBar progressBar;
    private WebView webView;
    private SwipeRefreshLayout mySwipeRefreshLayout;
    private boolean mShouldPause;

    @SuppressLint("SetJavaScriptEnabled")
    @Override
    public void onCreate(Bundle savedInstanceState) {


        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        progressBar = (ProgressBar) findViewById(R.id.progressBar);
        progressBar.setMax(100);
        webView = (WebView) findViewById(R.id.webView);
        webView.setWebViewClient(new WebViewClientDemo());
        webView.setWebChromeClient(new WebChromeClientDemo());
        mySwipeRefreshLayout = (SwipeRefreshLayout) this.findViewById(R.id.swipeContainer);


        mySwipeRefreshLayout.setOnRefreshListener(
                new SwipeRefreshLayout.OnRefreshListener() {
                    @Override
                    public void onRefresh() {
                        webView.reload();
                        mySwipeRefreshLayout.setRefreshing(false);
                    }
                }
        );

        // ATTENTION: This was auto-generated to handle app links.
        Intent appLinkIntent = getIntent();
        String appLinkAction = appLinkIntent.getAction();
        Uri appLinkData = appLinkIntent.getData();

        if (getIntent().getExtras() != null) {
            if (appLinkData == null){
                webView.loadUrl("https://freeairdrop.io/");
            }else
            webView.loadUrl(String.valueOf(appLinkData));

        } else if (getIntent().getExtras() == null){
            webView.loadUrl("https://freeairdrop.io/");

        }webView.reload();
    }

    private class WebViewClientDemo extends WebViewClient {

        @Override
        public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
            super.onReceivedError(view, errorCode, description, failingUrl);
            Toasty.error(getApplicationContext(), "No Internet, pull down to refresh when you're connected to internet", Toast.LENGTH_LONG, true).show();
        }


        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            Uri uri = Uri.parse(url);
            if (uri.getHost() != null && (url.startsWith("https://freeairdrop.io/") || url.startsWith("https://www.freeairdrop.io/"))) {
                return false;
            }

            Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
            view.getContext().startActivity(intent);
            return true;
        }
        @Override
        public void onPageFinished(WebView view, String url) {
            super.onPageFinished(view, url);
            progressBar.setVisibility(View.GONE);
            progressBar.setProgress(100);
        }

        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
            super.onPageStarted(view, url, favicon);
            progressBar.setVisibility(View.VISIBLE);
            progressBar.setProgress(0);
        }
    }


    private class WebChromeClientDemo extends WebChromeClient {

        public void onProgressChanged(WebView view, int progress) {
            progressBar.setProgress(progress);
        }
    }
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if ((keyCode == KeyEvent.KEYCODE_BACK) && webView.canGoBack()) {
            webView.goBack();
            return true;
        }
        else {
        }
        return super.onKeyDown(keyCode, event);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        return true;
    }

    @Override
    // This method is used to detect back button
    public void onBackPressed() {
        if (this.webView.canGoBack()) {
            this.webView.goBack();
            return;
        }

        else {
            // Let the system handle the back button
           super.onBackPressed();
        }
    }


}

Код AndroidManifest:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="app.freeairdrop.io">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />

    <application
        android:appCategory="productivity"
        android:hardwareAccelerated="true"
        android:allowBackup="true"
        android:fullBackupContent="true"
        android:icon="@mipmap/ic_launcher"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:label="@string/app_name"
        android:theme="@style/AppTheme"
        android:name=".ApplicationClass"
        tools:ignore="GoogleAppIndexingWarning">
        <activity
            android:name="app.freeairdrop.io.MainActivity"
            android:label="@string/app_name"
            android:configChanges="orientation|screenSize|screenLayout"
            android:resizeableActivity="false"
            android:supportsPictureInPicture="false"
            android:launchMode="singleInstance"
            >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <intent-filter android:autoVerify="true">
                <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"
                    android:host="freeairdrop.io" />
            </intent-filter>


        </activity>
    </application>


</manifest>

1 Ответ

0 голосов
/ 29 февраля 2020

Установка android:launchMode="singleInstance" на действие приведет к запуску только одного экземпляра этого действия. Это означает, что когда ваша деятельность была открыта один раз через Deeplink, этот экземпляр запущен. Когда вы открываете вторую ссылку, вы ожидаете, что ваш пользовательский интерфейс будет обновлен, но, поскольку экземпляр все еще выполнялся, onCreate действия не вызывается, поэтому вы видите представления из более ранней ссылки. (Другой момент - когда для него установлен singleInstance не разрешать другие действия в стеке.)

Вы можете получить дополнительную информацию в официальных документах .

Теперь, хотя onCreate никогда не вызывается, но Методы onResume и onNewIntent вызываются при установке singleInstance. Хотя обычно упоминается, что onNewIntent работает с singleTop, по моему опыту он вызывается при установке любого из трех отдельных флагов.

Таким образом, вам нужно переопределить любой из двух и написать код для обновления вашего интерфейса в них. Также обратите внимание, что onResume вызывается, когда ваша деятельность создается в самый первый раз после onCreate, поэтому, если вы поместите туда код, который вы можете оптимизировать, чтобы избежать повторной загрузки одной и той же вещи, и каждый раз вызывается onResume после возврата из фона. В этом случае onNewIntent() кажется лучшим вариантом.

Надеюсь, что это вам помогло.

Обновление: По запросу Вы можете найти отредактированный код ниже

package app.freeairdrop.io;

        import...

public class MainActivity extends Activity{
    private ProgressBar progressBar;
    private WebView webView;
    private SwipeRefreshLayout mySwipeRefreshLayout;
    private boolean mShouldPause;

    @SuppressLint("SetJavaScriptEnabled")
    @Override
    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        progressBar = (ProgressBar) findViewById(R.id.progressBar);
        progressBar.setMax(100);
        webView = (WebView) findViewById(R.id.webView);
        webView.setWebViewClient(new WebViewClientDemo());
        webView.setWebChromeClient(new WebChromeClientDemo());
        mySwipeRefreshLayout = (SwipeRefreshLayout) this.findViewById(R.id.swipeContainer);

        mySwipeRefreshLayout.setOnRefreshListener(
                new SwipeRefreshLayout.OnRefreshListener() {
                    @Override
                    public void onRefresh() {
                        webView.reload();
                        mySwipeRefreshLayout.setRefreshing(false);
                    }
                }
        );
        // call your method here to manage the intent
        manageIntent(getIntent());
    }

    /* Simply moved your code which handles the intent to a common method
     * Call this method from onCreate so that when first instance of activity gets created it handles it
     * Similarly call it from onNewIntent to manage the new link you get
     * You just need to pass the respective intents from the methods
     */
    public void manageIntent(Intent intent) {
        // ATTENTION: This was auto-generated to handle app links.
        Intent appLinkIntent = intent;
        String appLinkAction = appLinkIntent.getAction();
        Uri appLinkData = appLinkIntent.getData();

        if (getIntent().getExtras() != null) {
            if (appLinkData == null){
                webView.loadUrl("https://freeairdrop.io/");
            }else
                webView.loadUrl(String.valueOf(appLinkData));

        } else if (getIntent().getExtras() == null){
            webView.loadUrl("https://freeairdrop.io/");

        }
    }

    // override to get the new intent when this activity has an instance already running
    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        // again call the same method here with the new intent received
        manageIntent(intent);
    }

    private class WebViewClientDemo extends WebViewClient {

        @Override
        public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
            super.onReceivedError(view, errorCode, description, failingUrl);
            Toasty.error(getApplicationContext(), "No Internet, pull down to refresh when you're connected to internet", Toast.LENGTH_LONG, true).show();
        }


        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            Uri uri = Uri.parse(url);
            if (uri.getHost() != null && (url.startsWith("https://freeairdrop.io/") || url.startsWith("https://www.freeairdrop.io/"))) {
                return false;
            }

            Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
            view.getContext().startActivity(intent);
            return true;
        }
        @Override
        public void onPageFinished(WebView view, String url) {
            super.onPageFinished(view, url);
            progressBar.setVisibility(View.GONE);
            progressBar.setProgress(100);
        }

        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
            super.onPageStarted(view, url, favicon);
            progressBar.setVisibility(View.VISIBLE);
            progressBar.setProgress(0);
        }
    }


    private class WebChromeClientDemo extends WebChromeClient {

        public void onProgressChanged(WebView view, int progress) {
            progressBar.setProgress(progress);
        }
    }
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if ((keyCode == KeyEvent.KEYCODE_BACK) && webView.canGoBack()) {
            webView.goBack();
            return true;
        }
        else {
        }
        return super.onKeyDown(keyCode, event);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        return true;
    }

    @Override
    // This method is used to detect back button
    public void onBackPressed() {
        if (this.webView.canGoBack()) {
            this.webView.goBack();
            return;
        }

        else {
            // Let the system handle the back button
            super.onBackPressed();
        }
    }

}

Посмотрите, работает ли это для вас, и дайте мне знать.

...