Rev 4 | Ir a la última revisión | 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.os.Environment;import android.provider.MediaStore;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.io.File;import java.io.IOException;import java.text.SimpleDateFormat;import java.util.ArrayList;import java.util.Date;public class MainActivity extends AppCompatActivity {private TouchyWebView mWebView = null;private SwipeRefreshLayout mSwipeRefreshLayout;private static String file_type = "*/*";private String cam_file_data = null;private ValueCallback<Uri> file_data;private ValueCallback<Uri[]> file_path;private final static int file_req_code = 1;private final static String _URL = "https://stanging.leaderslinked.com";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 -> {// For Android 5.0 (Lollipop) and aboveif (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {if (file_path == null) {return;}Uri[] uris = WebChromeClient.FileChooserParams.parseResult(result.getResultCode(), result.getData());if (uris == null) {if (cam_file_data != null) {uris = new Uri[]{Uri.parse(cam_file_data)};}}file_path.onReceiveValue(uris);file_path = null;} else { // For older versionsif (file_data == null) {return;}Uri resultUri = (result.getData() == null || result.getResultCode() != RESULT_OK) ? null : result.getData().getData();file_data.onReceiveValue(resultUri);file_data = null;}cam_file_data = null;});mSwipeRefreshLayout = (SwipeRefreshLayout) 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() && Build.VERSION.SDK_INT >= 21) {file_path = filePathCallback;Intent takePictureIntent = null;Intent takeVideoIntent = null;boolean includeVideo = false;boolean includePhoto = false;paramCheck:for (String acceptTypes : fileChooserParams.getAcceptTypes()) {String[] splitTypes = acceptTypes.split(", ?+");for (String acceptType : splitTypes) {switch (acceptType) {case "*/*":includePhoto = true;includeVideo = true;break paramCheck;case "image/*":includePhoto = true;break;case "video/*":includeVideo = true;break;}}}if (fileChooserParams.getAcceptTypes().length == 0) {includePhoto = true;includeVideo = true;}if (includePhoto) {takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);if (takePictureIntent.resolveActivity(MainActivity.this.getPackageManager()) != null) {File photoFile = null;try {photoFile = create_image();takePictureIntent.putExtra("PhotoPath", cam_file_data);} catch (IOException ex) {Log.e("MainClass" , "Image file creation failed", ex);}if (photoFile != null) {cam_file_data = "file:" + photoFile.getAbsolutePath();takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));} else {cam_file_data = null;takePictureIntent = null;}}}if (includeVideo) {takeVideoIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);if (takeVideoIntent.resolveActivity(MainActivity.this.getPackageManager()) != null) {File videoFile = null;try {videoFile = create_video();} catch (IOException ex) {Log.e("MainClass" , "Video file creation failed", ex);}if (videoFile != null) {cam_file_data = "file:" + videoFile.getAbsolutePath();takeVideoIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(videoFile));} else {cam_file_data = null;takeVideoIntent = null;}}}Intent contentSelectionIntent = new Intent(Intent.ACTION_GET_CONTENT);contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE);contentSelectionIntent.setType(file_type);Intent[] intentArray;if (takePictureIntent != null && takeVideoIntent != null) {intentArray = new Intent[]{takePictureIntent, takeVideoIntent};} else if (takePictureIntent != null) {intentArray = new Intent[]{takePictureIntent};} else if (takeVideoIntent != null) {intentArray = new Intent[]{takeVideoIntent};} else {intentArray = new Intent[0];}Intent chooserIntent = new Intent(Intent.ACTION_CHOOSER);chooserIntent.putExtra(Intent.EXTRA_INTENT, contentSelectionIntent);chooserIntent.putExtra(Intent.EXTRA_TITLE, "File chooser");chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray);fileChooserLauncher.launch(chooserIntent);return true;} else {return false;}}});// Verificar conectividad de redif (isNetworkAvailable()) {Log.d("WebView", "Network available, proceeding to load URL");// Limpiar completamente el caché antes de cargarclearWebViewCache();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();// Limpiar cookiesif (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {android.webkit.CookieManager.getInstance().removeAllCookies(null);android.webkit.CookieManager.getInstance().flush();} else {android.webkit.CookieManager.getInstance().removeAllCookie();}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;int checkPermissionCamera = ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA);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 = checkPermissionCamera == PackageManager.PERMISSION_GRANTED;if(Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {ok = ok && checkPermissionExternal == PackageManager.PERMISSION_GRANTED;} else {ok = 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(checkPermissionCamera != PackageManager.PERMISSION_GRANTED) {newPermissionList.add(Manifest.permission.CAMERA);}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 true;} else {return false;}}private File create_image() throws IOException {@SuppressLint("SimpleDateFormat") String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());String imageFileName = "img_"+timeStamp+"_";File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);return File.createTempFile(imageFileName,".jpg",storageDir);}private File create_video() throws IOException {@SuppressLint("SimpleDateFormat")String file_name = new SimpleDateFormat("yyyy_mm_ss").format(new Date());String new_name = "file_"+file_name+"_";File sd_directory = getExternalFilesDir(Environment.DIRECTORY_PICTURES);return File.createTempFile(new_name, ".3gp", sd_directory);}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();}}}}