Android: использование html5 для определения геолокации в webview с помощью javascript api

В настоящее время у меня проблема с геолокацией в веб-просмотре. У меня есть webapp. В настоящее время я не использую телефонную развязку или другие мобильные рамки. Мне не удалось получить встроенный JavaScript html5 javascript api для работы над приложением, которое работает в веб-браузере в приложении для Android. В противном случае сайт работает отлично от браузера Chrome на android 2.0+ (поддерживается геолокация).

Я собираюсь против android api версии 5.

Я уже прочитал это сообщение

Решение Phonegap о написании прокси-сервера, которое обертывает встроенный вызов и использует хост-активность, является хорошим, но я бы предпочел использовать встроенный веб-просмотр (webkit) без использования пробела в телефоне.

Я установил правильные разрешения в файле манифеста:

<uses-permission android:name="android.permission.INTERNET" /> <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" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> 

Вот пример фрагмента кода:

 webview = (WebView) findViewById(R.id.webview); pbarDialog = new ProgressDialog(this); pbarDialog.setCancelable(false); pbarDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); webview.setWebViewClient(new MyWebViewClient()); webview.getSettings().setJavaScriptEnabled(true); webview.setWebChromeClient(new MyChromeWebViewClient()); webview.setVerticalScrollBarEnabled(false); WebSettings webSettings = webview.getSettings(); webSettings.setSavePassword(true); webSettings.setSaveFormData(true); webSettings.setJavaScriptEnabled(true); webSettings.setSupportZoom(false); webSettings.setJavaScriptCanOpenWindowsAutomatically(true); webSettings.setGeolocationEnabled(true); 

 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; } } private class MyWebViewClient extends WebViewClient { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { view.loadUrl(url); return true; } @Override public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { } } 

У кого-нибудь еще были проблемы с получением веб-приложения для работы в веб-просмотре?

Solutions Collecting From Web of "Android: использование html5 для определения геолокации в webview с помощью javascript api"

Добавьте onGeolocationPermissionsShowPrompt() в MyChromeWebViewClient как MyChromeWebViewClient ниже:

 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); } } 

Вам нужно импортировать « android.webkit.GeolocationPermissions ».

Добавьте это разрешение:

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

Это будет работать, я думаю.

Ваша проблема может быть той же проблемой с Android WebView с использованием Geolocation .
Я думаю, что HTML5 использует локальную базу данных, поэтому вам нужно добавить некоторые требования HTML5, подобные этому

 // HTML5 API flags webView.getSettings().setAppCacheEnabled(true); webView.getSettings().setDatabaseEnabled(true); webView.getSettings().setDomStorageEnabled(true); 

Вы пробовали этот класс html5webview .

 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); } 

Разделяя мой класс рабочей деятельности, это полное решение, которое может продемонстрировать

  • Отображение диалогового окна загрузки при загрузке веб-страницы
  • Запросите разрешение в зефире и выше
  • Ошибка обработки веб-страницы
  • Проверьте подключение к Интернету и откройте страницу настроек
  • Разрешение разрешения на геолокацию с диалогом и без него

Надеюсь, это спасет чье-то время

  /** * 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; } }