簡體   English   中英

WebChromeClient 不再請求位置權限

[英]WebChromeClient doesn't ask for location permission anymore

我有一個 Android 應用程序,它使用 WebView 在 Open Street Map 上顯示 map,幾周后停止正常工作。

幾周前,當用戶在 web 頁面上點擊顯示我的位置時,Android 會提示允許應用加載當前的 position,但此時只顯示一個錯誤: Geolocation error: user denied Geolocation

我在 SO 和 Google 上查看了這里,看看我的代碼的某些部分是否已被棄用或被阻止,但我沒有發現任何有用的東西。 我發現的唯一信息是關於ActionBarActivity但也使用AppCompatActivity問題是一樣的。

MainActivity 的 MVP 版本如下(我刪除了此示例中其他無用的行):

package com.vinaysomawat.careerhigh;

import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;

import android.webkit.GeolocationPermissions;
import android.webkit.WebChromeClient;


public class MainActivity extends ActionBarActivity {
    public String mGeolocationOrigin;
    public GeolocationPermissions.Callback mGeolocationCallback;
    private static final int REQUEST_FINE_LOCATION=0;

    public class GeoWebViewClient extends WebViewClient {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            // When user clicks a hyperlink, load in the existing WebView
            view.loadUrl(url);
            return true;
        }
    }

    public class GeoWebChromeClient extends WebChromeClient {
        @Override
        public void onGeolocationPermissionsShowPrompt(String origin,
                                                       GeolocationPermissions.Callback callback) {
            String perm = Manifest.permission.ACCESS_FINE_LOCATION;
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M ||
                    ContextCompat.checkSelfPermission(MainActivity.this, perm) == PackageManager.PERMISSION_GRANTED) {
                // we're on SDK < 23 OR user has already granted permission
                callback.invoke(origin, true, false);
            } else {
                if (!ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, perm)) {
                    // ask the user for permission
                    ActivityCompat.requestPermissions(MainActivity.this, new String[] {perm}, REQUEST_FINE_LOCATION);

                    // we will use these when user responds
                    mGeolocationOrigin = origin;
                    mGeolocationCallback = callback;
                }
            }}

    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode) {
            case REQUEST_FINE_LOCATION:
                boolean allow = false;
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    // user has allowed this permission
                    allow = true;
                }
                if (mGeolocationCallback != null) {
                    // call back to web chrome client
                    mGeolocationCallback.invoke(mGeolocationOrigin, allow, false);
                }
                break;
        }
    }

    WebView mywebview;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        //Hide TopBar
        getSupportActionBar().hide();

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mywebview = (WebView)findViewById(R.id.webView);
        WebSettings webSettings = mywebview.getSettings();

        // Empty Cache
        mywebview.clearCache(true);

        // Hide Zoom buttons
        mywebview.getSettings().setDisplayZoomControls(false);

        mywebview.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
        mywebview.getSettings().setBuiltInZoomControls(true);
        mywebview.setWebViewClient(new GeoWebViewClient());
        // Below required for geolocation
        mywebview.getSettings().setJavaScriptEnabled(true);
        mywebview.getSettings().setGeolocationEnabled(true);
        mywebview.setWebChromeClient(new GeoWebChromeClient());

        mywebview.setWebChromeClient(new WebChromeClient() {
            @Override
            public boolean onCreateWindow(WebView view, boolean dialog, boolean userGesture, android.os.Message resultMsg)
            {
                WebView.HitTestResult result = view.getHitTestResult();
                String data = result.getExtra();
                Context context = view.getContext();
                Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(data));
                context.startActivity(browserIntent);
                return false;
            }
        });

        mywebview.loadUrl("https://mycurrentlocation.net/");
        
    }


    @Override
    public void onBackPressed(){
        if(mywebview.canGoBack()) {
            mywebview.goBack();
        } else
        {
            super.onBackPressed();
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu){
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item){
        int id = item.getItemId();

        if(id == R.id.action_settings){
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

}

當我單擊按鈕顯示我當前的 position 時,在 Android Studio 中我得到以下日志:

E/Resource: printErrorResource,可能不是錯誤,因為模塊對 =android.content.res.HwResourcesImpl.printErrorResource:2634 android.content.res.ResourcesImpl.openRawResource:444 android.content.res.Resources 調用的資源具有實體訪問權限。 openRawResource:1418 android.content.res.Resources.openRawResource:1362 android.support.v4.graphics.TypefaceCompatBaseImpl.createFromResourcesFontFile:304 android.support.v4.graphics.TypefaceCompat.createFromResourcesFontFile:232 I/ResourcesImplEx: The apk asset path = ApkAssets {path=/system/framework/framework-res.apk} apk資源路徑=ApkAssets{path=/system/framework/framework-res-hwext.apk} apk資源路徑=ApkAssets{path=/preas/oversea/ overlay/GmsConfigOverlay.apk} apk資源路徑 = ApkAssets{path=/preas/oversea/overlay/GmsGsaConfigOverlay.apk} apk資源路徑 = ApkAssets{path=/preas/oversea/overlay/GoogleExtServicesConfigOverlay.apk} apk資源路徑= ApkAssets{path=/preas/oversea/o verlay/GoogleModuleMetadataConfigOverlay.apk} apk資產路徑=ApkAssets{path=/preas/oversea/overlay/GooglePermissionControllerConfigOverlay.apk} apk資產路徑=ApkAssets{path=/hw_product/overlay/frameworkResOverlay.apk} apk資產路徑=ApkAssets {path=/odm/overlay/frameworkResOverlay.apk} apk 資產路徑 = ApkAssets{path=/data/app/com.vinaysomawat.careerhigh-3JvsuNOhaJTzUZrEdMaQnA==/base.apk} I/ResourcesImplEx: apk 資產路徑 = ApkAssets {path=/data/app/com.google.android.webview-Lw6x1ElnmD4d1UEVSG95iA==/base.apk} apk資產路徑=ApkAssets{path=/data/app/com.google.android.webview-Lw6x1ElnmD4d1UEVSG95iA==/ split_config.it.apk} apk資源路徑=ApkAssets{path=/data/app/com.google.android.webview-Lw6x1ElnmD4d1UEVSG95iA==/split_weblayer.apk} apk資源路徑=ApkAssets{path=/data/app/ com.google.android.trichromelibrary_489608833-ndmJcgRaxXQPmZ7r_KqT-w==/base.apk}

然后顯示此日志(我認為這是表示無法加載位置的錯誤橫幅):

D/HiTouch_PressGestureDetector: onAttached, package=com.vinaysomawat.careerhigh, windowType=2, mHiTouchRestricted=false D/mali_winsys: EGLint new_window_surface(egl_winsys_display *, void *, EGLSurface, EGLConfig, egl_winsys_surface **, EGLBoolean) 返回 0x3000

是的。 我有一個類似的問題。 android webview 和地理位置的位置權限不再由 webChromeClient 處理。 現在,它們的處理方式與 Android 原生應用程序相同。 我使用以下內容作為指南,效果很好。

https://developer.android.com/training/location/permissions

使用這個庫而不是擁有適用於 Android 的 WebView 組件

https://github.com/delight-im/Android-AdvancedWebView

在這個庫中,權限處理得很好

我希望這對你有幫助

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM