2010-03-05 14 views
10

Attualmente sto riscontrando un problema con la geolocalizzazione in una visualizzazione Web. Ho una webapp. Attualmente non sto usando PhoneGap o qualsiasi altro framework mobile. Non sono riuscito a ottenere la javascript api di geolocalizzazione html5 integrata per lavorare su un'applicazione che viene eseguita in una webview in un'app Android. Il sito funziona bene altrimenti dal browser Chrome su Android 2.0+ (geolocalizzazione supportato).Android: utilizzo di html5 per determinare la geolocalizzazione in webview con javascript api

Sto compilando contro versione Android API 5.

Ho letto this post già

soluzione PhoneGap di scrivere un proxy che avvolge il costruito in chiamata e utilizza l'attività di host invece è buona, ma preferirei usare il built-in per la webview (webkit) senza usare il gap telefonico.

ho impostato le autorizzazioni appropriate nel file manifesto:

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

Ecco un frammento di codice di esempio:

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

Qualcun altro ha avuto problemi nel far funzionare un'applicazione web nella webview?

+0

avete esempi di HTML/JavaScript che si sta utilizzando. Come dovrebbe funzionare .... Tieni presente che Chrome ha appena ottenuto la geolocalizzazione nel canale dev. – Kinlan

+0

Esiste una soluzione aggiornata a questo problema? –

risposta

8

Aggiungi onGeolocationPermissionsShowPrompt() al MyChromeWebViewClient come di seguito:

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

è necessario importare "android.webkit.GeolocationPermissions".

Aggiungi questa autorizzazione:

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

Questo funzionerà immagino.

+0

Grazie, mi mancava la funzione "WebChromeClient"! – AAlferez

1

Il tuo problema potrebbe essere lo stesso con Android WebView using Geolocation.
Penso HTML5 utilizzano database locale, quindi è necessario aggiungere alcuni requisiti HTML5 come questo

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

Hai fatto provare questa classe 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

Condividere il mio lavoro classe di attività, questa è una soluzione completa che può dimostrare la finestra di caricamento

  • Mostrando mentre la pagina web si sta caricando
  • chiedere il permesso a marshmallow e soprattutto
  • maniglia errore pagina web
  • verificare la connessione Internet e aprire la pagina di impostazione
  • Han dling il permesso Geolocalizzazione con e senza finestra

spero che risparmiare tempo di qualcuno

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