2010-03-05 22 views
10

Actualmente estoy teniendo un problema con la geolocalización en una vista web. Tengo una aplicación web. Actualmente no estoy usando phonegap ni ningún otro framework móvil. No he tenido éxito al obtener la aplicación JavaScript javascript html5 incorporada para trabajar en una aplicación que se ejecuta en una vista web en una aplicación de Android. El sitio funciona bien de lo contrario desde el navegador Chrome en Android 2.0+ (geolocalización compatible).Android: el uso de html5 para determinar la geolocalización en la vista web con javascript api

Estoy compilando contra la versión de Android API 5.

He leído this post ya

solución de escribir un proxy que envuelve el construido en la llamada y utiliza la actividad de host en lugar de Phonegap es bueno, pero preferiría usar el built-in en la vista web (webkit) sin usar la brecha telefónica.

he establecido los permisos adecuados en el archivo de manifiesto:

<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" /> 

He aquí un fragmento de código de ejemplo:

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

Alguien más ¿Ha tenido problemas para hacer que una aplicación web funcione en la vista web?

+0

tienes ejemplos de la html/javascript que está utilizando. Como debería funcionar ... Solo tenga en cuenta que Chrome acaba de obtener geolocalización en el canal de desarrollo. – Kinlan

+0

¿Hay alguna solución actualizada a este problema? –

Respuesta

8

Añadir onGeolocationPermissionsShowPrompt() a MyChromeWebViewClient de la siguiente manera:

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

debe importar "android.webkit.GeolocationPermissions".

Añadir este permiso:

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

Esto funcionará supongo.

+0

¡Gracias, me faltaba esa función 'WebChromeClient'! – AAlferez

1

Su problema puede ser el mismo problema con Android WebView using Geolocation.
creo HTML5 usar base de datos local, por lo que necesita añadir algunos requisitos HTML5 como esto

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

Hiciste tratar esta clase 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); 
} 
0

Compartir mi clase de actividad de trabajo, esta es una solución completa que puede demostrar de diálogo de carga

  • Mostrando mientras que la página web está cargando
  • pedir permiso en el malvavisco y por encima de
  • Mango error de página web
  • compruebe la conexión a Internet y la página de configuración abierta
  • Han dling permiso Geolocalización con y sin diálogo

espero que ahorrar tiempo de alguien

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