Proyectos de Subversion LeadersLinked - Android

Rev

Rev 4 | Ir a la última revisión | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
3 efrain 1
package com.cesams.leaderslinked.v2;
2
 
3
import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
4
 
5
import android.Manifest;
6
 
7
import androidx.activity.result.ActivityResultLauncher;
8
import androidx.activity.result.contract.ActivityResultContracts;
9
import androidx.annotation.NonNull;
10
import androidx.annotation.Nullable;
11
import androidx.annotation.RequiresApi;
12
import androidx.appcompat.app.AppCompatActivity;
13
import androidx.core.app.ActivityCompat;
14
import androidx.core.content.ContextCompat;
15
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
16
import androidx.core.view.ViewCompat;
17
import androidx.core.view.WindowInsetsCompat;
18
 
19
 
20
import android.content.pm.PackageManager;
21
import android.annotation.SuppressLint;
22
import android.content.Intent;
23
import android.content.res.Configuration;
5 efrain 24
import android.net.ConnectivityManager;
25
import android.net.NetworkInfo;
3 efrain 26
import android.net.Uri;
27
import android.os.Build;
28
import android.os.Bundle;
29
import android.os.Environment;
30
import android.provider.MediaStore;
31
import android.util.Log;
32
import android.view.KeyEvent;
33
import android.view.View;
34
import android.webkit.JavascriptInterface;
35
import android.webkit.ValueCallback;
36
import android.webkit.WebChromeClient;
37
import android.webkit.WebSettings;
38
import android.webkit.WebView;
39
import android.webkit.WebViewClient;
40
 
41
import java.io.File;
42
import java.io.IOException;
43
import java.text.SimpleDateFormat;
44
import java.util.ArrayList;
45
import java.util.Date;
46
 
47
public class MainActivity extends AppCompatActivity {
48
 
49
    private TouchyWebView mWebView = null;
50
 
51
 
52
    private SwipeRefreshLayout mSwipeRefreshLayout;
53
 
54
    private static String file_type = "*/*";
55
    private String cam_file_data = null;
56
    private ValueCallback<Uri> file_data;
57
    private ValueCallback<Uri[]> file_path;
58
    private final static int file_req_code = 1;
59
 
4 efrain 60
    private final static String _URL = "https://stanging.leaderslinked.com";
3 efrain 61
 
62
    private ActivityResultLauncher<Intent> fileChooserLauncher;
63
 
64
    @RequiresApi(api = Build.VERSION_CODES.M)
65
    @Override
66
    protected void onCreate(Bundle savedInstanceState) {
67
        super.onCreate(savedInstanceState);
68
        setContentView(R.layout.activity_main);
69
 
70
 
71
        ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.swipeRefreshLayout), (v, insets) -> {
72
            int top = insets.getInsets(WindowInsetsCompat.Type.systemBars()).top;
73
            int bottom = insets.getInsets(WindowInsetsCompat.Type.systemBars()).bottom;
74
            int left = insets.getInsets(WindowInsetsCompat.Type.systemBars()).left;
75
            int right = insets.getInsets(WindowInsetsCompat.Type.systemBars()).right;
76
 
77
            v.setPadding(left, top, right, bottom);
78
 
79
            return insets;
80
        });
81
 
82
 
83
        fileChooserLauncher = registerForActivityResult(
84
                new ActivityResultContracts.StartActivityForResult(),
85
                result -> {
86
                    // For Android 5.0 (Lollipop) and above
87
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
88
                        if (file_path == null) {
89
                            return;
90
                        }
91
                        Uri[] uris = WebChromeClient.FileChooserParams.parseResult(result.getResultCode(), result.getData());
92
                        if (uris == null) {
93
                            if (cam_file_data != null) {
94
                                uris = new Uri[]{Uri.parse(cam_file_data)};
95
                            }
96
                        }
97
                        file_path.onReceiveValue(uris);
98
                        file_path = null;
99
                    } else { // For older versions
100
                        if (file_data == null) {
101
                            return;
102
                        }
103
                        Uri resultUri = (result.getData() == null || result.getResultCode() != RESULT_OK) ? null : result.getData().getData();
104
                        file_data.onReceiveValue(resultUri);
105
                        file_data = null;
106
                    }
107
                    cam_file_data = null;
108
                });
109
 
110
        mSwipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipeRefreshLayout);
111
 
112
        mSwipeRefreshLayout.setOnChildScrollUpCallback(new SwipeRefreshLayout.OnChildScrollUpCallback() {
113
            @Override
114
            public boolean canChildScrollUp(@NonNull SwipeRefreshLayout parent, @Nullable View child) {
115
                return mWebView.canScrollVertically(-1);
116
            }
117
        });
118
 
119
 
120
 
121
 
122
        mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
123
            @Override
124
            public void onRefresh() {
125
                mWebView.reload();
126
            }
127
        });
128
 
129
 
130
 
131
 
132
        mWebView = (TouchyWebView) findViewById(R.id.webView);
133
 
5 efrain 134
 
3 efrain 135
       // mWebView.setWebViewClient( mCesaWebViewClient);
136
 
137
        mWebView.addJavascriptInterface(new JavaScriptShareInterface(), "AndroidShareHandler");
138
 
139
 
140
 
141
 
142
        WebSettings webSettings = mWebView.getSettings();
143
        webSettings.setJavaScriptEnabled(true);
144
        webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
145
        webSettings.setAllowFileAccess(true);
146
        webSettings.setAllowContentAccess(true);
147
        webSettings.setAllowFileAccessFromFileURLs(true);
148
        webSettings.setAllowUniversalAccessFromFileURLs(true);
149
        webSettings.setDomStorageEnabled(true);
150
        webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);
5 efrain 151
        webSettings.setDatabaseEnabled(false);
3 efrain 152
        webSettings.setDisplayZoomControls(true);
153
        webSettings.setBuiltInZoomControls(true);
154
 
155
        webSettings.setMediaPlaybackRequiresUserGesture(false);
156
 
157
 
158
        mWebView.setWebViewClient(new WebViewClient() {
159
 
5 efrain 160
            @Override
161
            public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
162
                super.onReceivedError(view, errorCode, description, failingUrl);
163
                Log.e("WebView", "Error loading URL: " + failingUrl + " - " + description + " (Code: " + errorCode + ")");
164
 
165
                // Intentar recargar una vez más después de un error
166
                if (failingUrl.equals(_URL)) {
167
                    Log.d("WebView", "Attempting to reload after error...");
168
                    new android.os.Handler().postDelayed(new Runnable() {
169
                        @Override
170
                        public void run() {
171
                            view.reload();
172
                        }
173
                    }, 2000); // Esperar 2 segundos antes de reintentar
174
                }
175
            }
176
 
177
            @Override
178
            public void onReceivedSslError(WebView view, android.webkit.SslErrorHandler handler, android.net.http.SslError error) {
179
                Log.e("WebView", "SSL Error: " + error.toString() + " for URL: " + error.getUrl());
180
                // Continuar a pesar del error SSL (solo para desarrollo/testing)
181
                handler.proceed();
182
            }
3 efrain 183
 
5 efrain 184
            @Override
185
            public void onPageStarted(WebView view, String url, android.graphics.Bitmap favicon) {
186
                super.onPageStarted(view, url, favicon);
187
                Log.d("WebView", "Started loading: " + url);
188
                mSwipeRefreshLayout.setRefreshing(true);
189
            }
3 efrain 190
 
191
            @Override
192
            public void onPageFinished(WebView view, String url) {
193
                findViewById(R.id.webView).setVisibility(View.VISIBLE);
194
                mSwipeRefreshLayout.setRefreshing(false);
5 efrain 195
                Log.d("WebView", "Finished loading: " + url);
3 efrain 196
            }
197
 
198
            @Override
199
            public boolean shouldOverrideUrlLoading(WebView webView, String url) {
200
                if(url.contains("leaderslinked.com") ) return false;
201
 
202
                Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
203
                MainActivity.this.startActivity(intent);
204
                return true;
205
            }
206
 
207
        });
208
 
209
        mWebView.setWebChromeClient(new WebChromeClient()
210
        {
211
            public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) {
212
 
213
                if(file_permission() && Build.VERSION.SDK_INT >= 21) {
214
                    file_path = filePathCallback;
215
                    Intent takePictureIntent = null;
216
                    Intent takeVideoIntent = null;
217
 
218
                    boolean includeVideo = false;
219
                    boolean includePhoto = false;
220
 
221
                    paramCheck:
222
                    for (String acceptTypes : fileChooserParams.getAcceptTypes()) {
223
                        String[] splitTypes = acceptTypes.split(", ?+");
224
                        for (String acceptType : splitTypes) {
225
                            switch (acceptType) {
226
                                case "*/*":
227
                                    includePhoto = true;
228
                                    includeVideo = true;
229
                                    break paramCheck;
230
                                case "image/*":
231
                                    includePhoto = true;
232
                                    break;
233
                                case "video/*":
234
                                    includeVideo = true;
235
                                    break;
236
                            }
237
                        }
238
                    }
239
 
240
                    if (fileChooserParams.getAcceptTypes().length == 0) {
241
                        includePhoto = true;
242
                        includeVideo = true;
243
                    }
244
 
245
                    if (includePhoto) {
246
                        takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
247
                        if (takePictureIntent.resolveActivity(MainActivity.this.getPackageManager()) != null) {
248
                            File photoFile = null;
249
                            try {
250
                                photoFile = create_image();
251
                                takePictureIntent.putExtra("PhotoPath", cam_file_data);
252
                            } catch (IOException ex) {
253
                                Log.e("MainClass" , "Image file creation failed", ex);
254
                            }
255
                            if (photoFile != null) {
256
                                cam_file_data = "file:" + photoFile.getAbsolutePath();
257
                                takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
258
                            } else {
259
                                cam_file_data = null;
260
                                takePictureIntent = null;
261
                            }
262
                        }
263
                    }
264
 
265
                    if (includeVideo) {
266
                        takeVideoIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
267
                        if (takeVideoIntent.resolveActivity(MainActivity.this.getPackageManager()) != null) {
268
                            File videoFile = null;
269
                            try {
270
                                videoFile = create_video();
271
                            } catch (IOException ex) {
272
                                Log.e("MainClass" , "Video file creation failed", ex);
273
                            }
274
                            if (videoFile != null) {
275
                                cam_file_data = "file:" + videoFile.getAbsolutePath();
276
                                takeVideoIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(videoFile));
277
                            } else {
278
                                cam_file_data = null;
279
                                takeVideoIntent = null;
280
                            }
281
                        }
282
                    }
283
 
284
                    Intent contentSelectionIntent = new Intent(Intent.ACTION_GET_CONTENT);
285
                    contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE);
286
                    contentSelectionIntent.setType(file_type);
287
 
288
 
289
                    Intent[] intentArray;
290
                    if (takePictureIntent != null && takeVideoIntent != null) {
291
                        intentArray = new Intent[]{takePictureIntent, takeVideoIntent};
292
                    } else if (takePictureIntent != null) {
293
                        intentArray = new Intent[]{takePictureIntent};
294
                    } else if (takeVideoIntent != null) {
295
                        intentArray = new Intent[]{takeVideoIntent};
296
                    } else {
297
                        intentArray = new Intent[0];
298
                    }
299
 
300
                    Intent chooserIntent = new Intent(Intent.ACTION_CHOOSER);
301
                    chooserIntent.putExtra(Intent.EXTRA_INTENT, contentSelectionIntent);
302
                    chooserIntent.putExtra(Intent.EXTRA_TITLE, "File chooser");
303
                    chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray);
304
                    fileChooserLauncher.launch(chooserIntent);
305
                    return true;
306
                } else {
307
                    return false;
308
                }
309
            }
310
        });
311
 
5 efrain 312
        // Verificar conectividad de red
313
        if (isNetworkAvailable()) {
314
            Log.d("WebView", "Network available, proceeding to load URL");
315
            // Limpiar completamente el caché antes de cargar
316
            clearWebViewCache();
317
            mWebView.loadUrl(_URL);
318
        } else {
319
            Log.e("WebView", "No network connection available");
320
        }
3 efrain 321
    }
5 efrain 322
 
323
    private void clearWebViewCache() {
324
        // Limpiar todos los tipos de caché del WebView
325
        mWebView.clearCache(true);
326
        mWebView.clearFormData();
327
        mWebView.clearHistory();
328
        mWebView.clearSslPreferences();
329
 
330
        // Limpiar cookies
331
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
332
            android.webkit.CookieManager.getInstance().removeAllCookies(null);
333
            android.webkit.CookieManager.getInstance().flush();
334
        } else {
335
            android.webkit.CookieManager.getInstance().removeAllCookie();
3 efrain 336
        }
5 efrain 337
 
338
        Log.d("WebView", "Cache, cookies and data cleared completely");
3 efrain 339
    }
5 efrain 340
 
341
    private boolean isNetworkAvailable() {
342
        ConnectivityManager connectivityManager =
343
                (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
344
        NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
345
        boolean isConnected = activeNetworkInfo != null && activeNetworkInfo.isConnected();
346
        Log.d("WebView", "Network status: " + (isConnected ? "Connected" : "Disconnected"));
347
        return isConnected;
348
    }
3 efrain 349
 
350
    @Override
351
    public boolean onKeyDown(int keyCode, KeyEvent event) {
352
        if ((keyCode == KeyEvent.KEYCODE_BACK) && this.mWebView.canGoBack()) {
353
            this.mWebView.goBack();
354
            return true;
355
        }
356
 
357
        return super.onKeyDown(keyCode, event);
358
    }
359
 
360
 
361
 
362
 
363
    @Override
364
    protected void onSaveInstanceState(Bundle outState){
365
        super.onSaveInstanceState(outState);
366
 
367
        // Save the state of the WebView
368
        mWebView.saveState(outState);
369
    }
370
 
371
    @Override
372
    protected void onRestoreInstanceState(Bundle savedInstanceState){
373
        super.onRestoreInstanceState(savedInstanceState);
374
 
375
        // Restore the state of the WebView
376
        mWebView.restoreState(savedInstanceState);
377
    }
378
 
379
    @Override
380
    public void onConfigurationChanged(Configuration newConfig){
381
        super.onConfigurationChanged(newConfig);
382
    }
383
 
384
    public boolean file_permission(){
385
        int checkPermissionExternal = PackageManager.PERMISSION_GRANTED;
386
        int checkPermissionReadMediaAudio = PackageManager.PERMISSION_GRANTED;
387
        int checkPermissionReadMediaVideo = PackageManager.PERMISSION_GRANTED;
388
        int checkPermissionReadMediaImages = PackageManager.PERMISSION_GRANTED;
389
 
390
        int checkPermissionCamera = ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA);
391
 
392
        if(Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
393
            checkPermissionExternal = ContextCompat.checkSelfPermission(this, WRITE_EXTERNAL_STORAGE);
394
        } else {
395
            checkPermissionReadMediaAudio = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_MEDIA_AUDIO);
396
            checkPermissionReadMediaVideo = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_MEDIA_VIDEO);
397
            checkPermissionReadMediaImages = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_MEDIA_IMAGES);
398
        }
399
 
400
 
401
        boolean ok = checkPermissionCamera == PackageManager.PERMISSION_GRANTED;
402
        if(Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
403
            ok = ok && checkPermissionExternal == PackageManager.PERMISSION_GRANTED;
404
        } else {
405
            ok = ok && checkPermissionReadMediaAudio == PackageManager.PERMISSION_GRANTED;
406
            ok = ok && checkPermissionReadMediaVideo == PackageManager.PERMISSION_GRANTED;
407
            ok = ok && checkPermissionReadMediaImages == PackageManager.PERMISSION_GRANTED;
408
        }
409
 
410
        if(!ok) {
411
 
412
            ArrayList<String> newPermissionList = new ArrayList<>();
413
 
414
            if(checkPermissionCamera != PackageManager.PERMISSION_GRANTED) {
415
                newPermissionList.add(Manifest.permission.CAMERA);
416
            }
417
 
418
            if(Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
419
                if(checkPermissionExternal != PackageManager.PERMISSION_GRANTED) {
420
                    newPermissionList.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
421
                }
422
            } else {
423
                if(checkPermissionReadMediaAudio != PackageManager.PERMISSION_GRANTED) {
424
                    newPermissionList.add(Manifest.permission.READ_MEDIA_AUDIO);
425
                }
426
                if(checkPermissionReadMediaVideo != PackageManager.PERMISSION_GRANTED) {
427
                    newPermissionList.add(Manifest.permission.READ_MEDIA_VIDEO);
428
                }
429
                if(checkPermissionReadMediaImages != PackageManager.PERMISSION_GRANTED) {
430
                    newPermissionList.add(Manifest.permission.READ_MEDIA_IMAGES);
431
                }
432
            }
433
 
434
 
435
 
436
 
437
            String permissions[] = newPermissionList.toArray(new String[newPermissionList.size()]);
438
            ActivityCompat.requestPermissions(MainActivity.this, permissions, 1);
439
            return true;
440
        } else {
441
            return false;
442
        }
443
    }
444
 
445
    private File create_image() throws IOException {
446
        @SuppressLint("SimpleDateFormat") String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
447
        String imageFileName = "img_"+timeStamp+"_";
448
        File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
449
        return File.createTempFile(imageFileName,".jpg",storageDir);
450
    }
451
 
452
    private File create_video() throws IOException {
453
        @SuppressLint("SimpleDateFormat")
454
        String file_name = new SimpleDateFormat("yyyy_mm_ss").format(new Date());
455
        String new_name = "file_"+file_name+"_";
456
        File sd_directory = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
457
        return File.createTempFile(new_name, ".3gp", sd_directory);
458
    }
459
 
460
 
461
    private class JavaScriptShareInterface {
462
 
463
 
464
        @JavascriptInterface
465
        public void share(String url, String title, String content) {
466
            try {
467
                Intent shareIntent = new Intent(Intent.ACTION_SEND);
468
                shareIntent.setType("text/plain");
469
                shareIntent.putExtra(Intent.EXTRA_SUBJECT, title);
470
                String shareMessage= "\n" +  content + "\n\n";
471
                shareMessage = shareMessage + url +"\n\n";
472
                shareIntent.putExtra(Intent.EXTRA_TEXT, shareMessage);
473
 
474
                Intent chooserIntent = Intent.createChooser(shareIntent, "choose one");
475
 
476
                startActivity(chooserIntent);
477
            } catch(Exception e) {
478
                //e.toString();
479
            }
480
        }
481
 
482
    }
483
}