Rev 5 | Autoría | Comparar con el anterior | Ultima modificación | Ver Log |
package com.cesams.leaderslinked.v2;import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;import android.Manifest;import androidx.activity.result.ActivityResultLauncher;import androidx.activity.result.contract.ActivityResultContracts;import androidx.annotation.NonNull;import androidx.annotation.Nullable;import androidx.annotation.RequiresApi;import androidx.appcompat.app.AppCompatActivity;import androidx.core.app.ActivityCompat;import androidx.core.content.ContextCompat;import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;import androidx.core.view.ViewCompat;import androidx.core.view.WindowInsetsCompat;import android.content.pm.PackageManager;import android.annotation.SuppressLint;import android.content.Intent;import android.content.res.Configuration;import android.net.ConnectivityManager;import android.net.NetworkInfo;import android.net.Uri;import android.os.Build;import android.os.Bundle;import android.util.Log;import android.view.KeyEvent;import android.view.View;import android.webkit.JavascriptInterface;import android.webkit.ValueCallback;import android.webkit.WebChromeClient;import android.webkit.WebSettings;import android.webkit.WebView;import android.webkit.WebViewClient;import java.util.ArrayList;public class MainActivity extends AppCompatActivity {private TouchyWebView mWebView = null;private SwipeRefreshLayout mSwipeRefreshLayout;private static final String file_type = "*/*";private ValueCallback<Uri[]> file_path;private final static String _URL = BuildConfig.BASE_URL;private ActivityResultLauncher<Intent> fileChooserLauncher;@RequiresApi(api = Build.VERSION_CODES.M)@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.swipeRefreshLayout), (v, insets) -> {int top = insets.getInsets(WindowInsetsCompat.Type.systemBars()).top;int bottom = insets.getInsets(WindowInsetsCompat.Type.systemBars()).bottom;int left = insets.getInsets(WindowInsetsCompat.Type.systemBars()).left;int right = insets.getInsets(WindowInsetsCompat.Type.systemBars()).right;v.setPadding(left, top, right, bottom);return insets;});fileChooserLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(),result -> {// Para selección de archivos de galeríaif (file_path == null) {return;}Uri[] uris = WebChromeClient.FileChooserParams.parseResult(result.getResultCode(), result.getData());file_path.onReceiveValue(uris);file_path = null;});mSwipeRefreshLayout = findViewById(R.id.swipeRefreshLayout);mSwipeRefreshLayout.setOnChildScrollUpCallback(new SwipeRefreshLayout.OnChildScrollUpCallback() {@Overridepublic boolean canChildScrollUp(@NonNull SwipeRefreshLayout parent, @Nullable View child) {return mWebView.canScrollVertically(-1);}});mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {@Overridepublic void onRefresh() {mWebView.reload();}});mWebView = (TouchyWebView) findViewById(R.id.webView);// mWebView.setWebViewClient( mCesaWebViewClient);mWebView.addJavascriptInterface(new JavaScriptShareInterface(), "AndroidShareHandler");WebSettings webSettings = mWebView.getSettings();webSettings.setJavaScriptEnabled(true);webSettings.setJavaScriptCanOpenWindowsAutomatically(true);webSettings.setAllowFileAccess(true);webSettings.setAllowContentAccess(true);webSettings.setAllowFileAccessFromFileURLs(true);webSettings.setAllowUniversalAccessFromFileURLs(true);webSettings.setDomStorageEnabled(true);webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);webSettings.setDatabaseEnabled(false);webSettings.setDisplayZoomControls(true);webSettings.setBuiltInZoomControls(true);webSettings.setMediaPlaybackRequiresUserGesture(false);mWebView.setWebViewClient(new WebViewClient() {@Overridepublic void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {super.onReceivedError(view, errorCode, description, failingUrl);Log.e("WebView", "Error loading URL: " + failingUrl + " - " + description + " (Code: " + errorCode + ")");// Intentar recargar una vez más después de un errorif (failingUrl.equals(_URL)) {Log.d("WebView", "Attempting to reload after error...");new android.os.Handler().postDelayed(new Runnable() {@Overridepublic void run() {view.reload();}}, 2000); // Esperar 2 segundos antes de reintentar}}@Overridepublic void onReceivedSslError(WebView view, android.webkit.SslErrorHandler handler, android.net.http.SslError error) {Log.e("WebView", "SSL Error: " + error.toString() + " for URL: " + error.getUrl());// Continuar a pesar del error SSL (solo para desarrollo/testing)handler.proceed();}@Overridepublic void onPageStarted(WebView view, String url, android.graphics.Bitmap favicon) {super.onPageStarted(view, url, favicon);Log.d("WebView", "Started loading: " + url);mSwipeRefreshLayout.setRefreshing(true);}@Overridepublic void onPageFinished(WebView view, String url) {findViewById(R.id.webView).setVisibility(View.VISIBLE);mSwipeRefreshLayout.setRefreshing(false);Log.d("WebView", "Finished loading: " + url);}@Overridepublic boolean shouldOverrideUrlLoading(WebView webView, String url) {if(url.contains("leaderslinked.com") ) return false;Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));MainActivity.this.startActivity(intent);return true;}});mWebView.setWebChromeClient(new WebChromeClient(){public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) {if(file_permission()) {file_path = filePathCallback;// Solo permitir selección de galería/archivosIntent contentSelectionIntent = new Intent(Intent.ACTION_GET_CONTENT);contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE);contentSelectionIntent.setType(file_type);contentSelectionIntent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);Intent chooserIntent = new Intent(Intent.ACTION_CHOOSER);chooserIntent.putExtra(Intent.EXTRA_INTENT, contentSelectionIntent);chooserIntent.putExtra(Intent.EXTRA_TITLE, "Seleccionar archivo");fileChooserLauncher.launch(chooserIntent);return true;} else {return false;}}});// Verify network connectionif (isNetworkAvailable()) {Log.d("WebView", "Network available, proceeding to load URL");// Clear cache before loadclearWebViewCache();mWebView.loadUrl(_URL);} else {Log.e("WebView", "No network connection available");}}private void clearWebViewCache() {// Limpiar todos los tipos de caché del WebViewmWebView.clearCache(true);mWebView.clearFormData();mWebView.clearHistory();mWebView.clearSslPreferences();// Clear cookiesandroid.webkit.CookieManager.getInstance().removeAllCookies(null);android.webkit.CookieManager.getInstance().flush();Log.d("WebView", "Cache, cookies and data cleared completely");}private boolean isNetworkAvailable() {ConnectivityManager connectivityManager =(ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();boolean isConnected = activeNetworkInfo != null && activeNetworkInfo.isConnected();Log.d("WebView", "Network status: " + (isConnected ? "Connected" : "Disconnected"));return isConnected;}@Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) {if ((keyCode == KeyEvent.KEYCODE_BACK) && this.mWebView.canGoBack()) {this.mWebView.goBack();return true;}return super.onKeyDown(keyCode, event);}@Overrideprotected void onSaveInstanceState(Bundle outState){super.onSaveInstanceState(outState);// Save the state of the WebViewmWebView.saveState(outState);}@Overrideprotected void onRestoreInstanceState(Bundle savedInstanceState){super.onRestoreInstanceState(savedInstanceState);// Restore the state of the WebViewmWebView.restoreState(savedInstanceState);}@Overridepublic void onConfigurationChanged(Configuration newConfig){super.onConfigurationChanged(newConfig);}public boolean file_permission(){int checkPermissionExternal = PackageManager.PERMISSION_GRANTED;int checkPermissionReadMediaAudio = PackageManager.PERMISSION_GRANTED;int checkPermissionReadMediaVideo = PackageManager.PERMISSION_GRANTED;int checkPermissionReadMediaImages = PackageManager.PERMISSION_GRANTED;if(Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {checkPermissionExternal = ContextCompat.checkSelfPermission(this, WRITE_EXTERNAL_STORAGE);} else {checkPermissionReadMediaAudio = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_MEDIA_AUDIO);checkPermissionReadMediaVideo = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_MEDIA_VIDEO);checkPermissionReadMediaImages = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_MEDIA_IMAGES);}boolean ok = true;if(Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {ok = checkPermissionExternal == PackageManager.PERMISSION_GRANTED;} else {ok = checkPermissionReadMediaAudio == PackageManager.PERMISSION_GRANTED;ok = ok && checkPermissionReadMediaVideo == PackageManager.PERMISSION_GRANTED;ok = ok && checkPermissionReadMediaImages == PackageManager.PERMISSION_GRANTED;}if(!ok) {ArrayList<String> newPermissionList = new ArrayList<>();if(Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {if(checkPermissionExternal != PackageManager.PERMISSION_GRANTED) {newPermissionList.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);}} else {if(checkPermissionReadMediaAudio != PackageManager.PERMISSION_GRANTED) {newPermissionList.add(Manifest.permission.READ_MEDIA_AUDIO);}if(checkPermissionReadMediaVideo != PackageManager.PERMISSION_GRANTED) {newPermissionList.add(Manifest.permission.READ_MEDIA_VIDEO);}if(checkPermissionReadMediaImages != PackageManager.PERMISSION_GRANTED) {newPermissionList.add(Manifest.permission.READ_MEDIA_IMAGES);}}String permissions[] = newPermissionList.toArray(new String[newPermissionList.size()]);ActivityCompat.requestPermissions(MainActivity.this, permissions, 1);return false; // No abrir selector hasta que se concedan permisos} else {return true; // Permisos concedidos, permitir abrir selector}}@Overridepublic void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {super.onRequestPermissionsResult(requestCode, permissions, grantResults);if (requestCode == 1) {boolean allPermissionsGranted = true;for (int result : grantResults) {if (result != PackageManager.PERMISSION_GRANTED) {allPermissionsGranted = false;break;}}if (allPermissionsGranted) {Log.d("MainActivity", "Todos los permisos han sido concedidos");// Los permisos han sido concedidos, el usuario puede intentar nuevamente abrir el selector} else {Log.d("MainActivity", "Algunos permisos fueron denegados");// Algunos permisos fueron denegados}}}private class JavaScriptShareInterface {@JavascriptInterfacepublic void share(String url, String title, String content) {try {Intent shareIntent = new Intent(Intent.ACTION_SEND);shareIntent.setType("text/plain");shareIntent.putExtra(Intent.EXTRA_SUBJECT, title);String shareMessage= "\n" + content + "\n\n";shareMessage = shareMessage + url +"\n\n";shareIntent.putExtra(Intent.EXTRA_TEXT, shareMessage);Intent chooserIntent = Intent.createChooser(shareIntent, "choose one");startActivity(chooserIntent);} catch(Exception e) {//e.toString();}}}}