【问题标题】:Turn on GPS function webview开启 GPS 功能 webview
【发布时间】:2019-01-29 16:58:14
【问题描述】:

我的网站有一个 webView 需要访问用户位置,它通过按下按钮并在表单中显示位置来实现。我需要一种来自 webView 的方法来询问用户在单击按钮时是否打开 gps(它有id="locate button")。如何在 Android Studio 中做到这一点?

我的代码:

MainActivity.java

public class MainActivity extends AppCompatActivity {

private WebView webview;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    ActivityCompat.requestPermissions(this, new String[]{
            Manifest.permission.ACCESS_FINE_LOCATION,
            Manifest.permission.ACCESS_COARSE_LOCATION
    }, 0);

    webview = (WebView) findViewById(R.id.webView);

    webview.setWebViewClient(new WebViewClient());
    webview.getSettings().setAppCacheEnabled(true);
    webview.getSettings().setDatabaseEnabled(true);
    webview.getSettings().setJavaScriptEnabled(true);
    webview.getSettings().setDomStorageEnabled(true);
    webview.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
    webview.getSettings().setGeolocationEnabled(true);
    webview.setWebChromeClient(new WebChromeClient() {
        @Override
        public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback) {
            callback.invoke(origin, true, false);
        }
    });
    webview.setOverScrollMode(WebView.OVER_SCROLL_NEVER);

    webview.setWebViewClient(new WebViewClient() {
        @Override
        public void onPageFinished(WebView view, String url)
        {
            // hide element by class name
            webview.loadUrl("javascript:(function() { " + "document.getElementsByClassName('menu-icone-container')[0].style.display='none';  })()");
        }
    });
    webview.loadUrl("http://www.example.it");
}

编辑: 我找到了一种方法来检查 gps 是否已关闭并提示用户进行 gps 设置,但我只能在应用程序启动时调用此方法,而不是在我按下按钮时调用此方法

 public void CheckEnableGPS() {
    String provider = Settings.Secure.getString(getContentResolver(),
            Settings.Secure.LOCATION_PROVIDERS_ALLOWED);
    if (!provider.contains("gps")){
        showSettingAlert();
    }

}

public void showSettingAlert()
{
    AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);
    alertDialog.setTitle("Impostazioni GPS");
    alertDialog.setMessage("Per ottenere la posizione corrente il GPS deve essere attivo, attivarlo?");
    alertDialog.setPositiveButton("Impostazioni", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
            startActivity(intent);
        }
    });
    alertDialog.setNegativeButton("Annulla", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            dialog.cancel();
        }
    });
    alertDialog.show();
}

【问题讨论】:

  • 看看android.webkit.JavascriptInterface注解。我不记得具体如何使用它,所以我不把它作为答案。
  • @dedda1994 我已经读过它,它可能是答案,但我无法让它工作

标签: java android webview geolocation gps


【解决方案1】:

最适合我的解决方案和完美的工作

当 NearBy 按钮或任何地理位置权限按钮点击链接时,WebView 将询问 GPS 权限。

1.首先我们必须使用 WebChromeClient 调用 GeolocationPermissions.Callback

webView.setWebChromeClient(new WebChromeClient() {

            @Override
            public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback) {
                Log.i(TAG, "onGeolocationPermissionsShowPrompt()");

                final boolean remember = false;
                AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this, R.style.MyAlertDialogStyle);
                      builder.setTitle("Locations");
                      builder.setIcon(R.mipmap.ic_launcher);
                      builder.setMessage("Would like to use your Current Location ")
                             .setCancelable(true).setPositiveButton("Allow", (dialog, id) -> {
                                  // origin, allow, remember
                                 callback.invoke(origin, true, remember);

                                 displayLocationSettingsRequest();

                                 int result = ContextCompat.checkSelfPermission(getBaseContext(), Manifest.permission.ACCESS_COARSE_LOCATION);
                                 if (result == PackageManager.PERMISSION_GRANTED) {

                                 } else {
                                     ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION}, 101);
                                 }

                          }).setNegativeButton("Don't Allow", (dialog, id) -> {
                          // origin, allow, remember
                                callback.invoke(origin, false, remember);
                          });
                         AlertDialog alert = builder.create();
                           alert.show();
            }
}
  1. 当用户单击允许 GPS 权限时,WebView 将调用 GPS 设置函数,在我的情况下为 displayLocationSettingsRequest();

3.为LocationSettingsRequest添加GoogleApiClient

private void displayLocationSettingsRequest() {
        GoogleApiClient googleApiClient = new GoogleApiClient.Builder(this)
                .addApi(LocationServices.API).build();
        googleApiClient.connect();
        final String TAG = "YOUR-TAG-NAME";
        final int REQUEST_CHECK_SETTINGS = 0x1;

        LocationRequest locationRequest = LocationRequest.create();
        locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        locationRequest.setInterval(10000);
        locationRequest.setFastestInterval(10000 / 2);

        LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder().addLocationRequest(locationRequest);
        builder.setAlwaysShow(true);

        PendingResult<LocationSettingsResult> result = LocationServices.SettingsApi.checkLocationSettings(googleApiClient, builder.build());
        result.setResultCallback(result1 -> {
            final Status status = result1.getStatus();
            switch (status.getStatusCode()) {
                case LocationSettingsStatusCodes.SUCCESS:
                    Log.i(TAG, "All location settings are satisfied.");
                    break;
                case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                    Log.i(TAG, "Location settings are not satisfied. Show the user a dialog to upgrade location settings ");

                    try {
                        // Show the dialog by calling startResolutionForResult(), and check the result
                        // in onActivityResult().
                        status.startResolutionForResult(MainActivity.this, REQUEST_CHECK_SETTINGS);
                    } catch (IntentSender.SendIntentException e) {
                        Log.i(TAG, "PendingIntent unable to execute request.");
                    }
                    break;
                case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                    Log.i(TAG, "Location settings are inadequate, and cannot be fixed here. Dialog not created.");
                    break;
            }
        });
    }

4.允许清单上的权限

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

5.使用 android 6+,您只需在运行时请求 GPS 权限作为安全措施使用

在 onCreate 中添加这个

ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);

在活动中添加这个

public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
    switch (requestCode) {
        case 1: {
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0
            && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

            } else {
                // permission denied, boo! Disable the
                // functionality that depends on this permission.
            }
        return;
        }
            // other 'case' lines to check for other
            // permissions this app might request
    }
}

【讨论】:

    【解决方案2】:

    使用此代码提示用户启用位置设置,它不需要用户打开手机的设置窗口:

    private void displayLocationSettingsRequest(Context context) {
        GoogleApiClient googleApiClient = new GoogleApiClient.Builder(context)
                .addApi(LocationServices.API).build();
        googleApiClient.connect();
        final String TAG = "YOUR-TAG-NAME";
        final int REQUEST_CHECK_SETTINGS = 0x1;
    
        LocationRequest locationRequest = LocationRequest.create();
        locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        locationRequest.setInterval(10000);
        locationRequest.setFastestInterval(10000 / 2);
    
        LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder().addLocationRequest(locationRequest);
        builder.setAlwaysShow(true);
    
        PendingResult<LocationSettingsResult> result = LocationServices.SettingsApi.checkLocationSettings(googleApiClient, builder.build());
        result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
            @Override
            public void onResult(LocationSettingsResult result) {
                final Status status = result.getStatus();
                switch (status.getStatusCode()) {
                    case LocationSettingsStatusCodes.SUCCESS:
                        Log.i(TAG, "All location settings are satisfied.");
                        break;
                    case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                        Log.i(TAG, "Location settings are not satisfied. Show the user a dialog to upgrade location settings ");
    
                        try {
                            // Show the dialog by calling startResolutionForResult(), and check the result
                            // in onActivityResult().
                            status.startResolutionForResult(MainActivity.this, REQUEST_CHECK_SETTINGS);
                        } catch (IntentSender.SendIntentException e) {
                            Log.i(TAG, "PendingIntent unable to execute request.");
                        }
                        break;
                    case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                        Log.i(TAG, "Location settings are inadequate, and cannot be fixed here. Dialog not created.");
                        break;
                }
            }
        });
    }
    

    【讨论】:

    • 非常感谢,但是,当我的 webview 中的按钮被点击时,我仍然需要一种方法来使用它...
    • 非常感谢您,您节省了很多时间,并且在访问该位置时不会出现此特定弹出窗口。
    【解决方案3】:

    当您的活动启动时,您可以要求用户打开他的 GPS。 第一步是创建位置请求。

          LocationRequest mLocationRequest = new LocationRequest();
          locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
          locationRequest.setInterval(1000);
          locationRequest.setFastestInterval(5000);
    

    然后,您必须创建位置请求设置:

    LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
     .addLocationRequest(mLocationRequest);
    

    接下来检查是否满足当前位置设置:

    SettingsClient client = LocationServices.getSettingsClient(this);
    Task<LocationSettingsResponse> task = client.checkLocationSettings(builder.build());
    

    接下来,提示用户更改位置设置

    task.addOnSuccessListener(this, new OnSuccessListener<LocationSettingsResponse>() {
    @Override
    public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
        // All location settings are satisfied. The client can initialize
        // location requests here.
        // ...
        }
    });
    task.addOnFailureListener(this, new OnFailureListener() {
    @Override
    public void onFailure(@NonNull Exception e) {
        if (e instanceof ResolvableApiException) {
            // Location settings are not satisfied, but this can be fixed
            // by showing the user a dialog.
            try {
                // Show the dialog by calling startResolutionForResult(),
                // and check the result in onActivityResult().
                ResolvableApiException resolvable = (ResolvableApiException) e;
                resolvable.startResolutionForResult(MainActivity.this,
                        REQUEST_CHECK_SETTINGS);
            } catch (IntentSender.SendIntentException sendEx) {
                // Ignore the error.
            }
        }
    }
    });
    

    请查看官方文档:Link

    【讨论】:

      猜你喜欢
      • 2020-10-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-18
      相关资源
      最近更新 更多