ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

使用GeolocationPermissions的Android WebView

2019-12-08 04:24:27  阅读:279  来源: 互联网

标签:geolocation webview android


我在这里查看了有关此问题的各种问题,例如:

> Using navigator.geolocation.getCurrentPosition in WebView on Android 2.0+ (PhoneGap related)
> android webview geolocation
> Android: Using html5 to determine geolocation in webview with javascript api

但是我还是有点困惑,我知道我应该从抽象类WebChromeClient创建自己的类.哪个获取位置,但是此对象如何从那里确切地向webView发送地理位置信息/它们如何通信?

这是我的代码:(这至少在正确的轨道上吗?)

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.webkit.GeolocationPermissions.Callback;
import android.webkit.JsResult;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.webkit.GeolocationPermissions;

public class site extends Activity {
WebView engine;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);


    WebViewClient yourWebClient = new WebViewClient() {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            if (url.contains("tel:") == true) { 
                Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse(url)); 
                startActivity(intent); 
            }
            else if(url.contains("visitchicagosouthland") == true) {
                view.loadUrl(url);
            }

//Here is where I create my object, I did this because I only need the location when this
//page is loaded. Could this be part of the problem?

            else if(url.contains("directions.cfm") == true) {
                GeoClient geo = new GeoClient();
                engine.setWebChromeClient(geo);        
                String origin = ""; //how to get origin in correct format?
                Callback call = null;
                geo.onGeolocationPermissionsShowPrompt(origin, call );  
            }
            else {
                /*Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("url")); 
                startActivity(browserIntent);*/
            }
        return true;
        }
    };


    engine = (WebView) findViewById(R.id.web_engine);
    engine.getSettings().setJavaScriptEnabled(true);
    engine.getSettings().setBuiltInZoomControls(true);
    engine.getSettings().setSupportZoom(true); 
    engine.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
    engine.getSettings().setGeolocationEnabled(true);
    engine.setWebViewClient(yourWebClient);
    engine.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);
    engine.loadUrl("http://www.visitchicagosouthland.com/jrudnydev/phone/");
}



@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.home, menu);
    return true;
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if ((keyCode == KeyEvent.KEYCODE_BACK) && engine.canGoBack()) {
        engine.goBack();
        return true;
    }
    return super.onKeyDown(keyCode, event);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle item selection
    if(item.getItemId() == R.id.home) {
        engine.loadUrl("http://www.visitchicagosouthland.com/mobile/");
        return true;
    }
    else if(item.getItemId() == R.id.refresh) {
            engine.reload();
            return true;
    }
    else if(item.getItemId() == R.id.stop) {
            engine.stopLoading();
            return true;
    }
    else {
        return super.onOptionsItemSelected(item);
    }
}

}

final class GeoClient 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(null);
    alertBldr.setMessage(message);
    alertBldr.setTitle("Alert");
    alertBldr.show();
    result.confirm();
    return true;
}

@Override
public void onGeolocationPermissionsShowPrompt(String origin, Callback callback) {
// TODO Auto-generated method stub
super.onGeolocationPermissionsShowPrompt(origin, callback);
callback.invoke(origin, true, false);
}

}

我的android-manifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  package="com.visitchicagosouthland"
  android:versionCode="1"
  android:versionName="1.0">

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_GPS" />
<uses-permission android:name="android.permission.ACCESS_ASSISTED_GPS" />
<uses-permission android:name="android.permission.ACCESS_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

<application android:icon="@drawable/icon" android:label="@string/app_name">
    <activity android:name=".site"
              android:label="@string/app_name"
              android:theme="@android:style/Theme.NoTitleBar">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

</application>
<uses-sdk android:minSdkVersion="4" />

</manifest> 

解决方法:

如果html是您自己的,这很简单.有几种方法,我将给您2种.

使用GET的简单方法

想法是在URL中发送位置(您可能需要一些编码,但只要是数字且没有空格,就可以了)

您的ShouldOverridUrlLoading的一些编辑

public boolean shouldOverrideUrlLoading(WebView view, String url){
    if (url.needs_geo) //meaning if this is the url that needs the geo location
        url += "?geo=" + your_location;
    view.loadUrl(url);
    return true;
}

在您的JavaScript中:

function getParam(name)
{
  name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
  var regexS = "[\\?&]"+name+"=([^&#]*)";
  var regex = new RegExp( regexS );
  var results = regex.exec( window.location.href );
  if( results == null )
    return "";
  else
    return results[1];
}

然后

var geo_location = getParam('geo');

使用WebView.addJavascriptInterface

(我从未尝试过将值从Java传递给JavaScript,但也可能会起作用).这个想法是为您的JavaScript提供Java类,可以访问该Java类以获得要传递给JavaScript的参数.

在您的Activity类中:

public String location; //as an example

    public class SherifJS {
        public String getLocation(){
            return location;
        }
    }
//bla bla

    SherifJS loc = new SherifJS();
    yourWebView.addJavascriptInterface(loc, "locationProvider"); 

在您的JavaScript中:

<script type="text/javascript">
        <!--

function sherifJS() {
    document.getElementById("locationHolder").innerHTML =
    window.locationProvider.getLocation();
}

        -->
</script> 

标签:geolocation,webview,android
来源: https://codeday.me/bug/20191208/2088892.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有