[wish&bug]webview

icefairy333

Active Member
Licensed User
Longtime User
please add
B4X:
((WebView)getObject()).setWebChromeClient(new WebChromeClient(){………………})
in the b4a webview wrapper because there are much web page have to use this,I had encounter much times come to this:BangHead::BangHead:
for example:no alert(maybe the js after "alert" will not be execute) no matter the js attribute is on or off.
 

warwound

Expert
Licensed User
Longtime User
To use that method in B4A you'd also need to be able to create an instance of WebChromeClient in B4A.
I'm not sure if that is possible - being able to override each of the available callback methods of the WebChromeClient.

The standard B4A WebView has no WebChromeClient, my WebViewExtras allows you to add one but the WebChromeClient it allows you to add is hardcoded in functionality.

Here's the source code of the WebViewExtras addWebChromeClient method:

B4X:
   /**
    * Add a WebChromeClient to WebView1.
    * The WebChromeClient will handle console logging and javascript modal dialogs.
    * It also overrides the default onExceededDatabaseQuota method, which enables the WebView to create and use the Database Storage API.
    * 
    * WebView1 - The WebView to add the WebChromeClient to.
    */
   public static final void addWebChromeClient(final BA pBA, final WebView WebView1, final String EventName) {
      WebView1.setWebChromeClient(new WebChromeClient() {
   
         @Override
         public boolean onConsoleMessage(final ConsoleMessage consoleMessage1) {
            String logMessage = consoleMessage1.message() + " in " + consoleMessage1.sourceId() + " (Line: " + consoleMessage1.lineNumber() + ")";
            switch (consoleMessage1.messageLevel()) {
            case DEBUG:
               Log.d("B4A", logMessage);
               break;
            case ERROR:
               Log.e("B4A", logMessage);
               break;
            case LOG:
               Log.i("B4A", logMessage);
               break;
            case TIP:
               Log.v("B4A", logMessage);
               break;
            case WARNING:
               Log.w("B4A", logMessage);
               break;
            default:
               // log all other message types with Log.i (info)
               // this condition currently will never occur but is included for future compatibility
               Log.i("B4A", logMessage);
            }
            return true;
         }
   
         @Override
         public void onExceededDatabaseQuota(String url, String databaseIdentifier, long currentQuota, long estimatedSize, long totalUsedQuota,
               WebStorage.QuotaUpdater quotaUpdater) {
            quotaUpdater.updateQuota(estimatedSize * 2);
         }
   
         @Override
         public void onGeolocationPermissionsShowPrompt(String pOrigin, Callback pCallback) {
            //   default does nothing
            //   super.onGeolocationPermissionsShowPrompt(pOrigin, pCallback);
            
            //   Log.d("B4A", "onGeolocationPermissionsShowPrompt");
            
            //   auto allow permission but do not remember
            //   parameters are origin, allow, remember
            
            //   handle permission in B4A
            int permission=(Integer) pBA.raiseEvent(this, EventName.toLowerCase(BA.cul)+"_geolocationpermissionsrequest", new Object[0]);
            
            switch(permission){
               case GEOLOCATION_PERMISSION_ALLOW:{
                  pCallback.invoke(pOrigin, true, false);
                  break;
               }
               case GEOLOCATION_PERMISSION_ALLOW_AND_REMEMBER:{
                  pCallback.invoke(pOrigin, true, true);
                  break;
               }
               case GEOLOCATION_PERMISSION_DISALLOW:{
                  pCallback.invoke(pOrigin, false, false);
                  break;
               }
               case GEOLOCATION_PERMISSION_DISALLOW_AND_REMEMBER:{
                  pCallback.invoke(pOrigin, false, true);
               }
            }
         }
         
         // For Android 3.0+
         public void openFileChooser(final ValueCallback<Uri> pUloadMessage, String pAcceptType) {
            Log.d("B4A", "openFileChooser 3.00+");
            Intent i = new Intent(Intent.ACTION_GET_CONTENT);
            i.addCategory(Intent.CATEGORY_OPENABLE);
   
            //   i.setType("image/*");   //   original code
            i.setType(pAcceptType); //   my code
   
            IOnActivityResult IOnActivityResult1 = new IOnActivityResult() {
               @Override
               public void ResultArrived(int pResultCode, Intent pIntent) {
                  //   pResultCode 0 is cancelled, -1 is file chosen?
   
                  Log.d("B4A", "ResultArrived");
                  Log.d("B4A", "pResultCode=" + pResultCode);
   
                  if (pIntent == null) {
                     pUloadMessage.onReceiveValue(null);
                  } else {
                     pUloadMessage.onReceiveValue(pIntent.getData());
                  }
               }
            };
   
            pBA.startActivityForResult(IOnActivityResult1, Intent.createChooser(i, "Select a file"));
         }
   
         // For Android < 3.0
         @SuppressWarnings("unused")
         public void openFileChooser(ValueCallback<Uri> pUploadMessage) {
            Log.d("B4A", "openFileChooser < 3.00");
            openFileChooser(pUploadMessage, "*/*");
         }
      });
   }

My comments ought to be generally disregarded - they just remnants of updates and don't make much sense!

Martin.
 

icefairy333

Active Member
Licensed User
Longtime User
thanks I know this library,but I think it's a small bug with native webview in b4a,I think Erel should add this to the core library.thanks.

To use that method in B4A you'd also need to be able to create an instance of WebChromeClient in B4A.
I'm not sure if that is possible - being able to override each of the available callback methods of the WebChromeClient.

The standard B4A WebView has no WebChromeClient, my WebViewExtras allows you to add one but the WebChromeClient it allows you to add is hardcoded in functionality.

Here's the source code of the WebViewExtras addWebChromeClient method:

B4X:
   /**
    * Add a WebChromeClient to WebView1.
    * The WebChromeClient will handle console logging and javascript modal dialogs.
    * It also overrides the default onExceededDatabaseQuota method, which enables the WebView to create and use the Database Storage API.
    * 
    * WebView1 - The WebView to add the WebChromeClient to.
    */
   public static final void addWebChromeClient(final BA pBA, final WebView WebView1, final String EventName) {
      WebView1.setWebChromeClient(new WebChromeClient() {
   
         @Override
         public boolean onConsoleMessage(final ConsoleMessage consoleMessage1) {
            String logMessage = consoleMessage1.message() + " in " + consoleMessage1.sourceId() + " (Line: " + consoleMessage1.lineNumber() + ")";
            switch (consoleMessage1.messageLevel()) {
            case DEBUG:
               Log.d("B4A", logMessage);
               break;
            case ERROR:
               Log.e("B4A", logMessage);
               break;
            case LOG:
               Log.i("B4A", logMessage);
               break;
            case TIP:
               Log.v("B4A", logMessage);
               break;
            case WARNING:
               Log.w("B4A", logMessage);
               break;
            default:
               // log all other message types with Log.i (info)
               // this condition currently will never occur but is included for future compatibility
               Log.i("B4A", logMessage);
            }
            return true;
         }
   
         @Override
         public void onExceededDatabaseQuota(String url, String databaseIdentifier, long currentQuota, long estimatedSize, long totalUsedQuota,
               WebStorage.QuotaUpdater quotaUpdater) {
            quotaUpdater.updateQuota(estimatedSize * 2);
         }
   
         @Override
         public void onGeolocationPermissionsShowPrompt(String pOrigin, Callback pCallback) {
            //   default does nothing
            //   super.onGeolocationPermissionsShowPrompt(pOrigin, pCallback);
            
            //   Log.d("B4A", "onGeolocationPermissionsShowPrompt");
            
            //   auto allow permission but do not remember
            //   parameters are origin, allow, remember
            
            //   handle permission in B4A
            int permission=(Integer) pBA.raiseEvent(this, EventName.toLowerCase(BA.cul)+"_geolocationpermissionsrequest", new Object[0]);
            
            switch(permission){
               case GEOLOCATION_PERMISSION_ALLOW:{
                  pCallback.invoke(pOrigin, true, false);
                  break;
               }
               case GEOLOCATION_PERMISSION_ALLOW_AND_REMEMBER:{
                  pCallback.invoke(pOrigin, true, true);
                  break;
               }
               case GEOLOCATION_PERMISSION_DISALLOW:{
                  pCallback.invoke(pOrigin, false, false);
                  break;
               }
               case GEOLOCATION_PERMISSION_DISALLOW_AND_REMEMBER:{
                  pCallback.invoke(pOrigin, false, true);
               }
            }
         }
         
         // For Android 3.0+
         public void openFileChooser(final ValueCallback<Uri> pUloadMessage, String pAcceptType) {
            Log.d("B4A", "openFileChooser 3.00+");
            Intent i = new Intent(Intent.ACTION_GET_CONTENT);
            i.addCategory(Intent.CATEGORY_OPENABLE);
   
            //   i.setType("image/*");   //   original code
            i.setType(pAcceptType); //   my code
   
            IOnActivityResult IOnActivityResult1 = new IOnActivityResult() {
               @Override
               public void ResultArrived(int pResultCode, Intent pIntent) {
                  //   pResultCode 0 is cancelled, -1 is file chosen?
   
                  Log.d("B4A", "ResultArrived");
                  Log.d("B4A", "pResultCode=" + pResultCode);
   
                  if (pIntent == null) {
                     pUloadMessage.onReceiveValue(null);
                  } else {
                     pUloadMessage.onReceiveValue(pIntent.getData());
                  }
               }
            };
   
            pBA.startActivityForResult(IOnActivityResult1, Intent.createChooser(i, "Select a file"));
         }
   
         // For Android < 3.0
         @SuppressWarnings("unused")
         public void openFileChooser(ValueCallback<Uri> pUploadMessage) {
            Log.d("B4A", "openFileChooser < 3.00");
            openFileChooser(pUploadMessage, "*/*");
         }
      });
   }

My comments ought to be generally disregarded - they just remnants of updates and don't make much sense!

Martin.
 

warwound

Expert
Licensed User
Longtime User
@warwound, note that it is better to call BA.Log(...).

Otherwise the messages will not show on Android 4.1+ devices when connected in Bridge mode.

Ok, i'll get that updated over the next couple of days.

Martin.
 

warwound

Expert
Licensed User
Longtime User
@warwound, note that it is better to call BA.Log(...).

Otherwise the messages will not show on Android 4.1+ devices when connected in Bridge mode.

I was just about to update the WebChromeClient to use BA.Log then realised that the update would simply log all console messages with the same log level.

Currently a console message is logged according to the console message 'message level':

B4X:
switch (consoleMessage1.messageLevel()) {
            case DEBUG:
               Log.d("B4A", logMessage);
               break;
            case ERROR:
               Log.e("B4A", logMessage);
               break;
            case LOG:
               Log.i("B4A", logMessage);
               break;
            case TIP:
               Log.v("B4A", logMessage);
               break;
            case WARNING:
               Log.w("B4A", logMessage);
               break;
            default:
               Log.i("B4A", logMessage);
            }

Is there any way to maintain this logging according to message level by using a B4A method?

Martin.
 

warwound

Expert
Licensed User
Longtime User
Ok, i've now updated WebViewExtras so that it uses the BA.Log method.

Martin.
 
Top