Android: Using html5 to determine geolocation in webview with javascript api

前端 未结 4 1956
孤独总比滥情好
孤独总比滥情好 2020-12-08 17:34

I\'m currently having an issue with geolocation in a webview. I have a webapp. I\'m currently not using phonegap or any other mobile framework. I\'ve been unsuccessful at ge

相关标签:
4条回答
  • 2020-12-08 17:52

    You did try this html5webview class.

    private HTML5WebView mWebView;
    String url = "SOMEURL";
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mWebView = new HTML5WebView(this);
        if (savedInstanceState != null) {
            mWebView.restoreState(savedInstanceState);
        } else {
            mWebView.loadUrl(url);
        }
        setContentView(mWebView.getLayout());
    }
    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        mWebView.saveState(outState);
    }
    
    0 讨论(0)
  • 2020-12-08 17:59

    Your problem may be the same problem with Android WebView using Geolocation.
    I think HTML5 use local database, so you need add some HTML5 requirements like this

    // HTML5 API flags
    webView.getSettings().setAppCacheEnabled(true);
    webView.getSettings().setDatabaseEnabled(true);
    webView.getSettings().setDomStorageEnabled(true);
    
    0 讨论(0)
  • 2020-12-08 18:00

    Add onGeolocationPermissionsShowPrompt() to MyChromeWebViewClient as below:

    private class MyChromeWebViewClient extends WebChromeClient {
    
        @Override
        public void onProgressChanged(WebView view, int progress) {
            // Activities and WebViews measure progress with different scales.
            // The progress meter will automatically disappear when we reach 100%
            activity.setProgress(progress * 100);
        }
    
        @Override
        public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
            Log.d(LOG_TAG, message);
            // This shows the dialog box.  This can be commented out for dev
            AlertDialog.Builder alertBldr = new AlertDialog.Builder(activity);
            alertBldr.setMessage(message);
            alertBldr.setTitle("Alert");
            alertBldr.show();
            result.confirm();
            return true;
        }
    
        public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback) {
            callback.invoke(origin, true, false);
        }
    }
    

    You need to import "android.webkit.GeolocationPermissions".

    Add this permission:

    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    

    This will work I guess.

    0 讨论(0)
  • 2020-12-08 18:09

    Sharing my Working activity class, this is a complete solution which can demonstrate

    • Showing loading dialog while the web page is loading
    • Ask for permission in marshmallow and above
    • Handle webpage error
    • check for the internet connection and open setting page
    • Handling Geolocation permission with and without dialog

    Hope it save someone's time

         /**
         * Created by Hitesh.Sahu on 3/24/2017.
         */
    
        public class WebViewActivity extends AppCompatActivity {
    
            final private int REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS = 124;
            private int webViewPreviousState;
            private final int PAGE_STARTED = 0x1;
            private final int PAGE_REDIRECTED = 0x2;
            private CoordinatorLayout rootView;
            private WebView webView;
    
    
            @Override
            protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_webview);
                webView = (WebView) findViewById(R.id.webView);
                rootView = (CoordinatorLayout) findViewById(R.id.root_view);
    
                if (Build.VERSION.SDK_INT >= 23) {
                    // Marshmallow+ Permission APIs
                    fuckMarshMallow();
                }
    
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                    if (0 != (getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE)) {
                        WebView.setWebContentsDebuggingEnabled(true);
                    }
                }
                webView.setInitialScale(1);
                webView.getSettings().setLoadWithOverviewMode(true);
                webView.getSettings().setUseWideViewPort(true);
                webView.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);
                webView.setScrollbarFadingEnabled(false);
    
                webView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
                webView.getSettings().setBuiltInZoomControls(true);
                webView.setWebViewClient(new GeoWebViewClient());
                // Below required for geolocation
                webView.getSettings().setJavaScriptEnabled(true);
                webView.getSettings().setGeolocationEnabled(true);
                webView.setWebChromeClient(new GeoWebChromeClient());
    
                webView.getSettings().setAppCacheEnabled(true);
                webView.getSettings().setDatabaseEnabled(true);
                webView.getSettings().setDomStorageEnabled(true);
    
                webView.getSettings().setGeolocationDatabasePath(getFilesDir().getPath());
    
                webView.loadUrl("file:///android_asset/index.html");
            }
    
            /**
             * WebChromeClient subclass handles UI-related calls
             * Note: think chrome as in decoration, not the Chrome browser
             */
            public class GeoWebChromeClient extends android.webkit.WebChromeClient {
                @Override
                public void onGeolocationPermissionsShowPrompt(final String origin,
                                                               final GeolocationPermissions.Callback callback) {
                    // Always grant permission since the app itself requires location
                    // permission and the user has therefore already granted it
                    callback.invoke(origin, true, false);
    
        //            final boolean remember = false;
        //            AlertDialog.Builder builder = new AlertDialog.Builder(WebViewActivity.this);
        //            builder.setTitle("Locations");
        //            builder.setMessage("Would like to use your Current Location ")
        //                    .setCancelable(true).setPositiveButton("Allow", new DialogInterface.OnClickListener() {
        //                public void onClick(DialogInterface dialog, int id) {
        //                    // origin, allow, remember
        //                    callback.invoke(origin, true, remember);
        //                }
        //            }).setNegativeButton("Don't Allow", new DialogInterface.OnClickListener() {
        //                public void onClick(DialogInterface dialog, int id) {
        //                    // origin, allow, remember
        //                    callback.invoke(origin, false, remember);
        //                }
        //            });
        //            AlertDialog alert = builder.create();
        //            alert.show();
                }
            }
    
            /**
             * WebViewClient subclass loads all hyperlinks in the existing WebView
             */
            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;
                }
    
                Dialog loadingDialog = new Dialog(WebViewActivity.this);
    
                @Override
                public void onPageStarted(WebView view, String url, Bitmap favicon) {
                    super.onPageStarted(view, url, favicon);
                    webViewPreviousState = PAGE_STARTED;
    
                    if (loadingDialog == null || !loadingDialog.isShowing())
                        loadingDialog = ProgressDialog.show(WebViewActivity.this, "",
                                "Loading Please Wait", true, true,
                                new DialogInterface.OnCancelListener() {
    
                                    @Override
                                    public void onCancel(DialogInterface dialog) {
                                        // do something
                                    }
                                });
    
                    loadingDialog.setCancelable(false);
                }
    
    
                @RequiresApi(api = Build.VERSION_CODES.M)
                @Override
                public void onReceivedError(WebView view, WebResourceRequest request,
                                            WebResourceError error) {
    
    
                    if (isConnected()) {
                        final Snackbar snackBar = Snackbar.make(rootView, "onReceivedError : " + error.getDescription(), Snackbar.LENGTH_INDEFINITE);
                        snackBar.setAction("Reload", new View.OnClickListener() {
                            @Override
                            public void onClick(View view) {
                                webView.loadUrl("javascript:window.location.reload( true )");
                            }
                        });
                        snackBar.show();
                    } else {
                        final Snackbar snackBar = Snackbar.make(rootView, "No Internet Connection ", Snackbar.LENGTH_INDEFINITE);
                        snackBar.setAction("Enable Data", new View.OnClickListener() {
                            @Override
                            public void onClick(View view) {
                                startActivityForResult(new Intent(Settings.ACTION_WIRELESS_SETTINGS), 0);
                                webView.loadUrl("javascript:window.location.reload( true )");
                                snackBar.dismiss();
                            }
                        });
                        snackBar.show();
                    }
    
                    super.onReceivedError(view, request, error);
    
                }
    
                @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
                @Override
                public void onReceivedHttpError(WebView view,
                                                WebResourceRequest request, WebResourceResponse errorResponse) {
    
                    if (isConnected()) {
                        final Snackbar snackBar = Snackbar.make(rootView, "HttpError : " + errorResponse.getReasonPhrase(), Snackbar.LENGTH_INDEFINITE);
    
                        snackBar.setAction("Reload", new View.OnClickListener() {
                            @Override
                            public void onClick(View view) {
                                webView.loadUrl("javascript:window.location.reload( true )");
                            }
                        });
                        snackBar.show();
                    } else {
                        final Snackbar snackBar = Snackbar.make(rootView, "No Internet Connection ", Snackbar.LENGTH_INDEFINITE);
                        snackBar.setAction("Enable Data", new View.OnClickListener() {
                            @Override
                            public void onClick(View view) {
                                startActivityForResult(new Intent(Settings.ACTION_WIRELESS_SETTINGS), 0);
                                webView.loadUrl("javascript:window.location.reload( true )");
                                snackBar.dismiss();
                            }
                        });
                        snackBar.show();
                    }
                    super.onReceivedHttpError(view, request, errorResponse);
                }
    
                @Override
                public void onPageFinished(WebView view, String url) {
    
                    if (webViewPreviousState == PAGE_STARTED) {
    
                        if (null != loadingDialog) {
                            loadingDialog.dismiss();
                            loadingDialog = null;
                        }
                    }
                }
            }
    
    
            /**
             * Check if there is any connectivity
             *
             * @return is Device Connected
             */
            public boolean isConnected() {
    
                ConnectivityManager cm = (ConnectivityManager)
                        this.getSystemService(Context.CONNECTIVITY_SERVICE);
    
                if (null != cm) {
                    NetworkInfo info = cm.getActiveNetworkInfo();
                    return (info != null && info.isConnected());
                }
    
                return false;
    
            }
    
            @Override
            public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
                switch (requestCode) {
                    case REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS: {
                        Map<String, Integer> perms = new HashMap<String, Integer>();
                        // Initial
                        perms.put(Manifest.permission.ACCESS_FINE_LOCATION, PackageManager.PERMISSION_GRANTED);
    
    
                        // Fill with results
                        for (int i = 0; i < permissions.length; i++)
                            perms.put(permissions[i], grantResults[i]);
    
                        // Check for ACCESS_FINE_LOCATION
                        if (perms.get(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
    
    
                                ) {
                            // All Permissions Granted
    
                            // Permission Denied
                            Toast.makeText(WebViewActivity.this, "All Permission GRANTED !! Thank You :)", Toast.LENGTH_SHORT)
                                    .show();
    
                        } else {
                            // Permission Denied
                            Toast.makeText(WebViewActivity.this, "One or More Permissions are DENIED Exiting App :(", Toast.LENGTH_SHORT)
                                    .show();
    
                            finish();
                        }
                    }
                    break;
                    default:
                        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
                }
            }
    
            @TargetApi(Build.VERSION_CODES.M)
            private void fuckMarshMallow() {
                List<String> permissionsNeeded = new ArrayList<String>();
    
                final List<String> permissionsList = new ArrayList<String>();
                if (!addPermission(permissionsList, Manifest.permission.ACCESS_FINE_LOCATION))
                    permissionsNeeded.add("Show Location");
    
                if (permissionsList.size() > 0) {
                    if (permissionsNeeded.size() > 0) {
    
                        // Need Rationale
                        String message = "App need access to " + permissionsNeeded.get(0);
    
                        for (int i = 1; i < permissionsNeeded.size(); i++)
                            message = message + ", " + permissionsNeeded.get(i);
    
                        showMessageOKCancel(message,
                                new DialogInterface.OnClickListener() {
    
                                    @Override
                                    public void onClick(DialogInterface dialog, int which) {
                                        requestPermissions(permissionsList.toArray(new String[permissionsList.size()]),
                                                REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS);
                                    }
                                });
                        return;
                    }
                    requestPermissions(permissionsList.toArray(new String[permissionsList.size()]),
                            REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS);
                    return;
                }
    
                Toast.makeText(WebViewActivity.this, "No new Permission Required- Launching App .You are Awesome!!", Toast.LENGTH_SHORT)
                        .show();
            }
    
    
            private void showMessageOKCancel(String message, DialogInterface.OnClickListener okListener) {
                new AlertDialog.Builder(WebViewActivity.this)
                        .setMessage(message)
                        .setPositiveButton("OK", okListener)
                        .setNegativeButton("Cancel", null)
                        .create()
                        .show();
            }
    
            @TargetApi(Build.VERSION_CODES.M)
            private boolean addPermission(List<String> permissionsList, String permission) {
    
                if (checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {
                    permissionsList.add(permission);
                    // Check for Rationale Option
                    if (!shouldShowRequestPermissionRationale(permission))
                        return false;
                }
                return true;
            }
        }
    
    0 讨论(0)
提交回复
热议问题