Я пытаюсь создать приложение, которое принимает текстовый файл URL и циклически повторяется, пока пользователь не захочет его остановить. Пока это происходит, приложение должно записывать все времена загрузки в базу данных, а затем пользователь должен экспортировать его.
В настоящее время, когда приложение достигает окончательного URL-адреса, оно перестает работать. Я провел несколько тестов и понял, что проблема возникает всякий раз, когда я включаю JavaScript и очищаю кеш. Но я не могу избавиться от JavaScript или очистить кеш, потому что это повредит числам.
Кажется, проблема возникает в browser.java строке 205 , которая:
mTimer.schedule(mRunOnFinished, mDelay);
Ошибка, которую я получаю:
"W/cr_ChildProcLH: Create a new ChildConnectionAllocator with package name = com.android.chrome, sandboxed = true
2019-11-08 11:22:32.214 8615-8615/com.example.time_app I/cr_BrowserStartup: Initializing chromium process, singleProcess=false
2019-11-08 11:22:32.220 8615-8615/com.example.time_app W/ResourceType: Failure getting entry for 0x7f1204b0 (t=17 e=1200) (error -2147483647)
2019-11-08 11:22:32.820 8615-8615/com.example.time_app E/chromium: [ERROR:gl_surface_egl.cc(335)] eglChooseConfig failed with error EGL_SUCCESS
2019-11-08 11:22:32.852 8615-8615/com.example.time_app D/EGL_emulation: eglCreateContext: 0xe0205ea0: maj 2 min 0 rcv 2
2019-11-08 11:22:32.855 8615-8615/com.example.time_app D/EGL_emulation: eglMakeCurrent: 0xe0205ea0: ver 2 0 (tinfo 0xce273280)
2019-11-08 11:22:32.888 8615-8643/com.example.time_app D/EGL_emulation: eglMakeCurrent: 0xe7dba3a0: ver 2 0 (tinfo 0xdd5b34a0)
2019-11-08 11:22:33.115 8615-9257/com.example.time_app W/cr_CrashFileManager: /data/user/0/com.example.time_app/cache/WebView/Crash Reports does not exist or is not a directory
2019-11-08 11:22:33.144 8615-8620/com.example.time_app I/zygote: Do full code cache collection, code=250KB, data=179KB
2019-11-08 11:22:33.145 8615-8620/com.example.time_app I/zygote: After code cache collection, code=247KB, data=136KB
2019-11-08 11:22:34.398 8615-8620/com.example.time_app I/zygote: Do partial code cache collection, code=249KB, data=138KB
2019-11-08 11:22:34.398 8615-8620/com.example.time_app I/zygote: After code cache collection, code=249KB, data=138KB
2019-11-08 11:22:34.398 8615-8620/com.example.time_app I/zygote: Increasing code cache capacity to 1024KB
2019-11-08 11:22:40.383 8615-8615/com.example.time_app E/Browser: DisplayNext::run : Start loading next page : http://www.Google.com
2019-11-08 11:22:40.397 8615-9206/com.example.time_app W/cr_media: Requires BLUETOOTH permission
2019-11-08 11:22:40.401 8615-9196/com.example.time_app D/NetworkSecurityConfig: No Network Security Config specified, using platform default
2019-11-08 11:22:40.478 8615-9448/com.example.time_app I/VideoCapabilities: Unsupported profile 4 for video/mp4v-es
2019-11-08 11:22:40.484 8615-9448/com.example.time_app W/cr_MediaCodecUtil: HW encoder for video/avc is not available on this device.
2019-11-08 11:22:40.490 8615-9448/com.example.time_app E/chromium: [ERROR:gl_surface_egl.cc(335)] eglChooseConfig failed with error EGL_SUCCESS
2019-11-08 11:22:40.516 8615-9448/com.example.time_app D/EGL_emulation: eglCreateContext: 0xcc055060: maj 2 min 0 rcv 2
2019-11-08 11:22:40.518 8615-9448/com.example.time_app D/EGL_emulation: eglMakeCurrent: 0xcc055060: ver 2 0 (tinfo 0xcc0756f0)
2019-11-08 11:22:41.060 8615-8643/com.example.time_app E/eglCodecCommon: glUtilsParamSize: unknow param 0x000085b5
2019-11-08 11:22:41.487 8615-8643/com.example.time_app I/chatty: uid=10079(com.example.time_app) RenderThread identical 6 lines
2019-11-08 11:22:41.487 8615-8643/com.example.time_app E/eglCodecCommon: glUtilsParamSize: unknow param 0x000085b5
2019-11-08 11:22:41.752 8615-8643/com.example.time_app D/EGL_emulation: eglMakeCurrent: 0xe7dba3a0: ver 2 0 (tinfo 0xdd5b34a0)
2019-11-08 11:22:41.833 8615-8643/com.example.time_app D/EGL_emulation: eglMakeCurrent: 0xe7dba3a0: ver 2 0 (tinfo 0xdd5b34a0)
2019-11-08 11:22:41.913 8615-8643/com.example.time_app E/eglCodecCommon: glUtilsParamSize: unknow param 0x000085b5
2019-11-08 11:22:41.913 8615-8643/com.example.time_app E/eglCodecCommon: glUtilsParamSize: unknow param 0x000085b5
2019-11-08 11:22:41.958 8615-8643/com.example.time_app D/EGL_emulation: eglMakeCurrent: 0xe7dba3a0: ver 2 0 (tinfo 0xdd5b34a0)
2019-11-08 11:22:42.011 8615-8643/com.example.time_app D/EGL_emulation: eglMakeCurrent: 0xe7dba3a0: ver 2 0 (tinfo 0xdd5b34a0)
2019-11-08 11:22:42.068 8615-8643/com.example.time_app E/eglCodecCommon: glUtilsParamSize: unknow param 0x000085b5
2019-11-08 11:22:42.068 8615-8643/com.example.time_app E/eglCodecCommon: glUtilsParamSize: unknow param 0x000085b5
2019-11-08 11:22:42.100 8615-8615/com.example.time_app D/AndroidRuntime: Shutting down VM
2019-11-08 11:22:42.100 8615-8615/com.example.time_app E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.time_app, PID: 8615
java.lang.IllegalStateException: Task already scheduled or cancelled
at java.util.Timer.sched(Timer.java:401)
at java.util.Timer.schedule(Timer.java:193)
at com.example.time_app.Browser$WaitPageLoadedClient.onPageFinished(Browser.java:205)
at xl.c(PG:228)
at afG.handleMessage(PG:72)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
2019-11-08 11:22:42.170 8615-8643/com.example.time_app E/eglCodecCommon: glUtilsParamSize: unknow param 0x000085b5
2019-11-08 11:22:42.170 8615-8643/com.example.time_app E/eglCodecCommon: glUtilsParamSize: unknow param 0x000085b5"
Browser.java
package com.example.time_app;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.util.Pair;
import android.view.View;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;
import static com.example.time_app.File_menu.names;
public class Browser extends AppCompatActivity {
private static class SomeComplicatedObject {
public final String mPath;
public final Integer mDuration;
public int j;
public SomeComplicatedObject(final String path, final int duration) {
mPath = path;
mDuration = duration;
}
String getPath() {
return mPath;
}
Integer getDureation() {
return mDuration;
}
}
public static final List<SomeComplicatedObject> complicatedList = new ArrayList<>();
static {
for (int i=0;i<names.size();i++)
{
complicatedList.add(new SomeComplicatedObject(names.get(i),8000));
}
}
public static final String TAG = "Browser";
public final ArrayList<Pair<String, Integer>> mSitesToDisplay = new ArrayList<>();
public final Timer mTimer = new Timer("LoadNext");
public final Handler mHandler = new Handler();
public WebView mWebView = null;
public int mIndex = -1;
public final Context context = this;
public void fillSitesToDisplay(List<SomeComplicatedObject> list) {
mIndex = -1;
mSitesToDisplay.clear();
for (SomeComplicatedObject item : list) {
mSitesToDisplay.add(new Pair<>(item.getPath(), item.getDureation()));
}
}
public Pair<String, Integer> getNext() {
mIndex = (mIndex + 1) % mSitesToDisplay.size();
return mSitesToDisplay.get(mIndex);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_browser);
fillSitesToDisplay(complicatedList);
View decorView = getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY | View.SYSTEM_UI_FLAG_FULLSCREEN;
decorView.setSystemUiVisibility(uiOptions);
mWebView = (WebView) findViewById(R.id.webview);
load_javascript();
//initial start delayed by 1 sec
mTimer.schedule(createTimerTask(), TimeUnit.SECONDS.toMillis(8));
}
public Runnable mDisplayNextPage = new Runnable() {
@Override
public void run() {
final Pair<String, Integer> pathTimePair = getNext();
Log.e(TAG, "DisplayNext::run : Start loading next page : " + pathTimePair.first);
mWebView.setWebViewClient(new WaitPageLoadedClient(mTimer, createTimerTask(), pathTimePair.second));
mWebView.loadUrl(pathTimePair.first);
}
};
public TimerTask createTimerTask() {
return new TimerTriggered(mHandler, mDisplayNextPage);
}
//simple utility class for notifying timer triggered event
//on UI thread.
public static class TimerTriggered extends TimerTask {
Runnable mOnTriggered;
Handler mHandler;
protected TimerTriggered(Handler handler, Runnable onTriggered) {
super();
mHandler = handler;
mOnTriggered = onTriggered;
}
@Override
public void run() {
//Timer runs int it's own thread so we need to
//pass execution to MainThread for accessing WebView.
mHandler.post(mOnTriggered);
}
}
public class WaitPageLoadedClient extends WebViewClient {
public final TimerTask mRunOnFinished;
public final Timer mTimer;
public final Integer mDelay;
//creating the webview variable
WebView wb;
//the end variable takes in the finshed load time(it is a long function because of the number length
long end;
//this is just a varibale to be used for the alert code
//this is the total number converted as a string because the alert function does not take in float
String numberAsString;
//the start variable takes in the start load time(it is a long function because of the number length
long start;
//The total variable takes in the substraction of the end and start and is a float variale do to its shorter length
float total;
Date end_Time;
Date start_Time;
WebView mWebView=(WebView) findViewById(R.id.webview);
public WaitPageLoadedClient(Timer timer, TimerTask toRunOnFinished, Integer delay) {
mRunOnFinished = toRunOnFinished;
mTimer = timer;
mDelay = delay;
}
@Override
//this function records the load time
public void onPageStarted(WebView view, String url, Bitmap favicon) {
start = System.currentTimeMillis();
start_Time = Calendar.getInstance().getTime();
}
@Override
public void onPageFinished(WebView view, String url) {
// Log.e(TAG, "onPageFinished: Schedule timer for " + mDelay);
mTimer.schedule(mRunOnFinished, mDelay);
end = System.currentTimeMillis();
total = end - start;
end_Time = Calendar.getInstance().getTime();
// Total is the difference in milliseconds.
// Dividing by 1000, you convert it to seconds
numberAsString = String.valueOf(total / 1000);
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context);
// set title
alertDialogBuilder.setTitle("Your Load Time");
// set dialog message
alertDialogBuilder
.setMessage("Elapsed Time:" + numberAsString + "\n" + "Start Time:" + start_Time + "\n" + "EndTime:" + end_Time + "\n")
.setCancelable(false)
.setNegativeButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// if this button is clicked, just close
// the dialog box and do nothing
dialog.cancel();
}
});
// create alert dialog
AlertDialog alertDialog = alertDialogBuilder.create();
// show it
alertDialog.show();
}
}
public void Go_back()
{
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context);
// set title
alertDialogBuilder.setTitle("Done");
// set dialog message
alertDialogBuilder
.setMessage("Load Test Done")
.setCancelable(false)
.setNegativeButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// if this button is clicked, just close
// the dialog box and do nothing
dialog.cancel();
}
});
// create alert dialog
AlertDialog alertDialog = alertDialogBuilder.create();
// show it
alertDialog.show();
Intent intent=new Intent(this, MainActivity.class);
startActivity(intent);
}
public void load_javascript()
{
//declaring and setting the web setting variable
WebSettings webSettings = mWebView.getSettings();
//setting up the javascript to allow thw browser to use javascript
webSettings.setJavaScriptEnabled(true);
mWebView.getSettings().setAppCacheEnabled(false);
mWebView.clearCache(true);
}
}
activity_browser.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Browser">
tools:context=".Browser_class">
<WebView
android:id="@+id/webview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout >
file_load.java
package com.example.time_app;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.Manifest;
import android.content.ContentUris;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.util.Log;
import android.widget.TextView;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.InputStream;
import static com.example.time_app.File_menu.names;
public class file_load extends AppCompatActivity {
private int request_code =1, FILE_SELECT_CODE =101;
private TextView textView;
private String TAG ="mainactivty";
public String actualfilepath="";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_file_load);
// sdcard/myfolder/mytextfile.txt
//URI sdcard/media/123242
textView =(TextView) findViewById(R.id.text2);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
// start runtime permission
Boolean hasPermission =( ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED);
if (!hasPermission){
Log.e(TAG, "get permision ");
ActivityCompat.requestPermissions( this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, request_code);
}else {
Log.e(TAG, "get permision-- already granted ");
showFileChooser();
}
}else {
//readfile();
showFileChooser();
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode){
case 1:{
if (grantResults.length>0 && grantResults[0]== PackageManager.PERMISSION_GRANTED){
//readfile();
showFileChooser();
}else {
// show a msg to user
}
}
}
}
private void showFileChooser() {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("*/*");
intent.addCategory(Intent.CATEGORY_OPENABLE);
try {
startActivityForResult( Intent.createChooser(intent, "Select a File to Upload"), FILE_SELECT_CODE);
} catch (Exception e) {
Log.e(TAG, " choose file error "+e.toString());
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// Log.e(TAG, " result is "+ data + " uri "+ data.getData()+ " auth "+ data.getData().getAuthority()+ " path "+ data.getData().getPath());
String fullerror ="";
if (requestCode == FILE_SELECT_CODE){
if (resultCode == RESULT_OK){
try {
Uri imageuri = data.getData();
InputStream stream = null;
String tempID= "", id ="";
Uri uri = data.getData();
Log.e(TAG, "file auth is "+uri.getAuthority());
fullerror = fullerror +"file auth is "+uri.getAuthority();
if (imageuri.getAuthority().equals("media")){
tempID = imageuri.toString();
tempID = tempID.substring(tempID.lastIndexOf("/")+1);
id = tempID;
Uri contenturi = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
String selector = MediaStore.Images.Media._ID+"=?";
actualfilepath = getColunmData( contenturi, selector, new String[]{id} );
}else if (imageuri.getAuthority().equals("com.android.providers.media.documents")){
tempID = DocumentsContract.getDocumentId(imageuri);
String[] split = tempID.split(":");
String type = split[0];
id = split[1];
Uri contenturi = null;
if (type.equals("image")){
contenturi = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
}else if (type.equals("video")){
contenturi = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
}else if (type.equals("audio")){
contenturi = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
}
String selector = "_id=?";
actualfilepath = getColunmData( contenturi, selector, new String[]{id} );
} else if (imageuri.getAuthority().equals("com.android.providers.downloads.documents")){
tempID = imageuri.toString();
tempID = tempID.substring(tempID.lastIndexOf("/")+1);
id = tempID;
Uri contenturi = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
// String selector = MediaStore.Images.Media._ID+"=?";
actualfilepath = getColunmData( contenturi, null, null );
}else if (imageuri.getAuthority().equals("com.android.externalstorage.documents")){
tempID = DocumentsContract.getDocumentId(imageuri);
String[] split = tempID.split(":");
String type = split[0];
id = split[1];
Uri contenturi = null;
if (type.equals("primary")){
actualfilepath= Environment.getExternalStorageDirectory()+"/"+id;
}
}
File myFile = new File(actualfilepath);
// MessageDialog dialog = new MessageDialog(Home.this, " file details --"+actualfilepath+"\n---"+ uri.getPath() );
// dialog.displayMessageShow();
String temppath = uri.getPath();
if (temppath.contains("//")){
temppath = temppath.substring(temppath.indexOf("//")+1);
}
Log.e(TAG, " temppath is "+ temppath);
fullerror = fullerror +"\n"+" file details - "+actualfilepath+"\n --"+ uri.getPath()+"\n--"+temppath;
if ( actualfilepath.equals("") || actualfilepath.equals(" ")) {
myFile = new File(temppath);
}else {
myFile = new File(actualfilepath);
}
//File file = new File(actualfilepath);
//Log.e(TAG, " actual file path is "+ actualfilepath + " name ---"+ file.getName());
// File myFile = new File(actualfilepath);
Log.e(TAG, " myfile is "+ myFile.getAbsolutePath());
readfile(myFile);
// lyf path - /storage/emulated/0/kolektap/04-06-2018_Admin_1528088466207_file.xls
} catch (Exception e) {
Log.e(TAG, " read errro "+ e.toString());
}
//------------ /document/primary:kolektap/30-05-2018_Admin_1527671367030_file.xls
}
}
}
public String getColunmData( Uri uri, String selection, String[] selectarg){
String filepath ="";
Cursor cursor = null;
String colunm = "_data";
String[] projection = {colunm};
cursor = getContentResolver().query( uri, projection, selection, selectarg, null);
if (cursor!= null){
cursor.moveToFirst();
Log.e(TAG, " file path is "+ cursor.getString(cursor.getColumnIndex(colunm)));
filepath = cursor.getString(cursor.getColumnIndex(colunm));
}
if (cursor!= null)
cursor.close();
return filepath;
}
public void readfile(File file){
// File file = new File(Environment.getExternalStorageDirectory(), "bla.txt");
StringBuilder builder = new StringBuilder();
Log.e("main", "read start");
try {
BufferedReader br = new BufferedReader(new FileReader(file));
String line;
while ((line = br.readLine())!=null){
builder.append(line);
builder.append("\n");
names.add(line);
}
br.close();
}catch (Exception e){
Log.e("main", " error is "+e.toString());
}
Log.e("main", " read text is "+ builder.toString());
textView.setText(builder.toString());
openActivityDecision();
}
public void openActivityDecision()
{
Intent intent=new Intent(this,File_menu.class);
startActivity(intent);
}
}
activity_file_load.xml
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/ScrollView01"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".file_load">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/text2"
android:textColor="@color/colorAccent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.time_app">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".File_menu"></activity>
<activity android:name=".Browser" />
<activity android:name=".file_load" />
<activity android:name=".Manual_menu" />
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>