For geolocation to work on the webview

Asked

Viewed 303 times

0

I looked at several topics on this, but as my project is a little different, I couldn’t make the adaptations. I need to enable geolocation for the map of a page of my site, which is inserted via webview in my application, by computer browser or mobile phone works normally, but by the webview of the application does not provide the location.

I have "android.permission.INTERNET", "android.permission.ACCESS_FINE_LOCATION" and other manifest.xml-enabled permissions

And this is my Webviewfragment.:

public class WebviewFragment extends Fragment implements BackPressFragment, CollapseControllingFragment {

    //Static
    public static final String HIDE_NAVIGATION = "hide_navigation";
    public static final String LOAD_DATA = "loadwithdata";
    public static final boolean FORCE_HIDE_NAVIGATION = false;

    //File upload
    public static final int INPUT_FILE_REQUEST_CODE = 1;
    public static final String EXTRA_FROM_NOTIFICATION = "EXTRA_FROM_NOTIFICATION";

    private ValueCallback<Uri[]> mFilePathCallback;
    private String mCameraPhotoPath;

    //References
    private Activity mAct;
    private FavDbAdapter mDbHelper;

    //Layout with interaction
    private WebView browser;
    private SwipeRefreshLayout mSwipeRefreshLayout;

    //Layouts
    private ImageButton webBackButton;
    private ImageButton webForwButton;
    private LinearLayout ll;

    //HTML5 video
    private View mCustomView;
    private int mOriginalSystemUiVisibility;
    private WebChromeClient.CustomViewCallback mCustomViewCallback;

    @SuppressLint("InflateParams")
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        //Return the existing layout if there is a savedInstance of this fragment
        if (savedInstanceState != null) { return ll; }

        ll = (LinearLayout) inflater.inflate(R.layout.fragment_webview,
                container, false);

        setHasOptionsMenu(true);

        browser = (WebView) ll.findViewById(R.id.webView);
        mSwipeRefreshLayout = (SwipeRefreshLayout) ll.findViewById(R.id.refreshlayout);

        // settings some settings like zooming etc in seperate method for
        // suppresslint
        browserSettings();

        browser.setWebViewClient(new WebViewClient() {

            @SuppressWarnings("deprecation")
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                if (url != null && url.startsWith("whatsapp://")) {
                    view.getContext().startActivity(
                            new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
                    return true;
                } else {
                    return handleUri(url);
                }

            }



            @TargetApi(Build.VERSION_CODES.N)
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
                return handleUri(request.getUrl().toString());
            }

            // handeling errors
            @SuppressWarnings("deprecation")
            @Override
            public void onReceivedError(WebView view, int errorCode,
                                        String description, String failingUrl) {

                if (failingUrl.startsWith("file:///android_asset/") || checkConnectivity()) {
                    //It is a local error, or a we have connectivity
                } else {
                    browser.loadUrl("about:blank");
                }
            }

            // Make sure any url clicked is opened in webview
            boolean handleUri(String url) {
                if (url.contains("market://") || url.contains("mailto:")
                        || url.contains("play.google") || url.contains("tel:") || url
                        .contains("vid:") || url.contains("youtube.com")) {
                    // Load new URL Don't override URL Link
                    startActivity(
                            new Intent(Intent.ACTION_VIEW, Uri.parse(url)));

                    return true;
                }

                // Return true to override url loading (In this case do
                // nothing).
                return false;
            }

            @Override
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(browser, url);

                adjustControls();
            }

        });

        // has all to do with progress bar
        browser.setWebChromeClient(new WebChromeClient() {
            public boolean onShowFileChooser(
                    WebView webView, ValueCallback<Uri[]> filePathCallback,
                    WebChromeClient.FileChooserParams fileChooserParams) {
                if(mFilePathCallback != null) {
                    mFilePathCallback.onReceiveValue(null);
                }
                mFilePathCallback = filePathCallback;

                Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                if (takePictureIntent.resolveActivity(getActivity().getPackageManager()) != null) {
                    // Create the File where the photo should go
                    File photoFile = null;
                    try {
                        photoFile = createImageFile();
                        takePictureIntent.putExtra("PhotoPath", mCameraPhotoPath);
                    } catch (IOException ex) {
                        // Error occurred while creating the File
                    }

                    // Continue only if the File was successfully created
                    if (photoFile != null) {
                        mCameraPhotoPath = "file:" + photoFile.getAbsolutePath();
                        takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
                                Uri.fromFile(photoFile));
                    } else {
                        takePictureIntent = null;
                    }
                }

                Intent contentSelectionIntent = new Intent(Intent.ACTION_GET_CONTENT);
                contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE);
                contentSelectionIntent.setType("image/*");

                Intent[] intentArray;
                if(takePictureIntent != null) {
                    intentArray = new Intent[]{takePictureIntent};
                } else {
                    intentArray = new Intent[0];
                }

                Intent chooserIntent = new Intent(Intent.ACTION_CHOOSER);
                chooserIntent.putExtra(Intent.EXTRA_INTENT, contentSelectionIntent);
                chooserIntent.putExtra(Intent.EXTRA_TITLE, "Image Chooser");
                chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray);

                startActivityForResult(chooserIntent, INPUT_FILE_REQUEST_CODE);

                return true;
            }

            @Override
            public void onProgressChanged(WebView view, int progress) {
                if (mSwipeRefreshLayout.isRefreshing()) {
                    if (progress == 100) {
                        mSwipeRefreshLayout.setRefreshing(false);
                    }
                } else if (progress < 100){
                    //If we do not hide the navigation, show refreshing
                    if (navigationIsVisible())
                        mSwipeRefreshLayout.setRefreshing(true);
                }
            }

            @SuppressLint("InlinedApi")
            @Override
            public void onShowCustomView(View view,
                                         WebChromeClient.CustomViewCallback callback) {
                // if a view already exists then immediately terminate the new one
                if (mCustomView != null) {
                    onHideCustomView();
                    return;
                }

                // 1. Stash the current state
                mCustomView = view;
                mCustomView.setBackgroundColor(Color.BLACK);
                mOriginalSystemUiVisibility = getActivity().getWindow().getDecorView().getSystemUiVisibility();

                // 2. Stash the custom view callback
                mCustomViewCallback = callback;

                // 3. Add the custom view to the view hierarchy
                FrameLayout decor = (FrameLayout) getActivity().getWindow().getDecorView();
                decor.addView(mCustomView, new FrameLayout.LayoutParams(
                        ViewGroup.LayoutParams.MATCH_PARENT,
                        ViewGroup.LayoutParams.MATCH_PARENT));


                // 4. Change the state of the window
                getActivity().getWindow().getDecorView().setSystemUiVisibility(
                        View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
                                View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
                                View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
                                View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
                                View.SYSTEM_UI_FLAG_FULLSCREEN |
                                View.SYSTEM_UI_FLAG_IMMERSIVE);
                getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
            }

            @Override
            public void onHideCustomView() {
                // 1. Remove the custom view
                FrameLayout decor = (FrameLayout) getActivity().getWindow().getDecorView();
                decor.removeView(mCustomView);
                mCustomView = null;

                // 2. Restore the state to it's original form
                getActivity().getWindow().getDecorView()
                        .setSystemUiVisibility(mOriginalSystemUiVisibility);

                //TODO Find a better solution to the keyboard not showing after custom view is hidden
                //The user will come from landscape, so we'll first 'rotate' to portrait (rotation fixes a bug of the keybaord not showing)
                getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
                //The we'll restore to the detected orientation (by immediately rotating back, the user should not notice any difference and/or flickering).
                getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR);

                // 3. Call the custom view callback
                mCustomViewCallback.onCustomViewHidden();
                mCustomViewCallback = null;


            }

            @Override
            public Bitmap getDefaultVideoPoster() {
                return BitmapFactory.decodeResource(getResources(),
                        R.drawable.placeholder);
                //return super.getDefaultVideoPoster();
            }

        });

        browser.setDownloadListener(new DownloadListener() {
            public void onDownloadStart(String url, String userAgent,
                                        String contentDisposition, String mimetype,
                                        long contentLength) {
                Intent i = new Intent(Intent.ACTION_VIEW);
                i.setData(Uri.parse(url));
                startActivity(i);
            }
        });

        // setting an on touch listener
        browser.setOnTouchListener(new View.OnTouchListener() {
            @SuppressLint("ClickableViewAccessibility")
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                    case MotionEvent.ACTION_UP:
                        if (!v.hasFocus()) {
                            v.requestFocus();
                        }
                        break;
                }
                return false;
            }
        });

        mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                browser.reload();
            }
        });

        return ll;
    }// of oncreateview

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        mAct = getActivity();

        setRetainInstance(true);

        String weburl = getArguments().getStringArray(MainActivity.FRAGMENT_DATA)[0];
        String data = getArguments().containsKey(LOAD_DATA) ? getArguments().getString(LOAD_DATA) : null;
        if (weburl.startsWith("file:///android_asset/") || checkConnectivity()) {
            //If this is the first time, load the initial url, otherwise restore the view if necessairy
            if (savedInstanceState == null) {
                //If we have HTML data to load, do so, else load the url.
                if (data != null) {
                    browser.loadDataWithBaseURL(weburl, data, "text/html", "UTF-8", "");
                } else {
                    browser.loadUrl(weburl);
                }
            } else if (mCustomView != null){
                FrameLayout decor = (FrameLayout) getActivity().getWindow().getDecorView();
                ((ViewGroup) mCustomView.getParent()).removeView(mCustomView);
                decor.addView(mCustomView, new FrameLayout.LayoutParams(
                        ViewGroup.LayoutParams.MATCH_PARENT,
                        ViewGroup.LayoutParams.MATCH_PARENT));
            }
        }

    }

    @Override
    public void onPause() {
        super.onPause();

        if (browser != null)
            browser.onPause();
        else
            Log.e("INFO", "Browser is null");

        setMenuVisibility(false);
    }

    @Override
    public void setMenuVisibility(final boolean visible) {
        super.setMenuVisibility(visible);
        if (mAct == null) return;

        if (visible) {
            if (navigationIsVisible()){

                ActionBar actionBar = ((AppCompatActivity) mAct)
                        .getSupportActionBar();

                if (mAct instanceof HolderActivity) {
                    actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM | ActionBar.DISPLAY_SHOW_HOME | ActionBar.DISPLAY_SHOW_TITLE | ActionBar.DISPLAY_HOME_AS_UP);
                } else {
                    actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM | ActionBar.DISPLAY_SHOW_HOME | ActionBar.DISPLAY_SHOW_TITLE);
                }

                View view = mAct.getLayoutInflater().inflate(R.layout.fragment_webview_actionbar, null);
                LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, Gravity.END | Gravity.CENTER_VERTICAL);
                actionBar.setCustomView(view, lp);

                webBackButton = (ImageButton) mAct.findViewById(R.id.goBack);
                webForwButton = (ImageButton) mAct.findViewById(R.id.goForward);

                webBackButton.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        if (browser.canGoBack())
                            browser.goBack();
                    }
                });
                webForwButton.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        if (browser.canGoForward())
                            browser.goForward();
                    }
                });
            }
        } else {
            if (navigationIsVisible()
                    && getActivity() != null) {

                ActionBar actionBar = ((AppCompatActivity) getActivity())
                        .getSupportActionBar();
                actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_HOME | ActionBar.DISPLAY_SHOW_TITLE);
            }
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        if (browser != null) {
            browser.onResume();
        } else {
            FragmentTransaction ft = getFragmentManager().beginTransaction();
            ft.detach(this).attach(this).commit();
        }

        if (this.getArguments().containsKey(HIDE_NAVIGATION) &&
                this.getArguments().getBoolean(HIDE_NAVIGATION)){
            mSwipeRefreshLayout.setEnabled(false);
        }

        adjustControls();
        if (isMenuVisible() || getUserVisibleHint())
            setMenuVisibility(true);
    }

    @Override
    public void onHiddenChanged(boolean hidden) {
        super.onHiddenChanged(hidden);
        if (!hidden) {
            setMenuVisibility(true);
        }
    }

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
    }


    /**
     * More info this method can be found at
     * http://developer.android.com/training/camera/photobasics.html
     *
     * @throws IOException
     */
    private File createImageFile() throws IOException {
        // Create an image file name
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date());
        String imageFileName = "JPEG_" + timeStamp + "_";
        File storageDir = Environment.getExternalStoragePublicDirectory(
                Environment.DIRECTORY_PICTURES);
        return File.createTempFile(
                imageFileName,  /* prefix */
                ".jpg",         /* suffix */
                storageDir      /* directory */
        );
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case R.id.share:
            shareURL();
            return true;
        case R.id.favorite:
            mDbHelper = new FavDbAdapter(mAct);
            mDbHelper.open();

            String title = browser.getTitle();
            String url = browser.getUrl();

            if (mDbHelper.checkEvent(title, url, FavDbAdapter.KEY_WEB)) {
                // This item is new
                mDbHelper.addFavorite(title, url, FavDbAdapter.KEY_WEB);
                Toast toast = Toast.makeText(mAct,
                        getResources().getString(R.string.favorite_success),
                        Toast.LENGTH_LONG);
                toast.show();
            } else {
                Toast toast = Toast.makeText(mAct,
                        getResources().getString(R.string.favorite_duplicate),
                        Toast.LENGTH_LONG);
                toast.show();
            }
            return true;
        default:
            return super.onOptionsItemSelected(item);
        }
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        if (!this.getArguments().containsKey(HIDE_NAVIGATION)  ||
                !this.getArguments().getBoolean(HIDE_NAVIGATION))
        inflater.inflate(R.menu.webview_menu, menu);

        //For local urls, we don't need a share item
        if (browser.getUrl() != null && browser.getUrl().startsWith("file:///android_asset/"))
            menu.findItem(R.id.share).setVisible(false);
    }

    // Checking for an internet connection
    private boolean checkConnectivity() {
        boolean enabled = true;

        ConnectivityManager connectivityManager = (ConnectivityManager) mAct
                .getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo info = connectivityManager.getActiveNetworkInfo();

        if ((info == null || !info.isConnected() || !info.isAvailable())) {
            enabled = false;

            Helper.noConnection(mAct);
        }

        return enabled;
    }

    public void adjustControls() {
        webBackButton = (ImageButton) mAct.findViewById(R.id.goBack);
        webForwButton = (ImageButton) mAct.findViewById(R.id.goForward);

        if (webBackButton == null || webForwButton == null || browser == null) return;

        if (browser.canGoBack()) {
            webBackButton.setColorFilter(Color.argb(255, 255, 255, 255));
        } else {
            webBackButton.setColorFilter(Color.argb(255, 0, 0, 0));
        }
        if (browser.canGoForward()) {
            webForwButton.setColorFilter(Color.argb(255, 255, 255, 255));
        } else {
            webForwButton.setColorFilter(Color.argb(255, 0, 0, 0));
        }
    }

    // sharing
    private void shareURL() {
        Intent shareIntent = new Intent(Intent.ACTION_SEND);
        shareIntent.setType("text/plain");
        String appname = getString(R.string.app_name);
        shareIntent.putExtra(Intent.EXTRA_TEXT,
                (getResources().getString(R.string.web_share_begin)) + appname
                        + getResources().getString(R.string.web_share_end)
                        + browser.getUrl());
        startActivity(Intent.createChooser(shareIntent, getResources()
                .getString(R.string.share)));
    }

    @SuppressLint("SetJavaScriptEnabled")
    @SuppressWarnings("deprecation")
    private void browserSettings() {
        // set javascript and zoom and some other settings
        browser.getSettings().setJavaScriptEnabled(true);
        browser.getSettings().setBuiltInZoomControls(true);
        browser.getSettings().setDisplayZoomControls(false);
        browser.getSettings().setAppCacheEnabled(true);
        browser.getSettings().setDatabaseEnabled(true);
        browser.getSettings().setDomStorageEnabled(true);
        browser.getSettings().setUseWideViewPort(true);
        browser.getSettings().setLoadWithOverviewMode(true);

        // enable all plugins (flash)
        browser.getSettings().setPluginState(PluginState.ON);
    }

    @Override
    public boolean handleBackPress() {
        if (browser.canGoBack()){
            browser.goBack();
            return true;
        }

        return false;
    }

    @Override
    public void onActivityResult (int requestCode, int resultCode, Intent data) {
        if(requestCode != INPUT_FILE_REQUEST_CODE || mFilePathCallback == null) {
            super.onActivityResult(requestCode, resultCode, data);
            return;
        }

        Uri[] results = null;

        // Check that the response is a good one
        if(resultCode == Activity.RESULT_OK) {
            if(data == null) {
                // If there is not data, then we may have taken a photo
                if(mCameraPhotoPath != null) {
                    results = new Uri[]{Uri.parse(mCameraPhotoPath)};
                }
            } else {
                String dataString = data.getDataString();
                if (dataString != null) {
                    results = new Uri[]{Uri.parse(dataString)};
                }
            }
        }

        mFilePathCallback.onReceiveValue(results);
        mFilePathCallback = null;
    }

    @Override
    public boolean supportsCollapse() {
        return false;
    }

    public boolean navigationIsVisible(){
        //If override is on, always hide
        if (FORCE_HIDE_NAVIGATION) return true;

        //Only hide navigation if key is provided and is true
        return (!this.getArguments().containsKey(HIDE_NAVIGATION)  ||
                !this.getArguments().getBoolean(HIDE_NAVIGATION)
        );
    }
}

What should I change or insert for geolocation to work on this webview?

  • Have you looked at these cases? https://stackoverflow.com/questions/36209971/getting-location-in-webview-via-js e https://stackoverflow.com/questions/5329662/android-webview-geolocation

  • tried, tried others also found here but maybe I did something wrong and could not get the result

  • Take a look if you asked the user’s permission to access the location. And a question, you could not exchange the webview for a direct Mapfragment?

  • is that I use a page that is in wordpress, on this page I use a map similar to this one: https://superstorefinder.net/superstorefinderwp/addon/distanceradius which places places according to where the user is but different from the example, the links from these points lead to different purchase pages, in the android browser the permission request and the location work, just not in the webview of the application. So citing your suggestion to use a Mapfragment, I wouldn’t know how to deploy

No answers

Browser other questions tagged

You are not signed in. Login or sign up in order to post.