diff --git a/README.md b/README.md index 5afb343..107b2a7 100644 --- a/README.md +++ b/README.md @@ -1,101 +1,22 @@ -# cdr9020_qtr - +BurnInTest_QTR +================= +This sample is Camera2 recording and wifi,bt test: + +* [Camera2](https://developer.android.com/reference/android/hardware/camera2/package-summary.html) +* [Fragment](https://developer.android.com/reference/android/app/Fragment.html) +* [RestartApp](https://qiita.com/Shiozawa/items/85f078ed57aed46f6b69.html) + +Libraries Used +-------------- +* [Foundation][0] - Components for core system capabilities, Kotlin extensions and support for + multidex and automated testing. + * [AppCompat][1] - Degrade gracefully on older versions of Android. +* [UI][2] - Details on why and how to use UI Components in your apps - together or separate + * [Fragment][3] - A basic unit of composable UI. + * [Layout][4] - Lay out widgets using different algorithms. + +[0]: https://developer.android.com/jetpack/components +[1]: https://developer.android.com/topic/libraries/support-library/packages#v7-appcompat +[2]: https://developer.android.com/guide/topics/ui +[3]: https://developer.android.com/guide/components/fragments +[4]: https://developer.android.com/guide/topics/ui/declaring-layout diff --git a/app/build.gradle b/app/build.gradle index ed5d389..5d4998a 100755 --- a/app/build.gradle +++ b/app/build.gradle @@ -9,15 +9,15 @@ android { keyPassword 'android' } } - compileSdkVersion 28 + compileSdkVersion 30 defaultConfig { - applicationId "com.askey.record" - minSdkVersion 27 + applicationId "com.d160.bit" + minSdkVersion 23 //noinspection OldTargetApi - targetSdkVersion 27 - versionCode 2 + targetSdkVersion 30 + versionCode 1 versionName "1.0" - testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' signingConfig signingConfigs.debug } buildTypes { @@ -26,6 +26,8 @@ android { proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } debug { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } buildToolsVersion '28.0.3' @@ -43,14 +45,15 @@ dependencies { compileOnly files('libs/layoutlib.jar') implementation fileTree(include: ['*.jar'], dir: 'libs') //noinspection GradleDependency,GradleCompatible - implementation 'com.android.support.constraint:constraint-layout:1.0.2' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' //noinspection GradleDependency,GradleCompatible - implementation 'com.android.support.constraint:constraint-layout-solver:1.0.2' + implementation 'androidx.constraintlayout:constraintlayout-solver:1.1.3' //noinspection GradleDependency,GradleCompatible - implementation 'com.android.support:design:27.1.0' + implementation 'com.google.android.material:material:1.0.0' //noinspection GradleDependency,GradleCompatible - implementation 'com.android.support:support-v4:27.1.0' + implementation 'androidx.legacy:legacy-support-v4:1.0.0' //noinspection GradleDependency,GradleCompatible - implementation 'com.android.support:appcompat-v7:27.1.0' + implementation 'androidx.appcompat:appcompat:1.0.0' + //noinspection GradleDependency testImplementation 'junit:junit:4.13-rc-1' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index c96370d..cb8578c 100755 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,33 +1,37 @@ + + - - + - + + + @@ -36,14 +40,11 @@ - - - + android:theme="@android:style/Theme.Translucent.NoTitleBar" /> diff --git a/app/src/main/java/com/askey/record/Configini.java b/app/src/main/java/com/askey/record/Configini.java deleted file mode 100644 index 3333ce6..0000000 --- a/app/src/main/java/com/askey/record/Configini.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.askey.record; - -import android.content.Context; - -public class Configini { - - protected Context context; - protected String firstCamera = "0"; - protected String secondCamera = "1"; - protected int numberOfRuns = 999; - protected boolean isNew = true; - - public Configini(Context context) { - this.context = context; - } - - public Configini(Context context, String firstCamera, String secondCamera, int isRuns, boolean isNew) { - this.context = context; - this.firstCamera = firstCamera; - this.secondCamera = secondCamera; - this.numberOfRuns = isRuns; - this.isNew = isNew; - } - - protected String[] config() { - return new String[]{ - "[VIDEO_RECORD_CONFIG]" + context.getString(R.string.app_name) + "\r\n", - "#CameraID (0:Outer, 1:Inner, 2:External)\r\n", - "firstCameraID = " + firstCamera + "\r\n", - "secondCameraID = " + secondCamera + "\r\n", "\r\n", - "#Total number of runs (1 record is 1 min)\r\n", - "numberOfRuns = " + numberOfRuns + "\r\n", "\r\n", - "#Set Property\r\n", - "setProperty = " + isNew + "\r\n", "\r\n", - "#Video path\r\n", - "video1_path = /sdcard/(ddhhmmss)f.mp4\r\n", - "video2_path = /sdcard/(ddhhmmss)s.mp4\r\n", "\r\n", - "#Start\r\n", - "adb shell am start -n com.askey.record/.VideoRecordActivity\r\n", "\r\n", - "#Start test record(no audio, 5s)\r\n", - "adb shell am broadcast -a com.askey.record.t\r\n", "\r\n", - "#Start/Stop record\r\n", - "adb shell am broadcast -a com.askey.record.s\r\n", "\r\n", - "#Finish\r\n", - "adb shell am broadcast -a com.askey.record.f\r\n", "\r\n", - "#At the recording video, please don't copy the sd card file.\r\n", - "#At least 3.5Gb memory needs to be available to record.\r\n", - "#Sometimes need reboot device to wake up the External camera.\r\n", - "#Inner and External can't be used at the same time.\r\n", - "\r\n" - }; - } -} diff --git a/app/src/main/java/com/askey/record/Utils.java b/app/src/main/java/com/askey/record/Utils.java deleted file mode 100644 index ad51ffe..0000000 --- a/app/src/main/java/com/askey/record/Utils.java +++ /dev/null @@ -1,531 +0,0 @@ -package com.askey.record; - -import android.annotation.SuppressLint; -import android.content.Context; -import android.media.MediaExtractor; -import android.media.MediaFormat; -import android.os.Handler; -import android.util.SparseIntArray; -import android.view.Surface; -import android.view.View; -import android.widget.EditText; -import android.widget.TextView; - -import com.askey.widget.LogMsg; -import com.askey.widget.mLog; - -import java.io.BufferedReader; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.time.format.DateTimeFormatter; -import java.util.ArrayList; -import java.util.Calendar; - -import static com.askey.record.VideoRecordActivity.SD_Mode; -import static com.askey.record.VideoRecordActivity.onReset; -import static com.askey.record.VideoRecordActivity.saveLog; - -public class Utils { - public static final double[] DFRAME_RATE = {16, 27.5}, - NEW_DFRAME_RATE = {14, 28}; - public static final String[] FRAME_RATE = {"16fps", "27.5fps"}, - NEW_FRAME_RATE = {"14fps", "28fps"}; - public static final String[] FPS = {"140", "280"}; - public static final String FRAMESKIP = "persist.our.camera.fps"; - public static final String EXTRA_VIDEO_RUN = "RestartActivity.run"; - public static final String EXTRA_VIDEO_FAIL = "RestartActivity.fail"; - public static final String EXTRA_VIDEO_RESET = "RestartActivity.reset"; - public static final String EXTRA_VIDEO_RECORD = "RestartActivity.record"; - public static final String EXTRA_VIDEO_SUCCESS = "RestartActivity.success"; - public static final String EXTRA_VIDEO_COPY = "RestartActivity.copy"; - public static final String EXTRA_VIDEO_PASTE = "RestartActivity.paste"; - public static final String EXTRA_VIDEO_REMOVE = "RestartActivity.remove"; - public static final String EXTRA_VIDEO_VERSION = "RestartActivity.version"; - public static final String EXTRA_VIDEO_REFORMAT = "RestartActivity.reformat"; - public static final String NO_SD_CARD = "SD card is not available!"; - public static final SparseIntArray ORIENTATIONS = new SparseIntArray(); - public static final String configName = "VideoRecordConfig.ini"; - public static final String logName = "VideoRecordLog.ini"; - public static final double sdData = 1; - public static int isRun = 0, Success = 0, Fail = 0; - public static String TAG = "VideoRecord"; - public static String firstCamera = "0"; - public static String secondCamera = "1"; - public static String lastfirstCamera = "0"; - public static String lastsecondCamera = "1"; - public static String firstFile = ""; - public static String secondFile = ""; - public static ArrayList firstFilePath, secondFilePath; - public static ArrayList videoLogList = null; - public static int isFinish = 999, delayTime = 60000, isFrame = 0, isQuality = 0; - public static boolean isReady = false, isRecord = false, isError = false, isNew = true; - public static boolean fCamera = true, sCamera = true, getSdCard = false; - public static String errorMessage = ""; - - static { - ORIENTATIONS.append(Surface.ROTATION_0, 90); - ORIENTATIONS.append(Surface.ROTATION_90, 0); - ORIENTATIONS.append(Surface.ROTATION_180, 270); - ORIENTATIONS.append(Surface.ROTATION_270, 180); - } - - public static int getFail() { - return Fail; - } - - public static int getIsRun() { - return isRun; - } - - public static int getSuccess() { - return Success; - } - - public static int getReset() { - return onReset; - } - - public static boolean isInteger(String s, boolean zero) { - try { - if (Integer.parseInt(s) <= (zero ? 0 : -1)) { - return false; - } - } catch (Exception e) { - e.printStackTrace(); - return false; - } - return true; - } - - public static boolean isBoolean(String s) { - try { - if (Boolean.parseBoolean(s)) { - return true; - } - } catch (Exception e) { - e.printStackTrace(); - return false; - } - return true; - } - - public static void setTestTime(Context context, int min) { - if (min > 0) { - isFinish = min; - if (min != 999) - videoLogList.add(new LogMsg("setRecord time: " + min + " min.", mLog.d)); - else - videoLogList.add(new LogMsg("setRecord time: unlimited times.", mLog.d)); - } else { - videoLogList.add(new LogMsg("The test time must be a positive number.", mLog.e)); - } - } - - public static void checkConfigFile(Context context, boolean first) { - videoLogList.add(new LogMsg("#checkConfigFile", mLog.v)); - if (!getPath().equals("")) { - getSdCard = true; - File file = new File(getPath(), configName); - if (!file.exists()) { - try { - file.createNewFile(); - } catch (Exception e) { - e.printStackTrace(); - } - videoLogList.add(new LogMsg("Create the config file.", mLog.w)); - writeConfigFile(context, file, new Configini(context).config()); - } else { - if (!isReady) { - videoLogList.add(new LogMsg("Find the config file.", mLog.d)); - videoLogList.add(new LogMsg("#------------------------------", mLog.v)); - } - checkConfigFile(context, new File(getPath(), configName), first); - } - } else { - getSdCard = false; - } - } - - public static void checkLogFile(Context context, File file, ArrayList list) { - String input = readConfigFile(context, file); - if (input.length() > 0) { - String[] read = input.split("\r\n"); - for (String s : read) - list.add(s); - } - } - - public static boolean[] checkConfigFile(Context context, File file, boolean firstOne) { - try { - String input = readConfigFile(context, file); - boolean reformat = true, isCameraChange = false, isPropChange = false, update = true; - if (input.length() > 0) { - String[] read = input.split("\r\n"); - int target = 0, t; - String title = "[VIDEO_RECORD_CONFIG]"; - String first = "firstCameraID = ", second = "secondCameraID = "; - String code = "numberOfRuns = ", prop = "setProperty = "; - for (String s : read) - if (s.indexOf(title) != -1) { - target++; - t = s.indexOf(title) + title.length(); - title = s.substring(t); - break; - } - for (String s : read) - if (s.indexOf(first) != -1) { - target++; - t = s.indexOf(first) + first.length(); - first = s.substring(t); - break; - } - for (String s : read) - if (s.indexOf(second) != -1) { - target++; - t = s.indexOf(second) + second.length(); - second = s.substring(t); - break; - } - for (String s : read) - if (s.indexOf(code) != -1) { - target++; - t = s.indexOf(code) + code.length(); - code = s.substring(t); - break; - } - for (String s : read) - if (s.indexOf(prop) != -1) { - target++; - t = s.indexOf(prop) + prop.length(); - prop = s.substring(t); - break; - } - - if (target == 5) { - reformat = false; - if (title.equals(context.getString(R.string.app_name))) { - update = false; - } else { - videoLogList.add(new LogMsg("Config is updated.", mLog.e)); - reformat = true; - } - if (!first.equals(second)) { - if ((first.equals("1") && second.equals("2")) || (first.equals("2") && second.equals("1"))) { - videoLogList.add(new LogMsg("Inner and External can't be used at the same time.", mLog.e)); - reformat = true; - } else { - if (isCameraID(context, first.split("\n")[0], second.split("\n")[0])) { - lastfirstCamera = firstOne ? first : firstCamera; - lastsecondCamera = firstOne ? second : secondCamera; - firstCamera = first; - secondCamera = second; - if (!firstOne) - if (!lastfirstCamera.equals(firstCamera) || !lastsecondCamera.equals(secondCamera)) - isCameraChange = true; - } else { - videoLogList.add(new LogMsg("Unknown Camera ID.", mLog.e)); - reformat = true; - } - } - } else { - videoLogList.add(new LogMsg("Cannot use the same Camera ID.", mLog.e)); - reformat = true; - } - if (isInteger(code.split("\n")[0], true)) { - int min = Integer.parseInt(code.split("\n")[0]); - setTestTime(context, min); - } else { - videoLogList.add(new LogMsg("Unknown Record Times.", mLog.e)); - reformat = true; - } - if (isBoolean(prop)) { - if (Boolean.parseBoolean(prop)) { - if (isNew != Boolean.parseBoolean(prop)) - isPropChange = true; - isNew = Boolean.parseBoolean(prop); - } - } else { - videoLogList.add(new LogMsg("Unknown setProperty.", mLog.e)); - reformat = true; - } - } - } - if (update) { - String logString = "[VIDEO_RECORD_LOG]" + context.getString(R.string.app_name) + "\r\n"; - videoLogList.add(new LogMsg("Reformat the Log file.", mLog.e)); - for (LogMsg logs : videoLogList) { - String time = logs.time.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) - + " run:" + logs.runTime + " -> "; - logString += (time + logs.msg + "\r\n"); - } - try { - FileOutputStream output = new FileOutputStream(new File(getPath(), logName), false); - output.write(logString.getBytes()); - output.close(); - videoLogList.clear(); - - } catch (Exception e) { - e.printStackTrace(); - videoLogList.add(new LogMsg("Write LOG failed. <============ error here", mLog.e)); - } - } - if (reformat) { - reformatConfigFile(context, file); - return new boolean[]{true, true}; - } else return new boolean[]{isCameraChange, isPropChange}; - } catch (Exception e) { - e.printStackTrace(); - reformatConfigFile(context, file); - return new boolean[]{true, true}; - } - } - - public static boolean isCameraID(Context context, String f, String b) { - try { - if (Integer.parseInt(f) <= -1) { - videoLogList.add(new LogMsg("The Camera ID must be a positive number.", mLog.e)); - return false; - } else { - boolean cameraID; - switch (Integer.parseInt(f)) { - case 0: - case 1: - case 2: - cameraID = true; - break; - default: - cameraID = false; - break; - } - if (!cameraID) { - videoLogList.add(new LogMsg("The Camera ID is unknown.", mLog.e)); - return false; - } - } - if (Integer.parseInt(b) <= -1) { - videoLogList.add(new LogMsg("The Camera ID must be a positive number.", mLog.e)); - return false; - } else { - boolean cameraID; - switch (Integer.parseInt(b)) { - case 0: - case 1: - case 2: - cameraID = true; - break; - default: - cameraID = false; - break; - } - if (!cameraID) { - videoLogList.add(new LogMsg("The Camera ID is unknown.", mLog.e)); - return false; - } - } - return true; - } catch (Exception e) { - e.printStackTrace(); - return false; - } - } - - public static void setConfigFile(Context context, File file, View view, boolean reset) { - EditText editText_1 = view.findViewById(R.id.dialog_editText_1); - EditText editText_2 = view.findViewById(R.id.dialog_editText_2); - EditText editText_3 = view.findViewById(R.id.dialog_editText_3); - TextView editText_4 = view.findViewById(R.id.dialog_editText_4); - int isFinish = 999; - boolean isNew = true; - - if (!reset) { - if (isInteger(editText_3.getText().toString(), false)) { - isFinish = Integer.parseInt(editText_3.getText().toString()); - } else { - isFinish = 999; - } - if (isBoolean(editText_4.getText().toString())) { - isNew = Boolean.parseBoolean(editText_4.getText().toString()); - } else { - isNew = true; - } - } - - //toast(context, "Ready to write.", mLog.w); - writeConfigFile(context, file, ( - !reset ? new Configini(context, editText_1.getText().toString(), - editText_2.getText().toString(), isFinish, isNew) : new Configini(context)).config()); - //toast(context, "Write file is completed.", mLog.i); - } - - public static void reformatConfigFile(Context context, File file) { - //toast(context, "Config file error.", mLog.e); - writeConfigFile(context, file, new Configini(context).config()); - videoLogList.add(new LogMsg("Reformat the Config file.", mLog.e)); - } - - public static String readConfigFile(Context context, File file) { - String tmp = ""; - try { - FileInputStream input = new FileInputStream(file); - ByteArrayOutputStream bytes = new ByteArrayOutputStream(); - byte[] buffer = new byte[1024]; - int length; - while ((length = input.read(buffer)) != -1) { - bytes.write(buffer, 0, length); - } - tmp += bytes.toString(); - bytes.close(); - input.close(); - } catch (Exception e) { - e.printStackTrace(); - isError = true; - getSdCard = !getSDPath().equals(""); - videoLogList.add(new LogMsg("Read failed. " + NO_SD_CARD + ". <============ Crash here", mLog.e)); - new Handler().post(() -> saveLog(context, false, false)); - errorMessage = "Read failed." + NO_SD_CARD + "<============ Crash here"; - videoLogList.add(new LogMsg("Read failed.", mLog.e)); - tmp += ("App Version:" + context.getString(R.string.app_name) + "\r\n"); - tmp += (NO_SD_CARD); - return tmp; - } - return tmp; - } - - public static void writeConfigFile(Context context, File file, String[] str) { - if (getSdCard) { - String tmp = ""; - for (String s : str) - tmp += s; - try { - FileOutputStream output = new FileOutputStream(file); - output.write(tmp.getBytes()); - output.close(); - } catch (Exception e) { - e.printStackTrace(); - isError = true; - getSdCard = !getSDPath().equals(""); - videoLogList.add(new LogMsg("Write failed. " + NO_SD_CARD + ". <============ Crash here", mLog.e)); - new Handler().post(() -> saveLog(context, false, false)); - errorMessage = "Write failed. " + NO_SD_CARD + "<============ Crash here"; - } - } else { - videoLogList.add(new LogMsg(NO_SD_CARD, mLog.e)); - } - } - - @SuppressLint("DefaultLocale") - public static String getCalendarTime() { - String d, h, i, s; - Calendar calendar = Calendar.getInstance(); - d = String.format("%02d", calendar.get(Calendar.DATE)); - h = String.format("%02d", calendar.get(Calendar.HOUR_OF_DAY)); - i = String.format("%02d", calendar.get(Calendar.MINUTE)); - s = String.format("%02d", calendar.get(Calendar.SECOND)); - - return d + h + i + s + ""; - } - - @SuppressLint("DefaultLocale") - public static String getCalendarTime(boolean isCameraOne) { - String y, m, d, h, i, s; - Calendar calendar = Calendar.getInstance(); - y = String.format("%02d", calendar.get(Calendar.YEAR)); - m = String.format("%02d", (calendar.get(Calendar.MONTH) - 1)); - d = String.format("%02d", calendar.get(Calendar.DATE)); - h = String.format("%02d", calendar.get(Calendar.HOUR_OF_DAY)); - i = String.format("%02d", calendar.get(Calendar.MINUTE)); - s = String.format("%02d", calendar.get(Calendar.SECOND)); - - return "v" + y + m + d + h + i + s + (isCameraOne ? "f" : "s"); - } - - public static String getPath() { - String path = "/storage/emulated/0/DCIM/"; - return path; - } - - public static String getSDPath() { - String path = ""; - if(SD_Mode) { - try { - long start = System.currentTimeMillis(); - long end = start + 10000; - Runtime run = Runtime.getRuntime(); - String cmd = "ls /storage"; - Process pr = run.exec(cmd); - BufferedReader buf = new BufferedReader(new InputStreamReader(pr.getInputStream())); - String line; - while ((line = buf.readLine()) != null) { - if (!line.equals("self") && !line.equals("emulated") && !line.equals("enterprise") && !line.contains("sdcard")) { - path = "/storage/" + line + "/"; - break; - } - if (System.currentTimeMillis() > end) { - break; - } - } - } catch (Exception e) { - e.printStackTrace(); - } - }else{ - path = getPath(); - } - return path; - } - - public static int getFrameRate(String path) { - int frameRate = 0; - if (!getSDPath().equals("")) { - try { - MediaExtractor extractor = null; - FileInputStream fis = null; - try { - extractor = new MediaExtractor(); - fis = new FileInputStream(new File(path)); - extractor.setDataSource(fis.getFD()); - } catch (IOException e) { - e.printStackTrace(); - isError = true; - getSdCard = !getSDPath().equals(""); - errorMessage = "getFrameRate failed.<============ Crash here"; - videoLogList.add(new LogMsg("getFrameRate failed.", mLog.e)); - return 0; - } - int numTracks = extractor.getTrackCount(); - for (int i = 0; i < numTracks; i++) { - MediaFormat format = extractor.getTrackFormat(i); - if (format.containsKey(MediaFormat.KEY_FRAME_RATE)) { - frameRate = format.getInteger(MediaFormat.KEY_FRAME_RATE); - } - } - if (extractor != null) - extractor.release(); - if (fis != null) - fis.close(); - } catch (Exception e) { - e.printStackTrace(); - isError = true; - getSdCard = !getSDPath().equals(""); - errorMessage = "getFrameRate failed.<============ Crash here"; - videoLogList.add(new LogMsg("getFrameRate failed.", mLog.e)); - } - } else { - isError = true; - getSdCard = !getSDPath().equals(""); - errorMessage = "getFrameRate failed." + NO_SD_CARD + "<============ Crash here"; - videoLogList.add(new LogMsg("getFrameRate failed. " + NO_SD_CARD + ". <============ Crash here", mLog.e)); - } - return frameRate; - } - - public static String getFileExtension(String fullName) { - String fileName = new File(fullName).getName(); - int dotIndex = fileName.lastIndexOf('.'); - return (dotIndex == -1) ? "" : fileName.substring(dotIndex + 1); - } - -} diff --git a/app/src/main/java/com/askey/record/VideoRecordActivity.java b/app/src/main/java/com/askey/record/VideoRecordActivity.java deleted file mode 100644 index 94d1dfc..0000000 --- a/app/src/main/java/com/askey/record/VideoRecordActivity.java +++ /dev/null @@ -1,1514 +0,0 @@ -package com.askey.record; - -import android.Manifest; -import android.annotation.SuppressLint; -import android.annotation.TargetApi; -import android.app.Activity; -import android.app.AlertDialog; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.pm.PackageManager; -import android.content.res.Configuration; -import android.graphics.SurfaceTexture; -import android.hardware.camera2.CameraCaptureSession; -import android.hardware.camera2.CameraCharacteristics; -import android.hardware.camera2.CameraDevice; -import android.hardware.camera2.CameraManager; -import android.hardware.camera2.CameraMetadata; -import android.hardware.camera2.CaptureRequest; -import android.media.CamcorderProfile; -import android.media.MediaRecorder; -import android.os.Bundle; -import android.os.Handler; -import android.os.HandlerThread; -import android.os.Message; -import android.os.SystemProperties; -import android.support.v4.app.ActivityCompat; -import android.util.Log; -import android.util.Size; -import android.view.LayoutInflater; -import android.view.Surface; -import android.view.TextureView; -import android.view.View; -import android.widget.EditText; -import android.widget.ListView; -import android.widget.TextView; - -import com.askey.widget.CustomPageTransformer; -import com.askey.widget.CustomTextView; -import com.askey.widget.HomeListen; -import com.askey.widget.LogMsg; -import com.askey.widget.PropertyUtils; -import com.askey.widget.VerticalViewPager; -import com.askey.widget.mListAdapter; -import com.askey.widget.mLog; -import com.askey.widget.mPagerAdapter; - -import java.io.File; -import java.math.BigDecimal; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Timer; -import java.util.TimerTask; - -import static com.askey.record.Utils.DFRAME_RATE; -import static com.askey.record.Utils.EXTRA_VIDEO_COPY; -import static com.askey.record.Utils.EXTRA_VIDEO_FAIL; -import static com.askey.record.Utils.EXTRA_VIDEO_PASTE; -import static com.askey.record.Utils.EXTRA_VIDEO_RECORD; -import static com.askey.record.Utils.EXTRA_VIDEO_REFORMAT; -import static com.askey.record.Utils.EXTRA_VIDEO_REMOVE; -import static com.askey.record.Utils.EXTRA_VIDEO_RESET; -import static com.askey.record.Utils.EXTRA_VIDEO_RUN; -import static com.askey.record.Utils.EXTRA_VIDEO_SUCCESS; -import static com.askey.record.Utils.EXTRA_VIDEO_VERSION; -import static com.askey.record.Utils.FPS; -import static com.askey.record.Utils.FRAMESKIP; -import static com.askey.record.Utils.FRAME_RATE; -import static com.askey.record.Utils.NEW_DFRAME_RATE; -import static com.askey.record.Utils.NEW_FRAME_RATE; -import static com.askey.record.Utils.NO_SD_CARD; -import static com.askey.record.Utils.TAG; -import static com.askey.record.Utils.checkConfigFile; -import static com.askey.record.Utils.configName; -import static com.askey.record.Utils.delayTime; -import static com.askey.record.Utils.errorMessage; -import static com.askey.record.Utils.fCamera; -import static com.askey.record.Utils.Fail; -import static com.askey.record.Utils.firstCamera; -import static com.askey.record.Utils.firstFile; -import static com.askey.record.Utils.firstFilePath; -import static com.askey.record.Utils.getCalendarTime; -import static com.askey.record.Utils.getFail; -import static com.askey.record.Utils.getFrameRate; -import static com.askey.record.Utils.getIsRun; -import static com.askey.record.Utils.getPath; -import static com.askey.record.Utils.getReset; -import static com.askey.record.Utils.getSDPath; -import static com.askey.record.Utils.getSdCard; -import static com.askey.record.Utils.getSuccess; -import static com.askey.record.Utils.isError; -import static com.askey.record.Utils.isFinish; -import static com.askey.record.Utils.isFrame; -import static com.askey.record.Utils.isInteger; -import static com.askey.record.Utils.isNew; -import static com.askey.record.Utils.isQuality; -import static com.askey.record.Utils.isReady; -import static com.askey.record.Utils.isRecord; -import static com.askey.record.Utils.isRun; -import static com.askey.record.Utils.lastfirstCamera; -import static com.askey.record.Utils.lastsecondCamera; -import static com.askey.record.Utils.logName; -import static com.askey.record.Utils.readConfigFile; -import static com.askey.record.Utils.reformatConfigFile; -import static com.askey.record.Utils.sCamera; -import static com.askey.record.Utils.secondCamera; -import static com.askey.record.Utils.secondFile; -import static com.askey.record.Utils.secondFilePath; -import static com.askey.record.Utils.setConfigFile; -import static com.askey.record.Utils.Success; -import static com.askey.record.Utils.videoLogList; -import static com.askey.record.restartActivity.EXTRA_MAIN_PID; - -public class VideoRecordActivity extends Activity { - //TODO 使用SD Card儲存時 SD_Mode 設置為 true - public static boolean SD_Mode = true; - //TODO 使用錯誤重啟時 autoRestart 設置為 true - public static boolean autoRestart = true; - public static boolean extraRecordStatus = false, onRestart = false; - public static int onRun = 0, onSuccess = 0, onFail = 0, onReset = 0; - private static String codeDate0, codeDate1, resetDate; - private Size mPreviewSize; - private TextureView mTextureView0, mTextureView1; - private CameraDevice mCameraDevice0, mCameraDevice1; - private CameraCaptureSession mPreviewSession0, mPreviewSession1; - private CameraDevice.StateCallback mStateCallback0, mStateCallback1; - private CaptureRequest.Builder mPreviewBuilder0, mPreviewBuilder1; - private MediaRecorder mMediaRecorder0, mMediaRecorder1; - private Handler mainHandler, demoHandler; - private Handler recordHandler0, recordHandler1, stopRecordHandler0, stopRecordHandler1; - private Handler backgroundHandler0, backgroundHandler1; - private HandlerThread thread0, thread1; - private HomeListen home; - private mTimerTask timerTask = null; - private Timer mTimer = null; - private float mLaptime = 0.0f; - - private void getSetting(Context context, EditText editText1, EditText editText2, EditText editText3, TextView editText4) { - String input = readConfigFile(context, new File(getPath(), configName)); - if (input.length() > 0) { - String[] read = input.split("\r\n"); - int t; - String first = "firstCameraID = ", second = "secondCameraID = "; - String code = "numberOfRuns = ", prop = "setProperty = "; - for (String s : read) - if (s.indexOf(first) != -1) { - t = s.indexOf(first) + first.length(); - first = s.substring(t); - break; - } - for (String s : read) - if (s.indexOf(second) != -1) { - t = s.indexOf(second) + second.length(); - second = s.substring(t); - break; - } - for (String s : read) - if (s.indexOf(code) != -1) { - t = s.indexOf(code) + code.length(); - code = s.substring(t); - break; - } - for (String s : read) - if (s.indexOf(prop) != -1) { - t = s.indexOf(prop) + prop.length(); - prop = s.substring(t); - break; - } - editText1.setText(first); - editText2.setText(second); - editText3.setText(code); - editText4.setText(prop); - } else { - videoLogList.add(new LogMsg("Error reading config file.")); - reformatConfigFile(context, new File(getPath(), configName)); - } - } - - private void setRecord() { - isRecord = true; - checkConfigFile(VideoRecordActivity.this, new File(getPath(), configName), false); - if (extraRecordStatus) { - isRun = onRun; - Success = onSuccess; - Fail = onFail; - } else { - onReset = 0; - isRun = 0; - Success = 0; - Fail = 0; - } - extraRecordStatus = true; - firstFilePath.clear(); - secondFilePath.clear(); - } - - private void isRecordStart(boolean auto) { - if (!isError && getSdCard) { - if (isReady) { - if (!isRecord) { - if (!auto) - videoLogList.add(new LogMsg("@Start record", mLog.v)); - else - videoLogList.add(new LogMsg("#Start record", mLog.v)); - setRecord(); - takeRecord(); - - } else { - if (!auto) - videoLogList.add(new LogMsg("@Stop record", mLog.v)); - else - videoLogList.add(new LogMsg("#Stop record", mLog.v)); - isFinish = 0; - new Handler().post(() -> stopRecord(true)); - } - } else { - videoLogList.add(new LogMsg("#Camera is not ready.", mLog.v)); - } - } else { - stopRecordAndSaveLog(false); - showDialogLog(); - } - } - - private boolean checkPermission() { - videoLogList.add(new LogMsg("#checkPermission", mLog.v)); - int CAMERA = checkSelfPermission(Manifest.permission.CAMERA); - int STORAGE = checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE); - return permission(CAMERA) || permission(STORAGE); - } - - @TargetApi(23) - @SuppressLint("NewApi") - private void showPermission() { - videoLogList.add(new LogMsg("#showPermission", mLog.v)); - // We don't have permission so prompt the user - List permissions = new ArrayList(); - permissions.add(Manifest.permission.CAMERA); - permissions.add(Manifest.permission.WRITE_EXTERNAL_STORAGE); - requestPermissions(permissions.toArray(new String[permissions.size()]), 0); - } - - public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { - switch (requestCode) { - case 0: - if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { - // 許可授權 - setStart(); - } else { - // 沒有權限 - showPermission(); - videoLogList.add(new LogMsg("#no permissions!", mLog.e)); - videoLogList.add(new LogMsg("No permissions!")); - } - break; - default: - super.onRequestPermissionsResult(requestCode, permissions, grantResults); - } - } - - private boolean permission(int mp) { - return mp != PackageManager.PERMISSION_GRANTED; - } - - @SuppressLint("InflateParams") - private void setStart() { - setContentView(R.layout.activity_video_record); - setHomeListener(); - initial(); - } - - public void onConfigurationChanged(Configuration newConfig) { - super.onConfigurationChanged(newConfig); - Log.d(TAG, "onConfigurationChanged: E"); - // do nothing - } - - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - isRun = 0; - videoLogList = new ArrayList(); - if (checkPermission()) { - showPermission(); - } else { - checkConfigFile(this, true); - //TODO SETPROP - // -> adb shell su 0 getprop persist.our.camera.frameskip - if (isNew) { - try { - SystemProperties.set(FRAMESKIP, FPS[0]); - } catch (Exception e) { - e.getStackTrace(); - isError = true; - videoLogList.add(new LogMsg("SystemProperties error.", mLog.e)); - new Handler().post(() -> saveLog(this, false, false)); - errorMessage = "SystemProperties error. Please check your BuildVersion is 0302."; - } - } //*reflection invoke - setStart(); - - } - } - - private void setHomeListener() { - home = new HomeListen(this); - home.setOnHomeBtnPressListener(new HomeListen.OnHomeBtnPressLitener() { - public void onHomeBtnPress() { - videoLogList.add(new LogMsg("@home", mLog.v)); - stopRecordAndSaveLog(true); - } - - public void onHomeBtnLongPress() { - videoLogList.add(new LogMsg("@home", mLog.v)); - stopRecordAndSaveLog(true); - } - }); - home.start(); - } - - private void setCallback(int callback) { - try { - if (callback == 0) - mStateCallback0 = new CameraDevice.StateCallback() { - - public void onOpened(CameraDevice camera) { - fCamera = true; - if (!isReady) { - // 打开摄像头 - Log.e(TAG, "onOpened"); - videoLogList.add(new LogMsg("Camera " + firstCamera + " is opened.", mLog.i)); - } - mCameraDevice0 = camera; - // 开启预览 - takePreview(firstCamera); - } - - public void onDisconnected(CameraDevice camera) { - try { - fCamera = false; - camera.close(); - // 关闭摄像头 - Log.e(TAG, "onDisconnected"); - videoLogList.add(new LogMsg("Camera " + firstCamera + " is disconnected.", mLog.w)); - if (null != mCameraDevice0) { - mCameraDevice0.close(); - mCameraDevice0 = null; - } - } catch (Exception e) { - e.printStackTrace(); - isError = true; - videoLogList.add(new LogMsg("Camera " + firstCamera + " close error.", mLog.w)); - new Handler().post(() -> stopRecordAndSaveLog(false)); - errorMessage = "Camera " + firstCamera + " close error."; - ((TextView) findViewById(R.id.record_status)).setText("Error"); - } - if (autoRestart && isError) { - final String dates = resetDate + ""; - final boolean records = extraRecordStatus; - new Handler().postDelayed(() -> restartApp(dates, records), 3000); - } - } - - public void onError(CameraDevice camera, int error) { - isError = true; - onDisconnected(camera); - // 前鏡頭開啟失敗 - Log.e(TAG, "onError"); - closePreviewSession(firstCamera); - videoLogList.add(new LogMsg("Open Camera " + firstCamera + " error. <============ Crash here", mLog.e)); - new Handler().post(() -> stopRecordAndSaveLog(false)); - errorMessage = "Open Camera " + firstCamera + " error. <============ Crash here"; - ((TextView) findViewById(R.id.record_status)).setText("Error"); - } - }; - if (callback == 1) - mStateCallback1 = new CameraDevice.StateCallback() { - - public void onOpened(CameraDevice camera) { - sCamera = true; - if (!isReady) { - // 打开摄像头 - Log.e(TAG, "onOpened"); - videoLogList.add(new LogMsg("Camera " + secondCamera + " is opened.", mLog.i)); - } - mCameraDevice1 = camera; - // 开启预览 - takePreview(secondCamera); - if (!isReady) { - isReady = true; - new Handler().postDelayed(() -> demoHandler.obtainMessage().sendToTarget(), 500); - } - } - - public void onDisconnected(CameraDevice camera) { - try { - sCamera = false; - camera.close(); - // 关闭摄像头 - Log.e(TAG, "onDisconnected"); - videoLogList.add(new LogMsg("Camera " + secondCamera + " is disconnected.", mLog.w)); - if (null != mCameraDevice1) { - mCameraDevice1.close(); - mCameraDevice1 = null; - } - } catch (Exception e) { - e.printStackTrace(); - isError = true; - videoLogList.add(new LogMsg("Camera " + secondCamera + " close error.", mLog.w)); - new Handler().post(() -> stopRecordAndSaveLog(false)); - errorMessage = "Camera " + secondCamera + " close error."; - ((TextView) findViewById(R.id.record_status)).setText("Error"); - } - if (autoRestart && isError) { - final String dates = resetDate + ""; - final boolean records = extraRecordStatus; - new Handler().postDelayed(() -> restartApp(dates, records), 3000); - } - } - - public void onError(CameraDevice camera, int error) { - isError = true; - onDisconnected(camera); - // 前鏡頭開啟失敗 - Log.e(TAG, "onError"); - closePreviewSession(secondCamera); - videoLogList.add(new LogMsg("Open Camera " + secondCamera + " error. <============ Crash here", mLog.e)); - new Handler().post(() -> stopRecordAndSaveLog(false)); - errorMessage = "Open Camera " + secondCamera + " error. <============ Crash here"; - ((TextView) findViewById(R.id.record_status)).setText("Error"); - } - }; - } catch (Exception e) { - e.printStackTrace(); - getSdCard = !getSDPath().equals(""); - isError = true; - videoLogList.add(new LogMsg("CameraDevice.StateCallback " + callback + " error. <============ Crash here", mLog.e)); - new Handler().post(() -> stopRecordAndSaveLog(false)); - errorMessage = "CameraDevice.StateCallback " + callback + " error. <============ Crash here"; - ((TextView) findViewById(R.id.record_status)).setText("Error"); - if (autoRestart) { - final String dates = resetDate + ""; - final boolean records = extraRecordStatus; - new Handler().postDelayed(() -> restartApp(dates, records), 3000); - } - } - } - - private void stopRecordAndSaveLog(boolean kill) { - isFinish = 0; - if (isRecord) new Handler().post(() -> { - new Handler().post(() -> stopRecord(false)); - }); - new Handler().post(() -> saveLog(getApplicationContext(), false, kill)); - } - - private void restartApp(String date, boolean record) { - if (date.equals(resetDate)) { - try { - home.stop(); - } catch (Exception e) { - - } - onRestart = true; - onReset++; - Context context = getApplicationContext(); - Intent intent = restartActivity.createIntent(context); - intent.putExtra(EXTRA_VIDEO_RUN, onRun); - intent.putExtra(EXTRA_VIDEO_FAIL, onFail); - intent.putExtra(EXTRA_VIDEO_RESET, onReset); - intent.putExtra(EXTRA_VIDEO_SUCCESS, onSuccess); - intent.putExtra(EXTRA_VIDEO_RECORD, record); - context.startActivity(intent); - } - } - - @SuppressLint("HandlerLeak") - private void initial() { - getSdCard = !getSDPath().equals(""); - ArrayList items_frame = new ArrayList(); - ArrayList items_quality = new ArrayList(); - for (String frame : new ArrayList<>(Arrays.asList( // or "3.9fps", "3.4fps", "1.7fps", "0.8fps" - isNew ? NEW_FRAME_RATE : FRAME_RATE))) { - View vi = LayoutInflater.from(this).inflate(R.layout.style_vertical_item, null); - CustomTextView item = vi.findViewById(R.id.customTextView); - item.setText(frame); - items_frame.add(vi); - } - for (String quality : new ArrayList<>(Arrays.asList("1080p", "720p"))) { - View vi = LayoutInflater.from(this).inflate(R.layout.style_vertical_item, null); - CustomTextView item = vi.findViewById(R.id.customTextView); - item.setText(quality); - items_quality.add(vi); - } - VerticalViewPager pager_Frame = findViewById(R.id.pager1); - pager_Frame.addOnPageChangeListener(new mOnPageChangeListener(0)); - pager_Frame.setAdapter(new mPagerAdapter(items_frame)); - pager_Frame.setPageTransformer(true, new CustomPageTransformer()); - - VerticalViewPager pager_Quality = findViewById(R.id.pager2); - pager_Quality.addOnPageChangeListener(new mOnPageChangeListener(1)); - pager_Quality.setAdapter(new mPagerAdapter(items_quality)); - pager_Quality.setPageTransformer(true, new CustomPageTransformer()); - - // TODO findViewById - setLoading(false); - videoLogList.add(new LogMsg("Initial now.", mLog.v)); - thread0 = new HandlerThread("CameraPreview0"); - thread0.start(); - thread1 = new HandlerThread("CameraPreview1"); - thread1.start(); - backgroundHandler0 = new Handler(thread0.getLooper()); - backgroundHandler1 = new Handler(thread1.getLooper()); - mainHandler = new Handler(getMainLooper()); - recordHandler0 = new Handler() { - public void handleMessage(android.os.Message msg) { - startRecord(firstCamera); - } - }; - recordHandler1 = new Handler() { - public void handleMessage(android.os.Message msg) { - startRecord(secondCamera); - } - }; - stopRecordHandler0 = new Handler() { - public void handleMessage(android.os.Message msg) { - stopRecord(false, msg.obj.toString(), msg.arg1 + ""); - } - }; - stopRecordHandler1 = new Handler() { - public void handleMessage(android.os.Message msg) { - stopRecord(false, msg.obj.toString(), msg.arg1 + ""); - } - }; - - codeDate0 = getCalendarTime(); - codeDate1 = getCalendarTime(); - resetDate = getCalendarTime(); - setCallback(0); - setCallback(1); - mTextureView0 = findViewById(R.id.surfaceView0); - mTextureView0.setSurfaceTextureListener(new mSurfaceTextureListener(firstCamera)); - mTextureView1 = findViewById(R.id.surfaceView1); - mTextureView1.setSurfaceTextureListener(new mSurfaceTextureListener(secondCamera)); - - findViewById(R.id.cancel).setOnClickListener((View v) -> { - videoLogList.add(new LogMsg("@cancel", mLog.v)); - stopRecordAndSaveLog(true); - }); - findViewById(R.id.record).setOnClickListener((View v) -> { - isRecordStart(false); - }); - findViewById(R.id.setting).setOnClickListener((View v) -> { - if (getSdCard && !isError) { - videoLogList.add(new LogMsg("@dialog_setting", mLog.v)); - View view = LayoutInflater.from(this).inflate(R.layout.layout_setting, null); - final AlertDialog dialog = new AlertDialog.Builder(this).setView(view).setCancelable(false).create(); - view.findViewById(R.id.dialog_button_1).setOnClickListener((View vs) -> { // reset - videoLogList.add(new LogMsg("@setting_reset", mLog.v)); - setConfigFile(this, new File(getPath(), configName), view, true); - getSetting(this, view.findViewById(R.id.dialog_editText_1), view.findViewById(R.id.dialog_editText_2), - view.findViewById(R.id.dialog_editText_3), view.findViewById(R.id.dialog_editText_4)); - setSetting(); - }); - view.findViewById(R.id.dialog_button_2).setOnClickListener((View vs) -> { // cancel - videoLogList.add(new LogMsg("@setting_cancel", mLog.v)); - dialog.dismiss(); - }); - view.findViewById(R.id.dialog_button_3).setOnClickListener((View vs) -> { // ok - videoLogList.add(new LogMsg("@setting_ok", mLog.v)); - setConfigFile(this, new File(getPath(), configName), view, false); - setSetting(); - dialog.dismiss(); - }); - getSetting(this, view.findViewById(R.id.dialog_editText_1), view.findViewById(R.id.dialog_editText_2), - view.findViewById(R.id.dialog_editText_3), view.findViewById(R.id.dialog_editText_4)); - dialog.show(); - } else { - showDialogLog(); - } - }); - findViewById(R.id.loadingView).setVisibility(View.INVISIBLE); - ((TextView) findViewById(R.id.record_status)).setText(getSDPath().equals("") ? "Error" : "Ready"); - firstFilePath = new ArrayList(); - secondFilePath = new ArrayList(); - videoLogList.add(new LogMsg("#initial complete", mLog.v)); - onRun = getIntent().getIntExtra(EXTRA_VIDEO_RUN, 0); - onFail = getIntent().getIntExtra(EXTRA_VIDEO_FAIL, 0); - onReset = getIntent().getIntExtra(EXTRA_VIDEO_RESET, 0); - onSuccess = getIntent().getIntExtra(EXTRA_VIDEO_SUCCESS, 0); - if (onReset != 0) - videoLogList.add(new LogMsg("#noReset:" + onReset, mLog.v)); - extraRecordStatus = getIntent().getBooleanExtra(EXTRA_VIDEO_RECORD, false); - // show DEMO - demoHandler = new Handler() { - public void handleMessage(android.os.Message msg) { - this.post(() -> checkSdCardFromFileList()); - if (!extraRecordStatus) { - this.post(() -> saveLog(getApplicationContext(), false, false)); - } else { - isRecordStart(true); - } - } - }; - this.registerReceiver(new BroadcastReceiver() { - - public void onReceive(Context context, Intent intent) { - if (intent.getAction().equals(Intent.ACTION_BATTERY_CHANGED)) { //Battery - videoLogList.add(new LogMsg("Battery:" + intent.getIntExtra("level", 0) + "%", mLog.e)); - new Handler().post(() -> saveLog(getApplicationContext(), false, false)); - } - } - }, new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); - } - - private void setSetting() { - if (!isRecord) { - boolean[] check = checkConfigFile(this, new File(getPath(), configName), false); - if (check[0]) { - new Handler().post(() -> { - mStateCallback0.onDisconnected(mCameraDevice0); - mStateCallback1.onDisconnected(mCameraDevice1); - openCamera(firstCamera); - openCamera(secondCamera); - }); - } - if (check[1]) { - try { - SystemProperties.set(FRAMESKIP, FPS[0]); - if (isNew) { - String getFrameSkip = PropertyUtils.get(FRAMESKIP); - if (null != getFrameSkip) { - if (isInteger(getFrameSkip, false)) { - //if FrameSkip is change or LastCamera != CameraID, delay 3s to change camera devices - SystemProperties.set(FRAMESKIP, FPS[isFrame]); - videoLogList.add(new LogMsg("getFrameSkip:" + PropertyUtils.get(FRAMESKIP), mLog.e)); - } else { - videoLogList.add(new LogMsg("getFrameSkip error, fs(" + getFrameSkip + ") is not integer.", mLog.e)); - } - } else { - videoLogList.add(new LogMsg("getFrameSkip error, fs == null.", mLog.e)); - } - } - ArrayList new_frame = new ArrayList(); - for (String frame : new ArrayList<>(Arrays.asList( // or "3.9fps", "3.4fps", "1.7fps", "0.8fps" - isNew ? NEW_FRAME_RATE : FRAME_RATE))) { - View vi = LayoutInflater.from(this).inflate(R.layout.style_vertical_item, null); - CustomTextView item = vi.findViewById(R.id.customTextView); - item.setText(frame); - new_frame.add(vi); - } - ((VerticalViewPager) findViewById(R.id.pager1)).setAdapter(new mPagerAdapter(new_frame)); - } catch (Exception e) { - e.getStackTrace(); - isError = true; - videoLogList.add(new LogMsg("SystemProperties error.", mLog.e)); - new Handler().post(() -> saveLog(this, false, false)); - errorMessage = "SystemProperties error. Please check your BuildVersion is 0302."; - } - } - } else { - new Handler().post(() -> saveLog(getApplicationContext(), false, false)); - } - } - - private void showDialogLog() { - if (!isRecord) { - videoLogList.add(new LogMsg("#dialog_log", mLog.v)); - View view = LayoutInflater.from(this).inflate(R.layout.layout_getlog, null); - final AlertDialog dialog = new AlertDialog.Builder(this, android.R.style.Theme_Black_NoTitleBar_Fullscreen).setView(view).setCancelable(true).create(); - - view.findViewById(R.id.dialog_button_2).setOnClickListener((View vs) -> { // ok - videoLogList.add(new LogMsg("@log_ok", mLog.v)); - dialog.dismiss(); - }); - ArrayList list = new ArrayList(); - list.add("App Version:" + this.getString(R.string.app_name)); - if (getSdCard) - list.add("Please check file at your SD card"); - else list.add(NO_SD_CARD); - if (!fCamera) { - list.add("Camera Access error, Please check camera " + firstCamera + ". <============ Crash here"); - if (firstCamera.equals("2")) - list.add("You can try Reboot device to walk up external camera."); - } - if (!sCamera) { - list.add("Camera Access error, Please check camera " + secondCamera + ". <============ Crash here"); - if (secondCamera.equals("2")) - list.add("You can try Reboot device to walk up external camera."); - } - if (!errorMessage.equals("")) - list.add(errorMessage); - if (list.size() > 0) { - ArrayList items = new ArrayList(); - for (String s : list) { - View item_layout = LayoutInflater.from(this).inflate(R.layout.style_text_item, null); - ((CustomTextView) item_layout.findViewById(R.id.customTextView)).setText(s); - items.add(item_layout); - } - ((ListView) view.findViewById(R.id.dialog_listview)).setAdapter(new mListAdapter(items)); - ((ListView) view.findViewById(R.id.dialog_listview)).setSelection(items.size() - 1); - } - dialog.show(); - } - } - - private void setLoading(boolean visible) { - runOnUiThread(() -> findViewById(R.id.loadingView).setVisibility(visible ? View.VISIBLE : View.INVISIBLE)); - } - - private void takeRecord() { - if (!isError && getSdCard) { - videoLogList.add(new LogMsg("#------------------------------", mLog.v)); - videoLogList.add(new LogMsg("#takeRecord FrameRate:" + - (isNew ? NEW_FRAME_RATE : FRAME_RATE)[isFrame], mLog.v)); - int delay = 0; - if (!lastfirstCamera.equals(firstCamera) || !lastsecondCamera.equals(secondCamera)) { - lastfirstCamera = firstCamera; // String - lastsecondCamera = secondCamera; - new Handler().post(() -> { - mStateCallback0.onDisconnected(mCameraDevice0); - mStateCallback1.onDisconnected(mCameraDevice1); - openCamera(firstCamera); - openCamera(secondCamera); - }); - delay = 3000; - } - - recordHandler0.obtainMessage().sendToTarget(); - recordHandler1.obtainMessage().sendToTarget(); - new Handler().postDelayed(() -> saveLog(getApplicationContext(), false, false), delay); - } else { - stopRecordAndSaveLog(false); - showDialogLog(); - } - } - - public static void saveLog(Context context, boolean reFormat, boolean kill) { - if (!getSDPath().equals("")) { - String version = context.getString(R.string.app_name); - Intent intent = new Intent(); - intent.setClassName(context.getPackageName(), saveLogService.class.getName()); - intent.putExtra(EXTRA_VIDEO_VERSION, version); - intent.putExtra(EXTRA_VIDEO_REFORMAT, reFormat); - if (kill) - intent.putExtra(EXTRA_MAIN_PID, android.os.Process.myPid()); - context.startService(intent); - } else { - isError = true; - getSdCard = !getSDPath().equals(""); - if (kill) - android.os.Process.killProcess(android.os.Process.myPid()); - } - } - - protected void onDestroy() { - super.onDestroy(); - isFinish = 0; - if (mStateCallback0 != null) { - mStateCallback0.onDisconnected(mCameraDevice0); - mStateCallback0 = null; - } - if (mStateCallback1 != null) { - mStateCallback1.onDisconnected(mCameraDevice1); - mStateCallback1 = null; - } - closePreviewSession(firstCamera); - closePreviewSession(secondCamera); - if (mMediaRecorder0 != null) { - mMediaRecorder0.stop(); - mMediaRecorder0.release(); - videoLogList.add(new LogMsg("Record " + firstCamera + " finish.")); - } - if (mMediaRecorder1 != null) { - mMediaRecorder1.stop(); - mMediaRecorder1.release(); - videoLogList.add(new LogMsg("Record " + secondCamera + " finish.")); - } - new Handler().post(() -> stopRecordAndSaveLog(false)); - } - - private void openCamera(String cameraId) { - CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE); - Log.e(TAG, "openCamera E"); - try { - /** cameraId - * 0 = CameraCharacteristics.LENS_FACING_FRONT - * 1 = CameraCharacteristics.LENS_FACING_BACK - * 2 = CameraCharacteristics.LENS_FACING_EXTERNAL - */ - Log.e(TAG, "camera ID: " + cameraId); - Log.e(TAG, "number of camera: " + manager.getCameraIdList().length); - if (isCameraOne(cameraId)) - mPreviewSize = manager.getCameraCharacteristics(cameraId) - .get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP) - .getOutputSizes(SurfaceTexture.class)[0]; - if (ActivityCompat.checkSelfPermission(this, - Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { - return; - } - Log.e(TAG, "camera open"); - manager.openCamera(cameraId, isCameraOne(cameraId) ? mStateCallback0 : mStateCallback1, mainHandler); - } catch (Exception e) { - e.printStackTrace(); - isError = true; - videoLogList.add(new LogMsg("Camera Access error, Please check camera " + cameraId + ". <============ Crash here", mLog.e)); - new Handler().post(() -> stopRecordAndSaveLog(false)); - errorMessage = "Camera Access error, Please check camera " + cameraId + ". <============ Crash here"; - ((TextView) findViewById(R.id.record_status)).setText("Error"); - if (cameraId.equals("2")) - errorMessage += "\nYou can try Reboot device to walk up external camera."; - } - Log.e(TAG, "openCamera X"); - } - - private String getCodeDate(String CameraID) { - return (isCameraOne(CameraID)) ? codeDate0 : codeDate1; - } - - private void stopRecord(boolean preview, String date, String cameraID) { - try { - if (date.equals(getCodeDate(cameraID))) { - if (isCameraOne(cameraID)) - codeDate0 = getCalendarTime(); - else - codeDate1 = getCalendarTime(); - if (isCameraOne(cameraID)) { - if (mTimer != null) { - mTimer.cancel(); - mTimer = null; - } - ((TextView) findViewById(R.id.record_status)).setText("Stop"); - videoLogList.add(new LogMsg("#stopRecord", mLog.v)); - Log.d(TAG, "stopRecord"); - } else - moveFile(getPath() + logName, getSDPath() + logName, false); - - if (isCameraOne(cameraID)) { - if (mMediaRecorder0 != null) { - mMediaRecorder0.stop(); - mMediaRecorder0.release(); - videoLogList.add(new LogMsg("Record " + firstCamera + " finish.")); - } else { - videoLogList.add(new LogMsg("mMediaRecorder " + firstCamera + " is null.")); - } - } else { - if (mMediaRecorder1 != null) { - mMediaRecorder1.stop(); - mMediaRecorder1.release(); - videoLogList.add(new LogMsg("Record " + secondCamera + " finish.")); - } else { - videoLogList.add(new LogMsg("mMediaRecorder " + secondCamera + " is null.")); - } - } - checkAndClear(cameraID); - - if (isFinish == 999 || isRun <= isFinish) { - startRecord(cameraID); - } else { - isRun = 0; - isFinish = 0; - isRecord = false; - extraRecordStatus = false; - videoLogList.add(new LogMsg("#completed")); - end(preview); - } - if (isError || !getSdCard) { - isRun = 0; - isFinish = 0; - isRecord = false; - extraRecordStatus = false; - ((TextView) findViewById(R.id.record_status)).setText("Error"); - } - } - } catch (Exception e) { - e.printStackTrace(); - isError = true; - videoLogList.add(new LogMsg("Camera " + cameraID + " stopRecord error. <============ Crash here", mLog.e)); - new Handler().post(() -> stopRecordAndSaveLog(false)); - errorMessage = "Camera " + cameraID + " stopRecord error. <============ Crash here"; - ((TextView) findViewById(R.id.record_status)).setText("Error"); - if (autoRestart) { - final String dates = resetDate + ""; - final boolean records = extraRecordStatus; - new Handler().postDelayed(() -> restartApp(dates, records), 3000); - } - } - } - - private void stopRecord(boolean preview) { - try { - if (mTimer != null) { - mTimer.cancel(); - mTimer = null; - } - codeDate0 = getCalendarTime(); - codeDate1 = getCalendarTime(); - moveFile(getPath() + logName, getSDPath() + logName, false); - if (!isError && getSdCard) { - ((TextView) findViewById(R.id.record_status)).setText("Stop"); - if (isRecord) { - videoLogList.add(new LogMsg("#stopRecord", mLog.v)); - Log.d(TAG, "stopRecord"); - try { - if (mMediaRecorder0 != null) { - mMediaRecorder0.stop(); - mMediaRecorder0.release(); - videoLogList.add(new LogMsg("Record " + firstCamera + " finish.")); - } - } catch (Exception e) { - videoLogList.add(new LogMsg("mMediaRecorder0 is error.")); - } - try { - if (mMediaRecorder1 != null) { - mMediaRecorder1.stop(); - mMediaRecorder1.release(); - videoLogList.add(new LogMsg("Record " + secondCamera + " finish.")); - } - } catch (Exception e) { - videoLogList.add(new LogMsg("mMediaRecorder1 is error.")); - } - try { - checkAndClear(); - } catch (Exception e) { - videoLogList.add(new LogMsg("Check file is fail.")); - } - if (isFinish == 999 || isRun <= isFinish) { - takeRecord(); - } else { - isRecord = false; - extraRecordStatus = false; - videoLogList.add(new LogMsg("#------------------------------", mLog.v)); - videoLogList.add(new LogMsg("#completed")); - isRun = 0; - isFinish = 0; - end(preview); - } - } else { - isRun = 0; - isFinish = 0; - end(preview); - } - } else { - ((TextView) findViewById(R.id.record_status)).setText("Error"); - } - } catch (Exception e) { - e.printStackTrace(); - isError = true; - videoLogList.add(new LogMsg("stopRecord all camera error. <============ Crash here", mLog.e)); - new Handler().post(() -> stopRecordAndSaveLog(false)); - errorMessage = "stopRecord all camera error. <============ Crash here"; - ((TextView) findViewById(R.id.record_status)).setText("Error"); - if (autoRestart) { - final String dates = resetDate + ""; - final boolean records = extraRecordStatus; - new Handler().postDelayed(() -> restartApp(dates, records), 3000); - } - } - } - - private void end(boolean preview) { - new Handler().post(() -> saveLog(getApplicationContext(), false, false)); - if (preview) { - takePreview(); - } - } - - private void moveFile(String video, String pathname, boolean remove) { - if (SD_Mode) { - Context context = getApplicationContext(); - Intent intent = new Intent(); - intent.setClassName(context.getPackageName(), copyFileService.class.getName()); - intent.putExtra(EXTRA_VIDEO_COPY, video); - intent.putExtra(EXTRA_VIDEO_PASTE, pathname); - intent.putExtra(EXTRA_VIDEO_REMOVE, remove); - context.startService(intent); - } - } - - @SuppressLint("DefaultLocale") - private void fileCheck(String path) { - try { - File video = new File(path); - int frameRate = 0; - - if (video.exists()) { - try { - frameRate = getFrameRate(path); - - } catch (Exception e) { - e.printStackTrace(); - videoLogList.add(new LogMsg("CheckFile error.", mLog.e)); - new Handler().post(() -> saveLog(getApplicationContext(), false, false)); - errorMessage = "CheckFile error."; - } - - boolean check = false; - double[] range = isNew ? NEW_DFRAME_RATE : DFRAME_RATE; - if (frameRate >= range[isFrame]) { - if (frameRate <= range[isFrame] + 3) { - check = true; - } - } else if (frameRate < range[isFrame]) { - if (frameRate >= range[isFrame] - 3) { - check = true; - } - } - if (check) - Success++; - else - Fail++; - } else { - Fail++; - } - videoLogList.add(new LogMsg("CheckFile: " + path.split("/")[3] + " frameRate:" + frameRate + - " success:" + getSuccess() + " fail:" + getFail() + " reset:" + getReset(), mLog.i)); - new Handler().post(() -> saveLog(getApplicationContext(), false, false)); - } catch (Exception e) { - e.printStackTrace(); - videoLogList.add(new LogMsg("CheckFile error.", mLog.e)); - new Handler().post(() -> saveLog(getApplicationContext(), false, false)); - } - } - - private void closePreviewSession(String cameraId) { - if (isCameraOne(cameraId) && mPreviewSession0 != null) { - mPreviewSession0.close(); - mPreviewSession0 = null; - } - if (!isCameraOne(cameraId) && mPreviewSession1 != null) { - mPreviewSession1.close(); - mPreviewSession1 = null; - } - } - - private void startRecord(String cameraId) { - if (!isError) { - Log.d(TAG, "startRecord"); - try { - if (isCameraOne(cameraId)) - codeDate0 = getCalendarTime(); - else - codeDate1 = getCalendarTime(); - - if (isCameraOne(cameraId)) { - checkSdCardFromFileList(); - runOnUiThread(() -> { - if (mTimer == null) { - isRun++; - onFail = getFail(); - onRun = getIsRun(); - onSuccess = getSuccess(); - //タイマーの初期化処理 - timerTask = new mTimerTask(); - mLaptime = 0.0f; - mTimer = new Timer(true); - mTimer.schedule(timerTask, 100, 100); - ((TextView) findViewById(R.id.record_timer)).setText("00"); - ((TextView) findViewById(R.id.record_status)).setText("Recording"); - } - }); - } - closePreviewSession(cameraId); - SurfaceTexture texture = isCameraOne(cameraId) ? mTextureView0.getSurfaceTexture() : mTextureView1.getSurfaceTexture(); - if (null == texture) { - Log.e(TAG, "texture is null, return"); - return; - } - - texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight()); - Surface surface = new Surface(texture); - List surfaces = new ArrayList<>(); - CameraDevice mCameraDevice; - CaptureRequest.Builder mPreviewBuilder; - Surface recorderSurface; - Handler backgroundHandler; - if (isCameraOne(cameraId)) { - backgroundHandler = backgroundHandler0; - mCameraDevice = mCameraDevice0; - mMediaRecorder0 = setUpMediaRecorder(firstCamera); - mPreviewBuilder0 = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_RECORD); - surfaces.add(surface); - mPreviewBuilder0.addTarget(surface); - recorderSurface = mMediaRecorder0.getSurface(); - surfaces.add(recorderSurface); - mPreviewBuilder0.addTarget(recorderSurface); - mPreviewBuilder = mPreviewBuilder0; - } else { - backgroundHandler = backgroundHandler1; - mCameraDevice = mCameraDevice1; - mMediaRecorder1 = setUpMediaRecorder(secondCamera); - mPreviewBuilder1 = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_RECORD); - surfaces.add(surface); - mPreviewBuilder1.addTarget(surface); - recorderSurface = mMediaRecorder1.getSurface(); - surfaces.add(recorderSurface); - mPreviewBuilder1.addTarget(recorderSurface); - mPreviewBuilder = mPreviewBuilder1; - } - // Start a capture session - // Once the session starts, we can update the UI and start recording - if (mPreviewBuilder != null) { - - try { - mCameraDevice.createCaptureSession(surfaces, - new CameraCaptureSession.StateCallback() { - - public void onConfigured(CameraCaptureSession session) { - // 当摄像头已经准备好时,开始显示预览 - if (isCameraOne(cameraId)) { - mPreviewSession0 = session; - } else { - mPreviewSession1 = session; - } - updatePreview(mPreviewBuilder, session, backgroundHandler); - - if (isCameraOne(cameraId)) { - Message msg = stopRecordHandler0.obtainMessage(); - msg.arg1 = Integer.parseInt(cameraId); - msg.obj = getCodeDate(cameraId); - stopRecordHandler0.sendMessageDelayed(msg, delayTime); - if (mMediaRecorder0 != null) - mMediaRecorder0.start(); - } else { - Message msg = stopRecordHandler1.obtainMessage(); - msg.arg1 = Integer.parseInt(cameraId); - msg.obj = getCodeDate(cameraId); - stopRecordHandler1.sendMessageDelayed(msg, delayTime); - if (mMediaRecorder1 != null) - mMediaRecorder1.start(); - } - - } - - public void onConfigureFailed(CameraCaptureSession cameraCaptureSession) { - videoLogList.add(new LogMsg("Camera " + cameraId + " Record onConfigureFailed.", mLog.e)); - new Handler().post(() -> saveLog(getApplicationContext(), false, false)); - } - }, backgroundHandler); - } catch (Exception e) { - e.printStackTrace(); - isError = true; - videoLogList.add(new LogMsg("Camera " + cameraId + " CameraCaptureSession.StateCallback() error. <============ Crash here", mLog.e)); - new Handler().post(() -> stopRecordAndSaveLog(false)); - errorMessage = "Camera " + cameraId + " startRecord error. <============ Crash here"; - ((TextView) findViewById(R.id.record_status)).setText("Error"); - if (autoRestart) { - final String dates = resetDate + ""; - final boolean records = extraRecordStatus; - new Handler().postDelayed(() -> restartApp(dates, records), 3000); - } - } - } else { - isError = true; - videoLogList.add(new LogMsg("Camera " + cameraId + " mPreviewBuilder is null. <============ Crash here", mLog.e)); - new Handler().post(() -> stopRecordAndSaveLog(false)); - errorMessage = "Camera " + cameraId + " mPreviewBuilder is null. <============ Crash here"; - ((TextView) findViewById(R.id.record_status)).setText("Error"); - if (autoRestart) { - final String dates = resetDate + ""; - final boolean records = extraRecordStatus; - new Handler().postDelayed(() -> restartApp(dates, records), 3000); - } - } - } catch (Exception e) { - e.printStackTrace(); - isError = true; - videoLogList.add(new LogMsg("Camera " + cameraId + " startRecord error. <============ Crash here", mLog.e)); - new Handler().post(() -> stopRecordAndSaveLog(false)); - errorMessage = "Camera " + cameraId + " startRecord error. <============ Crash here"; - ((TextView) findViewById(R.id.record_status)).setText("Error"); - if (autoRestart) { - final String dates = resetDate + ""; - final boolean records = extraRecordStatus; - new Handler().postDelayed(() -> restartApp(dates, records), 3000); - } - } - } - } - - private void checkSdCardFromFileList() { - Context context = getApplicationContext(); - Intent intent = new Intent(); - intent.setClassName(context.getPackageName(), checkSdCardService.class.getName()); - context.startService(intent); - } - - private void checkAndClear(String cameraID) { - if (isCameraOne(cameraID)) { - try { - for (String f : firstFilePath) - fileCheck(f); - } catch (Exception e) { - videoLogList.add(new LogMsg("CheckFile " + cameraID + " error.", mLog.e)); - } finally { - firstFilePath.clear(); - } - } - if (!isCameraOne(cameraID)) { - try { - for (String s : secondFilePath) - fileCheck(s); - } catch (Exception e) { - videoLogList.add(new LogMsg("CheckFile " + cameraID + " error.", mLog.e)); - } finally { - secondFilePath.clear(); - } - } - } - - private void checkAndClear() { - for (String f : firstFilePath) - fileCheck(f); - for (String s : secondFilePath) - fileCheck(s); - firstFilePath.clear(); - secondFilePath.clear(); - } - - private MediaRecorder setUpMediaRecorder(String cameraId) { - MediaRecorder mediaRecorder = null; - try { - /*TODO CamcorderProfile.QUALITY_HIGH:质量等级对应于最高可用分辨率*/// 1080p, 720p - CamcorderProfile profile_720 = CamcorderProfile.get(CamcorderProfile.QUALITY_720P); - CamcorderProfile profile_1080 = CamcorderProfile.get(CamcorderProfile.QUALITY_1080P); - String file = ""; - if (!getSDPath().equals("")) { - file = getSDPath() + getCalendarTime(isCameraOne(cameraId)) + ".mp4"; - videoLogList.add(new LogMsg("Create: " + file.split("/")[3], mLog.w)); - - (isCameraOne(cameraId) ? firstFilePath : secondFilePath).add(file); - if (isCameraOne(cameraId)) - firstFile = file + ""; - else - secondFile = file + ""; - // Step 1: Unlock and set camera to MediaRecorder - CamcorderProfile profile = isQuality == 1 ? profile_720 : profile_1080; - mediaRecorder = new MediaRecorder(); - // Step 2: Set sources - if (isCameraOne(cameraId)) - mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); - mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE); - mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); - if (isCameraOne(cameraId)) - mediaRecorder.setAudioEncoder(profile.audioCodec); - mediaRecorder.setVideoEncoder(profile.videoCodec); - mediaRecorder.setVideoSize(profile.videoFrameWidth, profile.videoFrameHeight); - if (isCameraOne(cameraId)) - mediaRecorder.setAudioEncodingBitRate(profile.audioBitRate); - mediaRecorder.setVideoEncodingBitRate((int) (profile.videoBitRate / 3.3)); - if (isCameraOne(cameraId)) { - mediaRecorder.setAudioChannels(profile.audioChannels); - mediaRecorder.setAudioSamplingRate(profile.audioSampleRate); - } - /*设置要捕获的视频的帧速率*/ // default is 24.6 - mediaRecorder.setVideoFrameRate(!isNew ? isFrame == 0 ? 10 : 28 : 27); // 1 -> 12fps, 10 -> 16fps - // Step 4: Set output file - mediaRecorder.setOutputFile(file); - // Step 5: Prepare configured MediaRecorder - mediaRecorder.prepare(); - } else { - getSdCard = !getSDPath().equals(""); - isError = true; - videoLogList.add(new LogMsg("MediaRecorder error. " + NO_SD_CARD + " <============ Crash here", mLog.e)); - new Handler().post(() -> stopRecordAndSaveLog(false)); - errorMessage = "MediaRecorder error. " + NO_SD_CARD + " <============ Crash here"; - ((TextView) findViewById(R.id.record_status)).setText("Error"); - return null; - } - } catch (Exception e) { - e.printStackTrace(); - getSdCard = !getSDPath().equals(""); - isError = true; - videoLogList.add(new LogMsg("MediaRecorder " + cameraId + " error. <============ Crash here", mLog.e)); - new Handler().post(() -> stopRecordAndSaveLog(false)); - errorMessage = "MediaRecorder " + cameraId + " error. <============ Crash here"; - ((TextView) findViewById(R.id.record_status)).setText("Error"); - if (getSdCard) { - if (autoRestart) { - final String dates = resetDate + ""; - final boolean records = extraRecordStatus; - new Handler().postDelayed(() -> restartApp(dates, records), 3000); - } - } else { - videoLogList.add(new LogMsg(NO_SD_CARD, mLog.e)); - } - } - return mediaRecorder; - } - - private void takePreview() { - takePreview(firstCamera); - takePreview(secondCamera); - } - - private void takePreview(String cameraId) { - Log.d(TAG, "takePreview"); - videoLogList.add(new LogMsg("Preview " + cameraId + " Camera.", mLog.i)); - SurfaceTexture texture = null; - try { - texture = isCameraOne(cameraId) ? mTextureView0.getSurfaceTexture() : mTextureView1.getSurfaceTexture(); - } catch (Exception e) { - e.printStackTrace(); - isError = true; - videoLogList.add(new LogMsg("takePreview " + cameraId + " error. <============ Crash here", mLog.e)); - new Handler().post(() -> stopRecordAndSaveLog(false)); - errorMessage = "takePreview " + cameraId + " error. <============ Crash here"; - ((TextView) findViewById(R.id.record_status)).setText("Error"); - if (autoRestart) { - final String dates = resetDate + ""; - final boolean records = extraRecordStatus; - new Handler().postDelayed(() -> restartApp(dates, records), 3000); - } - } - if (null != texture) { - texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight()); - Surface surface = new Surface(texture); - - CaptureRequest.Builder mPreviewBuilder; - CameraDevice mCameraDevice; - Handler backgroundHandler; - if (isCameraOne(cameraId)) { - backgroundHandler = backgroundHandler0; - mCameraDevice = mCameraDevice0; - } else { - backgroundHandler = backgroundHandler1; - mCameraDevice = mCameraDevice1; - } - if (!isError) { - try { - mPreviewBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW); - - mPreviewBuilder.addTarget(surface); - - // CaptureRequest.CONTROL_MODE - mCameraDevice.createCaptureSession(Arrays.asList(surface), - new CameraCaptureSession.StateCallback() { - - public void onConfigured(CameraCaptureSession session) { - // 当摄像头已经准备好时,开始显示预览 - if (isCameraOne(cameraId)) { - mPreviewSession0 = session; - } else { - mPreviewSession1 = session; - } - updatePreview(mPreviewBuilder, session, backgroundHandler); - } - - - public void onConfigureFailed(CameraCaptureSession session) { - videoLogList.add(new LogMsg("Preview " + cameraId + " onConfigureFailed", mLog.e)); - } - }, backgroundHandler); - } catch (Exception e) { - e.printStackTrace(); - isError = true; - videoLogList.add(new LogMsg("Preview " + cameraId + " error.", mLog.e)); - new Handler().post(() -> stopRecordAndSaveLog(false)); - errorMessage = "Preview " + cameraId + " error."; - ((TextView) findViewById(R.id.record_status)).setText("Error"); - if (autoRestart) { - final String dates = resetDate + ""; - final boolean records = extraRecordStatus; - new Handler().postDelayed(() -> restartApp(dates, records), 3000); - } - } - } - } - } - - protected void updatePreview(CaptureRequest.Builder mPreviewBuilder, CameraCaptureSession mPreviewSession, Handler backgroundHandler) { - mPreviewBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO); - try { - mPreviewSession.setRepeatingRequest(mPreviewBuilder.build(), null, backgroundHandler); - } catch (Exception e) { - e.printStackTrace(); - isError = true; - videoLogList.add(new LogMsg("setCaptureRequest error.", mLog.e)); - new Handler().post(() -> stopRecordAndSaveLog(false)); - errorMessage = "setCaptureRequest error."; - ((TextView) findViewById(R.id.record_status)).setText("Error"); - if (autoRestart) { - final String dates = resetDate + ""; - final boolean records = extraRecordStatus; - new Handler().postDelayed(() -> restartApp(dates, records), 3000); - } - } - } - - private boolean isCameraOne(String cameraId) { - return cameraId.equals(firstCamera); - } - - private class mTimerTask extends TimerTask { - - - public void run() { - // mHandlerを通じてUI Threadへ処理をキューイング - runOnUiThread(() -> { - //実行間隔分を加算処理 - mLaptime += 0.1d; - if (mLaptime >= 65) { - isError = true; - videoLogList.add(new LogMsg("Application has timed out.", mLog.w)); - new Handler().post(() -> stopRecordAndSaveLog(false)); - errorMessage = "Application has timed out."; - new Handler().post(() -> ((TextView) findViewById(R.id.record_status)).setText("Error")); - if (autoRestart) { - final String dates = resetDate + ""; - final boolean records = extraRecordStatus; - new Handler().postDelayed(() -> restartApp(dates, records), 3000); - } - } - //計算にゆらぎがあるので小数点第1位で丸める - BigDecimal bi = new BigDecimal(mLaptime); - float outputValue = bi.setScale(1, BigDecimal.ROUND_HALF_UP).floatValue(); - //現在のLapTime - ((TextView) findViewById(R.id.record_timer)).setText(Float.toString(outputValue)); - }); - } - } - - private class mSurfaceTextureListener implements TextureView.SurfaceTextureListener { - String CameraID; - - public mSurfaceTextureListener(String CameraID) { - this.CameraID = CameraID; - } - - public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) { - openCamera(CameraID); - } - - public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) { - - } - - public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) { - return false; - } - - public void onSurfaceTextureUpdated(SurfaceTexture surface) { - - } - } - - private class mOnPageChangeListener implements VerticalViewPager.OnPageChangeListener { - int pos; - - public mOnPageChangeListener(int pos) { - this.pos = pos; - } - - public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { - - } - - public void onPageSelected(int position) { - switch (pos) { - case 0: - if (!isRecord) { - isFrame = position; - if (isNew) { - setLoading(true); - new Handler().post(() -> { - String getFrameSkip = PropertyUtils.get(FRAMESKIP); - if (null != getFrameSkip) { - if (isInteger(getFrameSkip, false)) { - //if frameskip is chehe or lastcamera != cameraid, delay 3s to change camera devices - try { - SystemProperties.set(FRAMESKIP, FPS[isFrame]); - } catch (Exception e) { - e.getStackTrace(); - isError = true; - videoLogList.add(new LogMsg("SystemProperties error.", mLog.e)); - new Handler().post(() -> saveLog(getApplicationContext(), false, false)); - errorMessage = "SystemProperties error. Please check your BuildVersion is 0302."; - } - videoLogList.add(new LogMsg("getFrameSkip:" + PropertyUtils.get(FRAMESKIP), mLog.e)); - mStateCallback0.onDisconnected(mCameraDevice0); - mStateCallback1.onDisconnected(mCameraDevice1); - new Handler().post(() -> openCamera(firstCamera)); - new Handler().post(() -> openCamera(secondCamera)); - } else { - videoLogList.add(new LogMsg("getFrameSkip error, fs(" + getFrameSkip + ") is not integer.", mLog.e)); - } - } else { - videoLogList.add(new LogMsg("getFrameSkip error, fs == null.", mLog.e)); - } - setLoading(false); - }); - } - } else { - ((VerticalViewPager) findViewById(R.id.pager1)).setCurrentItem(isFrame); - } - break; - case 1: - if (!isRecord) { - isQuality = position; - } else { - ((VerticalViewPager) findViewById(R.id.pager2)).setCurrentItem(isQuality); - } - break; - default: - break; - } - } - - public void onPageScrollStateChanged(int state) { - - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/askey/record/checkSdCardService.java b/app/src/main/java/com/askey/record/checkSdCardService.java deleted file mode 100644 index 007521a..0000000 --- a/app/src/main/java/com/askey/record/checkSdCardService.java +++ /dev/null @@ -1,158 +0,0 @@ -package com.askey.record; - - -import android.app.IntentService; -import android.content.Context; -import android.content.Intent; -import android.os.StatFs; - -import com.askey.widget.LogMsg; -import com.askey.widget.mLog; - -import java.io.File; -import java.util.ArrayList; -import java.util.Arrays; - -import static com.askey.record.Utils.EXTRA_VIDEO_REFORMAT; -import static com.askey.record.Utils.EXTRA_VIDEO_VERSION; -import static com.askey.record.Utils.NO_SD_CARD; -import static com.askey.record.Utils.errorMessage; -import static com.askey.record.Utils.firstFile; -import static com.askey.record.Utils.getSDPath; -import static com.askey.record.Utils.getSdCard; -import static com.askey.record.Utils.isError; -import static com.askey.record.Utils.sdData; -import static com.askey.record.Utils.secondFile; -import static com.askey.record.Utils.videoLogList; - -public class checkSdCardService extends IntentService { - - public checkSdCardService() { - // ActivityのstartService(intent);で呼び出されるコンストラクタはこちら - super("checkSdCardService"); - } - - private void saveLog(Context context) { - Intent intent = new Intent(); - intent.setClassName(context.getPackageName(), saveLogService.class.getName()); - intent.putExtra(EXTRA_VIDEO_VERSION, context.getString(R.string.app_name)); - intent.putExtra(EXTRA_VIDEO_REFORMAT, false); - context.startService(intent); - } - - private void checkSdCardFromFileList() { - getSdCard = !getSDPath().equals(""); - if (getSdCard) { - try { - StatFs stat = new StatFs(getSDPath()); - long sdAvailSize = stat.getAvailableBlocksLong() - * stat.getBlockSizeLong(); - double gigaAvailable = (sdAvailSize >> 30); - if (gigaAvailable < sdData) { - if (null != videoLogList) { - videoLogList.add(new LogMsg("SD Card is Full.")); - } - ArrayList tmp = new ArrayList(); - File[] fileList = new File(getSDPath()).listFiles(); - for (int i = 0; i < fileList.length; i++) { - // Recursive call if it's a directory - File file = fileList[i]; - if (!fileList[i].isDirectory()) { - if (Utils.getFileExtension(file.toString()).equals("mp4")) - if (!file.toString().equals(firstFile) || !file.toString().equals(secondFile)) - tmp.add(file.toString()); - } - } - if (tmp.size() >= 2) { - Object[] list = tmp.toArray(); - Arrays.sort(list); - delete((String) list[0], true); - delete((String) list[1], true); - checkSdCardFromFileList(); - } - } - } catch (Exception e) { - e.printStackTrace(); - isError = true; - getSdCard = !getSDPath().equals(""); - if (getSdCard) { - if (null != videoLogList) { - videoLogList.add(new LogMsg("#error: At least " + sdData + " memory needs to be available to record, please check the SD Card free space.", mLog.e)); - saveLog(this); - } - errorMessage = "error: At least " + sdData + " memory needs to be available to record, please check the SD Card free space."; -// ((TextView) findViewById(R.id.record_status)).setText("Error"); - } else { - if (null != videoLogList) { - videoLogList.add(new LogMsg(NO_SD_CARD, mLog.e)); - saveLog(this); - } - errorMessage = NO_SD_CARD; - } - } - } else { - isError = true; - if (null != videoLogList) { - videoLogList.add(new LogMsg(NO_SD_CARD, mLog.e)); - saveLog(this); - } - errorMessage = NO_SD_CARD; - } - } - - private void delete(String path, boolean fromSDcard) { - try { - if (path != "") { - File video = new File(path); - if (video.exists()) { - if (null != videoLogList) - if (fromSDcard) - videoLogList.add(new LogMsg("Delete: " + path.split("/")[3], mLog.w)); - else - videoLogList.add(new LogMsg("Delete: " + path.split("/")[5], mLog.w)); - video.delete(); - } else { - if (null != videoLogList) - videoLogList.add(new LogMsg("Video not find.", mLog.e)); - } - } - } catch (Exception e) { - e.printStackTrace(); - isError = true; - getSdCard = !getSDPath().equals(""); - if (null != videoLogList) { - videoLogList.add(new LogMsg("#delete " + path + " error. <============ Crash here", mLog.e)); - saveLog(this); - } - errorMessage = "Delete file error. <============ Crash here"; -// ((TextView) findViewById(R.id.record_status)).setText("Error"); - } - } - - @Override - protected void onHandleIntent(Intent intent) { - try { - - Thread t = new Thread(() -> { - try { - checkSdCardFromFileList(); - } catch (Exception e) { - e.printStackTrace(); - if (null != videoLogList) { - videoLogList.add(new LogMsg("checkSdCardFromFileList error.", mLog.e)); - saveLog(this); - } - } - }); - t.start(); - t.join(); - } catch (Exception e) { - e.printStackTrace(); - if (null != videoLogList) { - videoLogList.add(new LogMsg("checkSdCardService error.", mLog.e)); - saveLog(this); - } - } - } -} - diff --git a/app/src/main/java/com/askey/record/copyFileService.java b/app/src/main/java/com/askey/record/copyFileService.java deleted file mode 100644 index b025858..0000000 --- a/app/src/main/java/com/askey/record/copyFileService.java +++ /dev/null @@ -1,107 +0,0 @@ -package com.askey.record; - -import android.app.IntentService; -import android.content.Intent; -import android.util.Log; - -import com.askey.widget.LogMsg; -import com.askey.widget.mLog; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -import static com.askey.record.Utils.EXTRA_VIDEO_COPY; -import static com.askey.record.Utils.EXTRA_VIDEO_PASTE; -import static com.askey.record.Utils.EXTRA_VIDEO_REMOVE; -import static com.askey.record.Utils.errorMessage; -import static com.askey.record.Utils.getSDPath; -import static com.askey.record.Utils.isError; -import static com.askey.record.Utils.videoLogList; - -public class copyFileService extends IntentService { - String video; - String pathname; - boolean reomve; - - public copyFileService() { - // ActivityのstartService(intent);で呼び出されるコンストラクタはこちら - super("copyFileService"); - } - - public static void copy(String src, String dst, boolean remove) { - try { - File sf = new File(src); - InputStream in = new FileInputStream(sf); - try { - OutputStream out = new FileOutputStream(dst); - try { - // Transfer bytes from in to out - byte[] buf = new byte[1024]; - int len; - while ((len = in.read(buf)) > 0) { - out.write(buf, 0, len); - } - } catch (IOException | RuntimeException e) { - e.printStackTrace(); - isError = true; - errorMessage = "Copy file error. <============ Crash here"; - } finally { - out.close(); - } - } catch (Exception e) { - e.printStackTrace(); - isError = true; - errorMessage = "Copy file error. <============ Crash here"; - } finally { - in.close(); - if (remove) sf.delete(); - } - } catch (Exception e) { - e.printStackTrace(); - isError = true; - errorMessage = "Copy file error. <============ Crash here"; - if (null != videoLogList) - videoLogList.add(new LogMsg("Copy file error", mLog.e)); - } - } - - - protected void onHandleIntent(Intent intent) { - video = intent.getStringExtra(EXTRA_VIDEO_COPY); - pathname = intent.getStringExtra(EXTRA_VIDEO_PASTE); - reomve = intent.getBooleanExtra(EXTRA_VIDEO_REMOVE, false); - // 非同期処理を行うメソッド。タスクはonHandleIntentメソッド内で実行する - try { - if (null != videoLogList) - videoLogList.add(new LogMsg("#copy.", mLog.e)); - Log.d("IntentService", "onHandleIntent Start"); - Thread t = new Thread(() -> { - try { - if (!getSDPath().equals("")) - copy(video, pathname, reomve); - } catch (Exception e) { - e.printStackTrace(); - isError = true; - errorMessage = "Copy file error. <============ Crash here"; - if (null != videoLogList) - videoLogList.add(new LogMsg("Copy file error", mLog.e)); - } - }); - t.start(); - t.join(); - if (null != videoLogList) - videoLogList.add(new LogMsg("copy successful.", mLog.e)); - } catch (Exception e) { - e.printStackTrace(); - isError = true; - errorMessage = "Copy file error. <============ Crash here"; - if (null != videoLogList) - videoLogList.add(new LogMsg("Copy file error", mLog.e)); - } - } -} - diff --git a/app/src/main/java/com/askey/record/saveLogService.java b/app/src/main/java/com/askey/record/saveLogService.java deleted file mode 100644 index fafcc85..0000000 --- a/app/src/main/java/com/askey/record/saveLogService.java +++ /dev/null @@ -1,119 +0,0 @@ -package com.askey.record; - - -import android.app.IntentService; -import android.content.Context; -import android.content.Intent; - -import com.askey.widget.LogMsg; -import com.askey.widget.mLog; - -import java.io.File; -import java.io.FileOutputStream; -import java.time.format.DateTimeFormatter; -import java.util.ArrayList; - -import static com.askey.record.Utils.EXTRA_VIDEO_COPY; -import static com.askey.record.Utils.EXTRA_VIDEO_PASTE; -import static com.askey.record.Utils.EXTRA_VIDEO_REFORMAT; -import static com.askey.record.Utils.EXTRA_VIDEO_REMOVE; -import static com.askey.record.Utils.EXTRA_VIDEO_VERSION; -import static com.askey.record.Utils.getPath; -import static com.askey.record.Utils.getSDPath; -import static com.askey.record.Utils.logName; -import static com.askey.record.Utils.videoLogList; -import static com.askey.record.VideoRecordActivity.SD_Mode; -import static com.askey.record.restartActivity.EXTRA_MAIN_PID; - -public class saveLogService extends IntentService { - private String version; - private boolean reFormat; - - public saveLogService() { - // ActivityのstartService(intent);で呼び出されるコンストラクタはこちら - super("saveLogService"); - } - - private void saveLog(ArrayList mLogList, boolean reFormat, boolean move) { - String logString; - - File file = new File(getPath(), logName); - if (!file.exists()) { - logString = "[VIDEO_RECORD_LOG]" + version + "\r\n"; - try { - file.createNewFile(); - mLogList.add(new LogMsg("Create the log file.", mLog.w)); - } catch (Exception e) { - e.printStackTrace(); - } - } else { - logString = ""; - } - - for (LogMsg logs : mLogList) { - String time = logs.time.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) - + " run:" + logs.runTime + " -> "; - logString += (time + logs.msg + "\r\n"); - } - try { - FileOutputStream output = new FileOutputStream(new File(getPath(), logName), !reFormat); - output.write(logString.getBytes()); - output.close(); - mLogList.clear(); - - } catch (Exception e) { - e.printStackTrace(); - } - if(SD_Mode) { - if (move) - try { - Thread tMove = new Thread(() -> { - moveFile(getPath() + logName, getSDPath() + logName, false); - }); - tMove.start(); - tMove.join(); - } catch (Exception e) { - e.printStackTrace(); - } - } - } - - private void moveFile(String video, String pathname, boolean remove) { - Context context = getApplicationContext(); - Intent intent = new Intent(); - intent.setClassName(context.getPackageName(), copyFileService.class.getName()); - intent.putExtra(EXTRA_VIDEO_COPY, video); - intent.putExtra(EXTRA_VIDEO_PASTE, pathname); - intent.putExtra(EXTRA_VIDEO_REMOVE, remove); - context.startService(intent); - } - - - protected void onHandleIntent(Intent intent) { - int mainPid = 0; - try { - mainPid = intent.getIntExtra(EXTRA_MAIN_PID, -1); - version = intent.getStringExtra(EXTRA_VIDEO_VERSION); - reFormat = intent.getBooleanExtra(EXTRA_VIDEO_REFORMAT, false); - - int finalMainPid = mainPid; - Thread t = new Thread(() -> { - final boolean move = finalMainPid > 0; - try { - saveLog(videoLogList, reFormat, move); - } catch (Exception e) { - e.printStackTrace(); - } - }); - t.start(); - t.join(); - } catch (Exception e) { - e.printStackTrace(); - if (null != videoLogList) - videoLogList.add(new LogMsg("saveLog Service error.", mLog.e)); - } finally { - if (mainPid > 0) android.os.Process.killProcess(mainPid); - } - } -} - diff --git a/app/src/main/java/com/askey/widget/CommandUtil.java b/app/src/main/java/com/askey/widget/CommandUtil.java deleted file mode 100644 index 5e9732d..0000000 --- a/app/src/main/java/com/askey/widget/CommandUtil.java +++ /dev/null @@ -1,162 +0,0 @@ -package com.askey.widget; - -import java.io.BufferedReader; -import java.io.DataOutputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.ArrayList; -import java.util.List; - -public class CommandUtil { - - // public static final String TAG = CommandUtil.class.getSimpleName(); - public static final String COMMAND_SH = "sh"; - public static final String COMMAND_SU = "su"; - public static final String COMMAND_LINE_END = "\n"; - public static final String COMMAND_EXIT = "exit\n"; - private static final boolean ISDEBUG = true; - - /** - * 執行單條命令 - * - * @param command - * @return - */ - public static List execute(String command) { - //CommandUtil.execute("getprop " + FRAMESKIP).get(0); - return execute(new String[]{command}); - } - - /** - * 可執行多行命令(bat) - * - * @param commands - * @return - */ - public static List execute(String[] commands) { - List results = new ArrayList(); - int status = -1; - if (commands == null || commands.length == 0) { - return null; - } -// debug("execute command start : " + commands); - Process process = null; - BufferedReader successReader = null; - BufferedReader errorReader = null; - StringBuilder errorMsg = null; - - DataOutputStream dos = null; - try { - // TODO - process = Runtime.getRuntime().exec(COMMAND_SH); - dos = new DataOutputStream(process.getOutputStream()); - for (String command : commands) { - if (command == null) { - continue; - } - dos.write(command.getBytes()); - dos.writeBytes(COMMAND_LINE_END); - dos.flush(); - } - dos.writeBytes(COMMAND_EXIT); - dos.flush(); - - status = process.waitFor(); - - errorMsg = new StringBuilder(); - successReader = new BufferedReader(new InputStreamReader( - process.getInputStream())); - errorReader = new BufferedReader(new InputStreamReader( - process.getErrorStream())); - String lineStr; - while ((lineStr = successReader.readLine()) != null) { - results.add(lineStr); -// debug(" command line item : " + lineStr); - } - while ((lineStr = errorReader.readLine()) != null) { - errorMsg.append(lineStr); - } - - } catch (IOException e) { - e.printStackTrace(); - } catch (Exception e) { - e.printStackTrace(); - } finally { - try { - if (dos != null) { - dos.close(); - } - if (successReader != null) { - successReader.close(); - } - if (errorReader != null) { - errorReader.close(); - } - } catch (IOException e) { - e.printStackTrace(); - } - - if (process != null) { - process.destroy(); - } - } -// debug(String.format(Locale.CHINA, -// "execute command end,errorMsg:%s,and status %d: ", errorMsg, -// status)); - return results; - } - - public static void executed(String command) { - //CommandUtil.executed("setprop " + FRAMESKIP + " 0"); - executed(new String[]{command}); - } - - public static void executed(String[] commands) { - Process process = null; - DataOutputStream dos = null; - try { - // TODO - process = Runtime.getRuntime().exec(COMMAND_SH); - dos = new DataOutputStream(process.getOutputStream()); - for (String command : commands) { - if (command == null) { - continue; - } - dos.write(command.getBytes()); - dos.writeBytes(COMMAND_LINE_END); - dos.flush(); - } - dos.writeBytes(COMMAND_EXIT); - dos.flush(); - - } catch (IOException e) { - e.printStackTrace(); - } catch (Exception e) { - e.printStackTrace(); - } finally { - try { - if (dos != null) { - dos.close(); - } - } catch (IOException e) { - e.printStackTrace(); - } - - if (process != null) { - process.destroy(); - } - } - } - -// /** -// * DEBUG LOG -// * -// * @param message -// */ -// private static void debug(String message) { -// if (ISDEBUG) { -// Log.d(TAG, message); -// } -// } - -} \ No newline at end of file diff --git a/app/src/main/java/com/askey/widget/CustomPageTransformer.java b/app/src/main/java/com/askey/widget/CustomPageTransformer.java deleted file mode 100644 index 0924686..0000000 --- a/app/src/main/java/com/askey/widget/CustomPageTransformer.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.askey.widget; - -import android.view.View; - -import com.askey.record.R; - -public class CustomPageTransformer implements VerticalViewPager.PageTransformer { - @Override - public void transformPage(View view, float position) { - int pageWidth = view.getWidth(); - int pageHeight = view.getHeight(); - float dafTranslation = 0; - float xPosition = pageWidth * -position; - view.setTranslationX(xPosition); - float yPosition = position * pageHeight - dafTranslation; - view.setTranslationY(yPosition); - CustomTextView item_timezone = view.findViewById(R.id.customTextView); - item_timezone.setTextColor(view.getResources().getColor(R.color.gray_dark)); - item_timezone.setTranslationX(dafTranslation * 1.5f); - if (position < 0) { - view.setAlpha(1f + 0.3f * position); - item_timezone.setScaleX(0.2f * position + 1); - } else if (position < 1) { - view.setAlpha(1f - 0.3f * position); - item_timezone.setScaleX(-0.2f * position + 1); - item_timezone.setTextColor(view.getResources().getColor(R.color.orange)); - } else { - view.setAlpha(1f - 0.3f * position); - item_timezone.setScaleX(-0.2f * position + 1); - } - } -} diff --git a/app/src/main/java/com/askey/widget/LogMsg.java b/app/src/main/java/com/askey/widget/LogMsg.java deleted file mode 100644 index 6450693..0000000 --- a/app/src/main/java/com/askey/widget/LogMsg.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.askey.widget; - -import com.askey.record.Utils; - -import java.time.LocalDateTime; - -public class LogMsg { - public int runTime; - public LocalDateTime time; - public String msg; - public mLog type; - - public LogMsg(String msg) { - this.runTime = Utils.getIsRun(); - this.time = LocalDateTime.now(); - this.msg = msg; - this.type = mLog.d; - } - - public LogMsg(String msg, mLog type) { - this.runTime = Utils.getIsRun(); - this.time = LocalDateTime.now(); - this.msg = msg; - this.type = type; - } -} diff --git a/app/src/main/java/com/askey/widget/PropertyUtils.java b/app/src/main/java/com/askey/widget/PropertyUtils.java deleted file mode 100755 index 812c4c4..0000000 --- a/app/src/main/java/com/askey/widget/PropertyUtils.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.askey.widget; - -import java.lang.reflect.Method; - -public class PropertyUtils { - //Use the reflection invoke SystemProperites. - //https://gist.github.com/crossle/5046538 - public static String get(String key) { - String value = ""; - try { - Class c = Class.forName("android.os.SystemProperties"); - Method get = c.getMethod("get", String.class, String.class); - value = (String) (get.invoke(c, key, "unknown")); - } catch (Exception e) { - e.printStackTrace(); - } finally { - return value; - } - } - - public static void set(String key, String value) { - try { - Class c = Class.forName("android.os.SystemProperties"); - Method set = c.getMethod("set", String.class, String.class); - set.invoke(c, key, value); - } catch (Exception e) { - e.printStackTrace(); - } - } -} diff --git a/app/src/main/java/com/askey/widget/VerticalPageTransformer.java b/app/src/main/java/com/askey/widget/VerticalPageTransformer.java deleted file mode 100755 index 3dfca6e..0000000 --- a/app/src/main/java/com/askey/widget/VerticalPageTransformer.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.askey.widget; - -import android.view.View; - -import com.askey.record.R; - -public class VerticalPageTransformer implements VerticalViewPager.PageTransformer { - @Override - public void transformPage(View view, float position) { - int pageWidth = view.getWidth(); - int pageHeight = view.getHeight(); - CustomTextView customTextView = view.findViewById(R.id.customTextView); - customTextView.setTextColor(view.getResources().getColor(R.color.gray_dark)); - int width = customTextView.getText().toString().length(); - float dafTranslation = 0; - float xPosition = pageWidth * -position + dafTranslation * (width == 2 ? 2f : width == 3 ? 1.6f : 1); - float yPosition = position * pageHeight; - view.setTranslationX(xPosition); - view.setTranslationY(yPosition); - if (position < 0) { - view.setAlpha(1f + 0.5f * position); - view.setScaleX(0.2f * position + 1); - } else if (position < 1) { - view.setAlpha(1f - 0.5f * position); - view.setScaleX(-0.2f * position + 1); - customTextView.setTextColor(view.getResources().getColor(R.color.orange)); - } else { - view.setAlpha(1f - 0.5f * position); - view.setScaleX(-0.2f * position + 1); - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/askey/widget/VerticalPagerContainer.java b/app/src/main/java/com/askey/widget/VerticalPagerContainer.java deleted file mode 100755 index 7a8263d..0000000 --- a/app/src/main/java/com/askey/widget/VerticalPagerContainer.java +++ /dev/null @@ -1,90 +0,0 @@ -package com.askey.widget; - -import android.content.Context; -import android.graphics.Point; -import android.util.AttributeSet; -import android.view.MotionEvent; -import android.view.View; -import android.widget.FrameLayout; - -public class VerticalPagerContainer extends FrameLayout implements VerticalViewPager.OnPageChangeListener { - - boolean mNeedsRedraw = false; - private VerticalViewPager mPager; - private Point mCenter = new Point(); - private Point mInitialTouch = new Point(); - - public VerticalPagerContainer(Context context) { - super(context); - init(); - } - - public VerticalPagerContainer(Context context, AttributeSet attrs) { - super(context, attrs); - init(); - } - - public VerticalPagerContainer(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - init(); - } - - private void init() { - //Disable clipping of children so non-selected pages are visible - setClipChildren(false); - setLayerType(View.LAYER_TYPE_SOFTWARE, null); - } - - @Override - protected void onFinishInflate() { - super.onFinishInflate(); - try { - mPager = (VerticalViewPager) getChildAt(0); - mPager.setOnPageChangeListener(this); - } catch (Exception e) { - throw new IllegalStateException("The root child of PagerContainer must be a ViewPager"); - } - } - - public VerticalViewPager getViewPager() { - return mPager; - } - - @Override - protected void onSizeChanged(int w, int h, int oldw, int oldh) { - mCenter.x = w / 2; - mCenter.y = h / 2; - } - - @Override - public boolean onTouchEvent(MotionEvent ev) { - //We capture any touches not already handled by the ViewPager - // to implement scrolling from a touch outside the pager bounds. - switch (ev.getAction()) { - case MotionEvent.ACTION_DOWN: - mInitialTouch.x = (int) ev.getX(); - mInitialTouch.y = (int) ev.getY(); - default: - ev.offsetLocation(mCenter.x - mInitialTouch.x, mCenter.y - mInitialTouch.y); - break; - } - - return mPager.dispatchTouchEvent(ev); - } - - @Override - public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { - //Force the container to redraw on scrolling. - //Without this the outer pages render initially and then stay static - if (mNeedsRedraw) invalidate(); - } - - @Override - public void onPageSelected(int position) { - } - - @Override - public void onPageScrollStateChanged(int state) { - mNeedsRedraw = (state != VerticalViewPager.SCROLL_STATE_IDLE); - } -} \ No newline at end of file diff --git a/app/src/main/java/com/askey/widget/VerticalViewPager.java b/app/src/main/java/com/askey/widget/VerticalViewPager.java deleted file mode 100755 index 07d3932..0000000 --- a/app/src/main/java/com/askey/widget/VerticalViewPager.java +++ /dev/null @@ -1,61 +0,0 @@ -package com.askey.widget; - -import android.content.Context; -import android.support.v4.view.ViewPager; -import android.util.AttributeSet; -import android.view.MotionEvent; -import android.view.View; - -public class VerticalViewPager extends ViewPager { - public VerticalViewPager(Context context) { - super(context); - init(); - } - - public VerticalViewPager(Context context, AttributeSet attrs) { - super(context, attrs); - init(); - } - - /** - * @return {@code false} since a vertical view pager can never be scrolled horizontally - */ - @Override - public boolean canScrollHorizontally(int direction) { - return false; - } - - /** - * @return {@code true} if a normal view pager would support horizontal scrolling at this time - */ - @Override - public boolean canScrollVertically(int direction) { - return super.canScrollHorizontally(direction); - } - - private void init() { - // Make page transit vertical - setPageTransformer(true, new VerticalPageTransformer()); - // Get rid of the overscroll drawing that happens on the left and right (the ripple) - setOverScrollMode(View.OVER_SCROLL_NEVER); - } - - @Override - public boolean onInterceptTouchEvent(MotionEvent ev) { - return super.onInterceptTouchEvent(flipXY(ev)); - } - - @Override - public boolean onTouchEvent(MotionEvent ev) { - return super.onTouchEvent(flipXY(ev)); - } - - private MotionEvent flipXY(MotionEvent ev) { - final float width = getWidth(); - final float height = getHeight(); - final float x = (ev.getY() / height) * width; - final float y = (ev.getX() / width) * height; - ev.setLocation(x, y); - return ev; - } -} diff --git a/app/src/main/java/com/askey/widget/ViewHolder.java b/app/src/main/java/com/askey/widget/ViewHolder.java deleted file mode 100644 index 214b64d..0000000 --- a/app/src/main/java/com/askey/widget/ViewHolder.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.askey.widget; - -import android.widget.TextView; - -public class ViewHolder { - TextView tv; -} diff --git a/app/src/main/java/com/askey/widget/mLogListAdapter.java b/app/src/main/java/com/askey/widget/mLogListAdapter.java deleted file mode 100644 index ed6631b..0000000 --- a/app/src/main/java/com/askey/widget/mLogListAdapter.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.askey.widget; - -import android.content.Context; -import android.graphics.Color; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.BaseAdapter; - -import com.askey.record.R; - -import java.time.format.DateTimeFormatter; -import java.util.ArrayList; - -public class mLogListAdapter extends BaseAdapter { - - private LayoutInflater inflater; - private ArrayList arrayList; - - public mLogListAdapter(Context context, ArrayList arrayList) { - this.arrayList = arrayList; - inflater = LayoutInflater.from(context); - } - - public int getCount() { - return arrayList.size(); - } - - public Object getItem(int position) { - return position; - } - - public long getItemId(int position) { - return position; - } - - public View getView(int position, View convertView, ViewGroup parent) { - ViewHolder holder; - if (convertView == null) { - convertView = inflater.inflate(R.layout.style_text_item, null); - holder = new ViewHolder(); - holder.tv = convertView.findViewById(R.id.customTextView); - convertView.setTag(holder); - } else { - holder = (ViewHolder) convertView.getTag(); - } - if (arrayList.size() > 0) { - LogMsg log = arrayList.get(position); - String time = log.time.format(DateTimeFormatter.ofPattern("HH:mm:ss")) + " "; - holder.tv.setText(time + log.msg); - mLog type = log.type; - int color = type == mLog.v ? Color.BLACK : type == mLog.d ? Color.BLUE : - type == mLog.i ? Color.GREEN : type == mLog.w ? Color.YELLOW : Color.RED; - holder.tv.setTextColor(color); - } - return convertView; - } -} diff --git a/app/src/main/java/com/askey/widget/mPagerAdapter.java b/app/src/main/java/com/askey/widget/mPagerAdapter.java deleted file mode 100644 index 721cdd1..0000000 --- a/app/src/main/java/com/askey/widget/mPagerAdapter.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.askey.widget; - -import android.support.v4.view.PagerAdapter; -import android.view.View; -import android.view.ViewGroup; - -import java.util.ArrayList; - -public class mPagerAdapter extends PagerAdapter { - - ArrayList viewList; - - public mPagerAdapter(ArrayList viewList) { - this.viewList = viewList; - } - - public int getCount() { - return viewList.size(); - } - - public Object instantiateItem(ViewGroup container, int position) { - container.addView(viewList.get(position)); - return viewList.get(position); - } - - public boolean isViewFromObject(View view, Object object) { - return view == object; - } - - public void destroyItem(ViewGroup container, int position, Object object) { - container.removeView((View) object); - } -} \ No newline at end of file diff --git a/app/src/main/java/com/d160/bit/CameraActivity.java b/app/src/main/java/com/d160/bit/CameraActivity.java new file mode 100644 index 0000000..49e62fb --- /dev/null +++ b/app/src/main/java/com/d160/bit/CameraActivity.java @@ -0,0 +1,1309 @@ +package com.d160.bit; + +import android.*; +import android.annotation.*; +import android.app.*; +import android.bluetooth.*; +import android.content.*; +import android.content.pm.*; +import android.content.res.*; +import android.graphics.*; +import android.hardware.camera2.*; +import android.media.*; +import android.net.wifi.*; +import android.os.*; +import android.util.*; +import android.view.*; +import android.widget.*; + +import androidx.annotation.NonNull; +import androidx.core.app.*; +import androidx.core.content.*; + +import com.d160.view.*; + +import java.io.*; +import java.math.*; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.concurrent.atomic.*; + +import static com.d160.bit.Utils.*; +import static java.lang.System.gc; + +@SuppressLint("SetTextI18n") +public class CameraActivity extends Activity { + public static final String TAG = "com.d160.bit"; + public static final String configName = "BurnInTestConfig.ini"; + public static final String logName = "BurnInTestLog.ini"; + public static final String CONFIG_TITLE = "[BurnIn_Test_Config]"; + public static final String LOG_TITLE = "[BurnIn_Test_Log]"; + public static final int delay_3 = 3000, delay_60 = 60600; + //------------------------------------------------------------------------------- + public static final boolean Open_Audio = false; + public static String firstCamera = "0", secondCamera = "1"; + public static String lastFirstCamera = "0", lastSecondCamera = "1"; + //TODO 是否啟用keepScreen + public static boolean keepScreen = true; + //TODO 是否啟用preview + public static boolean preview = false; + //TODO 是否使用SD_Mode + public static boolean SD_Mode = true; + //TODO 是否啟用重啟功能 + public static boolean autoRestart = true; + //TODO 是否啟用60s停止錄影 + public static boolean autoStopRecord = true; + //TODO 是否啟用BurnIn測試 + public static boolean burnInTest = true; + //------------------------------------------------------------------------------- + public static boolean extraRecordStatus = true, onRestart = false; + public static int onRun = 0, onSuccess = 0, onFail = 0, onReset = 0; + public static int onWifiSuccess = 0, onWifiFail = 0, onBtSuccess = 0, onBtFail = 0; + //------------------------------------------------------------------------------- + private BroadcastReceiver mBroadcastReceiver; + private Handler mainHandler, resetHandler; + private Size mPreviewSize = null; + private HomeListen home; + private mTimerTask timerTask = null; + private Timer mTimer = null; + private float value = 0.0f; + private WifiManager wifiManager; + private BluetoothAdapter mbtAdapter; + + public static void saveLog(Context context, boolean reFormat, boolean kill) { + if (null != videoLogList) { + String version = context.getString(R.string.app_name); + StringBuilder logString; + assert videoLogList != null; + File file = new File(getPath(), logName); + if (!file.exists()) { + logString = new StringBuilder(LOG_TITLE + version + "\r\n"); + try { + boolean create = file.createNewFile(); + if (null != videoLogList) { + if (!create) + videoLogList.add(new mLogMsg("Create file failed.", mLog.w)); + else + videoLogList.add(new mLogMsg("Create the log file.", mLog.w)); + } + } catch (Exception e) { + e.printStackTrace(); + if (null != videoLogList) + videoLogList.add(new mLogMsg("Create file failed.", mLog.w)); + } + } else { + logString = new StringBuilder(); + } + if (null != videoLogList) + try { + for (mLogMsg logs : videoLogList) { + @SuppressLint("SimpleDateFormat") DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + logString.append(dateFormat.format(logs.time)).append(" run:") + .append(logs.runTime).append(" -> ").append(logs.msg).append("\r\n"); + } + } catch (Exception e) { + e.printStackTrace(); + } + try { + FileOutputStream output = new FileOutputStream(file, !reFormat); + output.write(logString.toString().getBytes()); + output.close(); + videoLogList.clear(); + } catch (Exception e) { + e.printStackTrace(); + } + } + if (kill) + android.os.Process.killProcess(android.os.Process.myPid()); + } + + public static int getFrameRate(File file) { + int frameRate = 0; + if (!getSDPath().equals("")) { + try { + MediaExtractor extractor; + FileInputStream fis; + try { + fis = new FileInputStream(file); + extractor = new MediaExtractor(); + extractor.setDataSource(fis.getFD()); + } catch (Exception e) { + e.printStackTrace(); + videoLogList.add(new mLogMsg("getFrameRate failed on MediaExtractor.<============ Crash here", mLog.e)); + return 0; + } + int numTracks = extractor.getTrackCount(); + for (int i = 0; i < numTracks; i++) { + MediaFormat format = extractor.getTrackFormat(i); + if (format.containsKey(MediaFormat.KEY_FRAME_RATE)) { + try { + frameRate = format.getInteger(MediaFormat.KEY_FRAME_RATE); + } catch (Exception e) { + e.printStackTrace(); + videoLogList.add(new mLogMsg("getFrameRate failed on MediaExtractor.<============ Crash here", mLog.e)); + } + } + } + extractor.release(); + fis.close(); + } catch (Exception e) { + e.printStackTrace(); + videoLogList.add(new mLogMsg("getFrameRate failed.<============ Crash here", mLog.e)); + } + } else { + videoLogList.add(new mLogMsg("getFrameRate failed " + NO_SD_CARD + ".", mLog.e)); + } + return frameRate; + } + + public static void checkFile(String path) { + try { + File video = new File(path); + int frameRate = 0; + if (video.exists()) { + try { + frameRate = getFrameRate(video); + } catch (Exception e) { + e.printStackTrace(); + } + if (frameRate != 0) Success++; + else Fail++; + } else { + Fail++; + if (null != videoLogList) + videoLogList.add(new mLogMsg("video not exists.", mLog.e)); + } + String bit = ") wifi_success/fail:(" + getWifiSuccess() + "/" + getWifiFail() + + ") bt_success/fail:(" + getBtSuccess() + "/" + getBtFail(); + if (null != videoLogList) + videoLogList.add(new mLogMsg("CheckFile:(" + path.split("/")[3] + + ") video_frameRate:(" + frameRate + ") video_success/fail:(" + getSuccess() + "/" + getFail() + + (burnInTest ? bit : "") + ") app_reset:(" + getReset() + ")", mLog.i)); + } catch (Exception e) { + e.printStackTrace(); + Fail++; + if (null != videoLogList) + videoLogList.add(new mLogMsg("CheckFile error.", mLog.e)); + } + } + + private boolean checkFile(String file, AtomicReferenceArray list) { + if (file.equals(list.get(0))) + return false; + else return (file.equals(list.get(1))); + } + + private void setRecord() { + isRecord = true; + checkConfigFile(CameraActivity.this, new File(getPath(), configName), false); + if (extraRecordStatus) { + isRun = onRun; + Success = onSuccess; + Fail = onFail; + wifiSuccess = onWifiSuccess; + wifiFail = onWifiFail; + btSuccess = onBtSuccess; + btFail = onBtFail; + } else { + onReset = 0; + isRun = 0; + Success = 0; + Fail = 0; + wifiSuccess = 0; + wifiFail = 0; + btSuccess = 0; + btFail = 0; + } + for (String CameraId : allCamera) { + int id = CameraId.equals(allCamera.get(0)) ? 0 : 1; + cameraFile.set(id, ""); + cameraFilePath.get(id).clear(); + } + extraRecordStatus = true; + } + + private void isRecordStart(boolean auto) { + if (!isError && isSave) { + if (isCameraReady) { + if (!isRecord) { + if (!auto) + videoLogList.add(new mLogMsg("@Start record", mLog.v)); + else + videoLogList.add(new mLogMsg("#Start record", mLog.v)); + if (burnInTest) + videoLogList.add(new mLogMsg("#Wifi_BT Test", mLog.v)); + else + videoLogList.add(new mLogMsg("#No Wifi_BT Test", mLog.v)); + setRecord(); + int delay = 0; + for (String CameraId : allCamera) { + int id = CameraId.equals(allCamera.get(0)) ? 0 : 1; + new Handler(getMainLooper()).postDelayed(() -> recordHandler.get(id).obtainMessage().sendToTarget(), delay); + delay += 500; + } + saveLog(this, false, false); + } else { + if (!auto) + videoLogList.add(new mLogMsg("@Stop record", mLog.v)); + else + videoLogList.add(new mLogMsg("#Stop record", mLog.v)); + new Handler(getMainLooper()).post(() -> stopRecord(!auto)); + } + } else { + Log.e(TAG, "isCameraReady is not ready"); + showDialogLog(false); + videoLogList.add(new mLogMsg("#Camera is not ready.", mLog.v)); + } + } else { + Log.e(TAG, "isSave && !isError"); + stopRecordAndSaveLog(false); + showDialogLog(false); + } + } + + private boolean checkPermission() { + videoLogList.add(new mLogMsg("#checkPermission", mLog.v)); + return permission(permission.get(0)) || permission(permission.get(1)) || permission(permission.get(2)) || permission(permission.get(3)) || permission(permission.get(4)); + } + + @TargetApi(23) + @SuppressLint("NewApi") + private void showPermission() { + videoLogList.add(new mLogMsg("#showPermission", mLog.v)); + // We don't have permission so prompt the user + List permissions = new ArrayList<>(); + for (int i = 0; i < permission.length(); i++) { + permissions.add(permission.get(i)); + } + requestPermissions(permissions.toArray(new String[0]), 0); + } + + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + if (requestCode == 0) { + if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { + initial(); + startBackgroundThread(); + } else { + showPermission(); + videoLogList.add(new mLogMsg("#no permissions!", mLog.e)); + } + } else { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + } + } + + private boolean permission(String mp) { + return ActivityCompat.checkSelfPermission(this, mp) != PackageManager.PERMISSION_GRANTED; + } + + private void setProp() { + try { + //TODO adb shell setprop persist.logd.logpersistd.size 1024 + //TODO adb shell setprop persist.logd.logpersistd logcatd + if (!SystemProperties.get("persist.logd.logpersistd").equals("logcatd")) { + Log.e(TAG, "persist.logd.logpersistd.size: 1024"); + SystemProperties.set("persist.logd.logpersistd.size", "1024"); + Log.e(TAG, "persist.logd.logpersistd: logcatd"); + SystemProperties.set("persist.logd.logpersistd", "logcatd"); + } + } catch (Exception e) { + e.printStackTrace(); + videoLogList.add(new mLogMsg("logcatd error.", mLog.e)); + new Handler(getMainLooper()).post(() -> saveLog(this, false, false)); + } + } + + public void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + Log.e(TAG, isRun + " onConfigurationChanged: E"); + // do nothing + } + + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + isRun = 0; + videoLogList = new ArrayList<>(); + //#onCreateView -> #onViewCreated -> #onActivityCreated -> #onResume + setProp(); + } + + protected void onResume() { + super.onResume(); + if (checkPermission()) { + showPermission(); + } else { + initial(); + startBackgroundThread(); + } + } + + public void onBackPressed() { + videoLogList.add(new mLogMsg("@back", mLog.v)); + stopRecordAndSaveLog(true); + } + + private void setHomeListener() { + try { + home = new HomeListen(this); + home.setOnHomeBtnPressListener(new HomeListen.OnHomeBtnPressLitener() { + public void onHomeBtnPress() { + videoLogList.add(new mLogMsg("@home", mLog.v)); + stopRecordAndSaveLog(true); + } + + public void onHomeBtnLongPress() { + videoLogList.add(new mLogMsg("@recent", mLog.v)); + stopRecordAndSaveLog(true); + } + }); + home.start(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + private CameraDevice.StateCallback setCallback(String CameraId) { + CameraDevice.StateCallback callback; + try { + callback = new CameraDevice.StateCallback() { + final int id = CameraId.equals(allCamera.get(0)) ? 0 : 1; + + public void onOpened(@NonNull CameraDevice cameraDevice) { + Log.e(TAG, "onOpened Camera " + CameraId); + try { + isCameraOpened.set(id, true); + Utils.cameraDevice.set(id, cameraDevice); + takePreview(CameraId); + videoLogList.add(new mLogMsg("Camera " + CameraId + " is opened.", mLog.i)); + } catch (Exception e) { + e.printStackTrace(); + errorMessage("closeCameraDevices " + CameraId + " close error.", true, e); + } + } + + public void onDisconnected(@NonNull CameraDevice cameraDevice) { + Log.e(TAG, "onDisconnected Camera " + CameraId); + try { + isCameraOpened.set(id, false); + Utils.cameraDevice.get(id).close(); + videoLogList.add(new mLogMsg("Camera " + CameraId + " is disconnected.", mLog.w)); + } catch (Exception e) { + e.printStackTrace(); + errorMessage("closeCameraDevices " + CameraId + " close error.", true, e); + } + } + + public void onError(@NonNull CameraDevice cameraDevice, int error) { + Log.e(TAG, "onError Camera " + CameraId); + try { + isCameraOpened.set(id, false); + Utils.cameraDevice.get(id).close(); + videoLogList.add(new mLogMsg("Camera " + CameraId + " is disconnected.", mLog.w)); + } catch (Exception e) { + e.printStackTrace(); + errorMessage("closeCameraDevices " + CameraId + " close error.", true, e); + } + errorMessage("Camera " + CameraId + " is error. <============ Crash here", true, null); + } + }; + return callback; + } catch (Exception e) { + e.printStackTrace(); + errorMessage("closeCameraDevices " + CameraId + " close error.", true, e); + } + return null; + } + + @SuppressLint("SetTextI18n") + private void errorMessage(String msg, boolean reset, Exception e) { + if (e != null) + Log.e(TAG, e.toString()); + isSave = !getSDPath().equals(""); + isError = true; + isRecord = false; + runOnUiThread(() -> ((TextView) findViewById(R.id.record_status)).setText("Error")); + if (null != videoLogList) + videoLogList.add(new mLogMsg(msg, mLog.e)); + errorMessage = msg; + new Handler(getMainLooper()).post(() -> stopRecordAndSaveLog(false)); + if (reset) { + new Handler(getMainLooper()).postDelayed(this::restartApp, delay_3); + } + } + + private void stopRecordAndSaveLog(boolean kill) { + if (isRecord) + new Handler(getMainLooper()).post(() -> stopRecord(true)); + saveLog(this, false, kill); + } + + @SuppressLint("HandlerLeak") + private void setCamera(String CameraId) { + int id = CameraId.equals(allCamera.get(0)) ? 0 : 1; + textView.set(id, this.findViewById(id_textView.get(id))); + cameraFilePath.set(id, new ArrayList<>()); + codeDate.set(id, getCalendarTime()); + stateCallback.set(id, setCallback(CameraId)); + videoLogList.add(new mLogMsg("setCallback " + CameraId + ".", mLog.w)); + recordHandler.set(id, new Handler(getMainLooper()) { + public void handleMessage(Message msg) { + try { + startRecord(CameraId); + videoLogList.add(new mLogMsg("startRecord " + CameraId + ".", mLog.w)); + } catch (Exception e) { + videoLogList.add(new mLogMsg("startRecord " + CameraId + " is error.", mLog.w)); + e.printStackTrace(); + } + } + }); + stopRecordHandler.set(id, new Handler(getMainLooper()) { + public void handleMessage(Message msg) { + if (isRecord) + try { + stopRecord(msg.obj.toString(), CameraId); + videoLogList.add(new mLogMsg("stopRecord " + CameraId + ".", mLog.w)); + } catch (Exception e) { + videoLogList.add(new mLogMsg("stopRecord " + CameraId + " is error.", mLog.w)); + e.printStackTrace(); + } + } + }); + } + + private void restartApp() { + try { + home.stop(); + } catch (Exception e) { + e.printStackTrace(); + } + onRestart = true; + onReset++; + Context context = getApplicationContext(); + Intent intent = RestartActivity.createIntent(context); + intent.putExtra(EXTRA_VIDEO_RUN, onRun); + intent.putExtra(EXTRA_VIDEO_FAIL, onFail); + intent.putExtra(EXTRA_VIDEO_SUCCESS, onSuccess); + intent.putExtra(EXTRA_VIDEO_WIFI_FAIL, onWifiFail); + intent.putExtra(EXTRA_VIDEO_WIFI_SUCCESS, onWifiSuccess); + intent.putExtra(EXTRA_VIDEO_BT_FAIL, onBtFail); + intent.putExtra(EXTRA_VIDEO_BT_SUCCESS, onBtSuccess); + intent.putExtra(EXTRA_VIDEO_RESET, onReset); + intent.putExtra(EXTRA_VIDEO_RECORD, extraRecordStatus); + context.startActivity(intent); + } + + @SuppressLint("HandlerLeak") + private void initial() { + setContentView(R.layout.activity_video_record); + setHomeListener(); + checkConfigFile(this, true); + isSave = !getSDPath().equals(""); + Log.e(TAG, "#initial"); + videoLogList.add(new mLogMsg("#initial", mLog.v)); + checkSdCardFromFileList(); + try { + wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE); + } catch (Exception e) { + errorMessage("wifiManager error.", false, e); + } + try { + mbtAdapter = BluetoothAdapter.getDefaultAdapter(); + } catch (Exception e) { + errorMessage("bluetoothAdapter error.", false, e); + } + findViewById(R.id.cancel).setOnClickListener((View v) -> { + videoLogList.add(new mLogMsg("@cancel", mLog.v)); + stopRecordAndSaveLog(true); + }); + findViewById(R.id.record).setOnClickListener((View v) -> isRecordStart(false)); + findViewById(R.id.setting).setOnClickListener((View v) -> { + if (isSave && !isError) { + videoLogList.add(new mLogMsg("@setting_show", mLog.v)); + View view = LayoutInflater.from(this).inflate(R.layout.layout_setting, null); + final AlertDialog dialog = new AlertDialog.Builder(this).setView(view).setCancelable(false).create(); + view.findViewById(R.id.dialog_button_1).setOnClickListener((View vs) -> { // reset + videoLogList.add(new mLogMsg("@setting_reset", mLog.v)); + setConfigFile(this, new File(getPath(), configName), view, true); + getSetting(this, view.findViewById(R.id.dialog_editText_1), + view.findViewById(R.id.dialog_editText_2), + view.findViewById(R.id.dialog_editText_3)); + setSetting(true); + dialog.dismiss(); + }); + view.findViewById(R.id.dialog_button_2).setOnClickListener((View vs) -> { // cancel + videoLogList.add(new mLogMsg("@setting_cancel", mLog.v)); + dialog.dismiss(); + }); + view.findViewById(R.id.dialog_button_3).setOnClickListener((View vs) -> { // ok + videoLogList.add(new mLogMsg("@setting_ok", mLog.v)); + if (!isRecord) { + setConfigFile(this, new File(getPath(), configName), view, false); + setSetting(false); + } else { + Toast.makeText(this, "you are recording..", Toast.LENGTH_SHORT).show(); + } + dialog.dismiss(); + }); + getSetting(this, view.findViewById(R.id.dialog_editText_1), view.findViewById(R.id.dialog_editText_2), + view.findViewById(R.id.dialog_editText_3)); + dialog.show(); + } else { + Log.e(TAG, "isSave && !isError"); + showDialogLog(false); + } + }); + ((TextView) findViewById(R.id.record_status)).setText(getSDPath().equals("") ? "Error" : "Ready"); + videoLogList.add(new mLogMsg("#initial complete", mLog.v)); + onRun = getIntent().getIntExtra(EXTRA_VIDEO_RUN, 0); + onFail = getIntent().getIntExtra(EXTRA_VIDEO_FAIL, 0); + onSuccess = getIntent().getIntExtra(EXTRA_VIDEO_SUCCESS, 0); + onReset = getIntent().getIntExtra(EXTRA_VIDEO_RESET, 0); + onWifiFail = getIntent().getIntExtra(EXTRA_VIDEO_WIFI_FAIL, 0); + onWifiSuccess = getIntent().getIntExtra(EXTRA_VIDEO_WIFI_SUCCESS, 0); + onBtFail = getIntent().getIntExtra(EXTRA_VIDEO_BT_FAIL, 0); + onBtSuccess = getIntent().getIntExtra(EXTRA_VIDEO_BT_SUCCESS, 0); +// extraRecordStatus = getIntent().getBooleanExtra(EXTRA_VIDEO_RECORD, false); + if (onReset != 0) + videoLogList.add(new mLogMsg("#noReset:" + onReset, mLog.v)); + } + + private void getSetting(Context context, EditText editText1, EditText editText2, EditText editText3) { + String input = readConfigFile(context, new File(getPath(), configName)); + if (input.length() > 0) { + String[] read = input.split("\r\n"); + int t; + String first = "firstCameraID = ", second = "secondCameraID = "; + String code = "numberOfRuns = "; + for (String s : read) + if (s.contains(first)) { + t = s.indexOf(first) + first.length(); + first = s.substring(t); + break; + } + for (String s : read) + if (s.contains(second)) { + t = s.indexOf(second) + second.length(); + second = s.substring(t); + break; + } + for (String s : read) + if (s.contains(code)) { + t = s.indexOf(code) + code.length(); + code = s.substring(t); + break; + } + editText1.setText(first); + editText2.setText(second); + editText3.setText(code); + } else { + videoLogList.add(new mLogMsg("Error reading config file.")); + reformatConfigFile(context, new File(getPath(), configName)); + } + } + + private void setSetting(boolean reset) { + if (!isRecord) { + boolean check = checkConfigFile(this, new File(getPath(), configName), false); + Log.e(TAG, "setSetting check:" + check); + if (check) { + runOnUiThread(() -> { + try { + closeCamera(); + stopBackgroundThread(); + Thread.sleep(1500); + startBackgroundThread(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + }); + } + } else { + saveLog(getApplicationContext(), false, false); + } + if (reset) { + Log.e(TAG, "@ResetApp"); + videoLogList.add(new mLogMsg("@ResetApp", mLog.v)); + restartApp(); + } + } + + private void showDialogLog(boolean end) { + videoLogList.add(new mLogMsg("#Log_show", mLog.v)); + View view = LayoutInflater.from(this).inflate(R.layout.layout_getlog, null); + final AlertDialog dialog = new AlertDialog.Builder(this, R.style.Theme_AppCompat_NoActionBar) + .setView(view).setCancelable(true).create(); + + view.findViewById(R.id.dialog_button_2).setOnClickListener((View vs) -> { // ok + videoLogList.add(new mLogMsg("@Log_ok", mLog.v)); + dialog.dismiss(); + }); + ArrayList list = new ArrayList<>(); + String bit = ") wifi_success/fail:(" + getWifiSuccess() + "/" + getWifiFail() + + ") bt_success/fail:(" + getBtSuccess() + "/" + getBtFail(); + if (isSave) + if (end) + list.add("CheckFile -> video_success/fail:(" + getSuccess() + "/" + getFail() + + (burnInTest ? bit : "") + ") app_reset:(" + getReset() + ")"); + else + list.add("App Version:" + this.getString(R.string.app_name)); + else list.add(NO_SD_CARD); + + if (!errorMessage.equals("")) + list.add(errorMessage); + else { + for (String CameraId : allCamera) { + int id = CameraId.equals(allCamera.get(0)) ? 0 : 1; + if (!isCameraOpened.get(id)) + list.add("Camera Access error, Please check camera " + CameraId + ". <============ Crash here"); + } + } + if (list.size() > 0) { + ArrayList items = new ArrayList<>(); + for (String s : list) { + @SuppressLint("InflateParams") View item_layout = LayoutInflater.from(this).inflate(R.layout.style_text_item, null); + ((CustomTextView) item_layout.findViewById(R.id.customTextView)).setText(s); + items.add(item_layout); + } + ((ListView) view.findViewById(R.id.dialog_listview)).setAdapter(new mListAdapter(items)); + ((ListView) view.findViewById(R.id.dialog_listview)).setSelection(items.size() - 1); + } + dialog.show(); + } + + protected void onDestroy() { + super.onDestroy(); + try { + for (String CameraId : allCamera) { + closeStateCallback(CameraId); + closePreviewSession(CameraId); + closeMediaRecorder(CameraId); + } + } catch (Exception e) { + e.printStackTrace(); + errorMessage("onDestroy error.", false, e); + } + try { + if (null != home) + home.stop(); + } catch (Exception e) { + e.printStackTrace(); + } + new Handler(getMainLooper()).post(() -> stopRecordAndSaveLog(false)); + } + + private void openCamera(String CameraId) { + int id = CameraId.equals(allCamera.get(0)) ? 0 : 1; + if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) + != PackageManager.PERMISSION_GRANTED) { + return; + } + videoLogList.add(new mLogMsg("#Open Camera" + CameraId + ".", mLog.w)); + Log.e(TAG, "camera ID: " + CameraId); + CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE); + try { + mPreviewSize = Objects.requireNonNull(manager.getCameraCharacteristics(CameraId) + .get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP)) + .getOutputSizes(SurfaceTexture.class)[0]; + Log.e(TAG, "camera " + CameraId + " is open"); + manager.openCamera(CameraId, stateCallback.get(id), mainHandler); + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (isLastCamera(CameraId)) + isCameraReady = true; + } + } + + private void closeCamera() { + isCameraReady = false; + Log.e(TAG, "camera is close"); + for (String CameraId : allCamera) { + int id = CameraId.equals(allCamera.get(0)) ? 0 : 1; + try { + if (null != cameraDevice.get(id)) { + runOnUiThread(() -> { + try { + cameraDevice.get(id).close(); + cameraDevice.set(id, null); + Thread.sleep(300); //TODO 防止 Camera error, 不過會慢很多 + } catch (InterruptedException e) { + e.printStackTrace(); + } + }); + } + } catch (Exception e) { + throw new RuntimeException("Interrupted while trying to lock camera closing.", e); + } + } + } + + @SuppressLint("HandlerLeak") + private void startBackgroundThread() { + mainHandler = new Handler(getMainLooper()); + if (keepScreen) + this.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + else + this.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + for (String CameraId : allCamera) { + int id = CameraId.equals(allCamera.get(0)) ? 0 : 1; + thread.set(id, new HandlerThread(threadString.get(id))); + thread.get(id).start(); + backgroundHandler.set(id, new Handler(thread.get(id).getLooper())); + try { + setCamera(CameraId); + } catch (Exception e) { + e.printStackTrace(); + videoLogList.add(new mLogMsg("setCallback " + CameraId + " is error.", mLog.w)); + } + if (textView.get(id).isAvailable()) + openCamera(CameraId); + else + textView.get(id).setSurfaceTextureListener(new mSurfaceTextureListener(CameraId)); + } + registerReceiver(mBroadcastReceiver = new BroadcastReceiver() { + public void onReceive(Context context, Intent intent) { + if (Objects.equals(intent.getAction(), Intent.ACTION_BATTERY_CHANGED)) { //Battery + Log.e(TAG, "Battery:" + intent.getIntExtra("level", 0) + "%"); + videoLogList.add(new mLogMsg("Battery:" + intent.getIntExtra("level", 0) + "%", mLog.e)); + saveLog(CameraActivity.this, false, false); + } + } + }, new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); + resetHandler = new Handler(getMainLooper()) { + public void handleMessage(Message msg) { + if (extraRecordStatus) + isRecordStart(true); + saveLog(CameraActivity.this, false, false); + } + }; + new Handler(getMainLooper()).postDelayed(() -> resetHandler.obtainMessage().sendToTarget(), delay_3); + } + + private void stopBackgroundThread() { + this.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + for (String CameraId : allCamera) { + int id = CameraId.equals(allCamera.get(0)) ? 0 : 1; + thread.get(id).quitSafely(); + try { + thread.get(id).join(); + thread.set(id, null); + } catch (InterruptedException e) { + e.printStackTrace(); + } + backgroundHandler.get(id).removeCallbacks(thread.get(id)); + backgroundHandler.set(id, null); + } + this.unregisterReceiver(mBroadcastReceiver); + } + + @SuppressLint("SetTextI18n") + private void stopRecord(String date, String CameraId) { + int id = CameraId.equals(allCamera.get(0)) ? 0 : 1; + try { + if (date.equals(codeDate.get(id))) { + isRun++; + videoLogList.add(new mLogMsg("#stopRecord " + CameraId, mLog.v)); + Log.e(TAG, "Run " + isRun + " stopRecord " + CameraId); + if (isCameraOne(CameraId)) + runOnUiThread(() -> { + if (mTimer != null) { + mTimer.cancel(); + mTimer = null; + } + ((TextView) findViewById(R.id.record_status)).setText("Stop"); + }); + codeDate.set(id, getCalendarTime()); + try { + closeMediaRecorder(CameraId); + checkAndClear(CameraId); + } catch (Exception e) { + e.printStackTrace(); + videoLogList.add(new mLogMsg("Check file is fail.")); + } + if (isFinish == 999 || isRun < isFinish - (isCameraOne(CameraId) ? 1 : 0)) { + startRecord(CameraId); + } else { + if (isLastCamera(CameraId)) + isRecordStart(true); + } + if (isError || !isSave) { + isRun = 0; + isFinish = 0; + isRecord = false; + ((TextView) findViewById(R.id.record_status)).setText("Error"); + } + } + } catch (Exception e) { + e.printStackTrace(); + errorMessage("Camera " + CameraId + " stopRecord error. <============ Crash here", true, e); + } + } + + @SuppressLint("SetTextI18n") + private void stopRecord(boolean reset) { + try { + if (!isError && isSave) { // noError, isSave + if (!reset) { + runOnUiThread(() -> { + if (getFail() + getReset() == 0) { + videoLogList.add(new mLogMsg("#Pass")); + ((TextView) findViewById(R.id.record_status)).setText("Pass"); + } else { + videoLogList.add(new mLogMsg("#Fail")); + ((TextView) findViewById(R.id.record_status)).setText("Fail " + getFail() + getReset()); + } + }); + new Handler(getMainLooper()).postDelayed(() -> showDialogLog(true), delay_3 / 3); + } + for (String CameraId : allCamera) { // 遍例Camera + int id = CameraId.equals(allCamera.get(0)) ? 0 : 1; + videoLogList.add(new mLogMsg("#stopRecord " + CameraId, mLog.v)); + Log.e(TAG, "Run " + isRun + " stopRecord " + CameraId); + if (isCameraOne(CameraId)) + runOnUiThread(() -> { + if (mTimer != null) { + mTimer.cancel(); + mTimer = null; + } + ((TextView) findViewById(R.id.record_status)).setText("Stop"); + }); + codeDate.set(id, getCalendarTime()); + try { + closeMediaRecorder(CameraId); + checkAndClear(CameraId); + } catch (Exception e) { + e.printStackTrace(); + errorMessage("Check file is fail. <============ Crash here", true, e); + } + } + } + isRun = 0; + isFinish = 0; + isRecord = false; + videoLogList.add(new mLogMsg("#Complete")); + videoLogList.add(new mLogMsg("#------------------------------", mLog.v)); + saveLog(this, false, false); + if (!reset) { + extraRecordStatus = false; + } + if (preview) { + takePreview(); + } + } catch (Exception e) { + e.printStackTrace(); + errorMessage("stopRecord all camera error. <============ Crash here", true, e); + } + } + + private void closeStateCallback(String CameraId) { + int id = CameraId.equals(allCamera.get(0)) ? 0 : 1; + try { + if (null != stateCallback.get(id)) { + stateCallback.get(id).onDisconnected(cameraDevice.get(id)); + stateCallback.set(id, null); + } + } catch (Exception e) { + e.printStackTrace(); + errorMessage("closeStateCallback" + CameraId + " is error.", true, e); + } + } + + private void closePreviewSession(String CameraId) { + int id = CameraId.equals(allCamera.get(0)) ? 0 : 1; + try { + if (null != previewSession.get(id)) { + previewSession.get(id).close(); + previewSession.set(id, null); + } + } catch (Exception e) { + e.printStackTrace(); + errorMessage("closePreviewSession" + CameraId + " is error.", false, e); + } + } + + private void closeMediaRecorder(String CameraId) { + int id = CameraId.equals(allCamera.get(0)) ? 0 : 1; + if (null != mediaRecorder.get(id)) { + try { + try { + mediaRecorder.get(id).stop(); + mediaRecorder.get(id).release(); + } catch (RuntimeException stopException) { + // handle cleanup here + videoLogList.add(new mLogMsg("stop MediaRecorder " + CameraId + " is error.")); + } + mediaRecorder.set(id, null); + videoLogList.add(new mLogMsg("Record " + CameraId + " finish.")); + } catch (Exception e) { + e.printStackTrace(); + videoLogList.add(new mLogMsg("closeMediaRecorder " + CameraId + " is error.")); + } + } + } + + @SuppressLint("SetTextI18n") + private void startRecord(String CameraId) { + int id = CameraId.equals(allCamera.get(0)) ? 0 : 1; + if (!isError) { + Log.e(TAG, isRun + " startRecord " + CameraId); + try { + if (isCameraOne(CameraId)) { + checkSdCardFromFileList(); + runOnUiThread(() -> { + if (mTimer == null) { + onRun = getIsRun(); + onFail = getFail(); + onSuccess = getSuccess(); + timerTask = new mTimerTask(); + value = 0.0f; + mTimer = new Timer(true); + ((TextView) findViewById(R.id.record_timer)).setText("00"); + ((TextView) findViewById(R.id.record_status)).setText("Recording"); + } + }); + CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE); + mPreviewSize = Objects.requireNonNull(manager.getCameraCharacteristics(CameraId) + .get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP)) + .getOutputSizes(SurfaceTexture.class)[0]; + if (burnInTest) { + onWifiFail = getWifiFail(); + onWifiSuccess = getWifiSuccess(); + onBtFail = getBtFail(); + onBtSuccess = getBtSuccess(); + wifiEnableOrDisable(); + } + } else { + if (burnInTest) + btEnableOrDisable(); + } + try { + closePreviewSession(CameraId); + } catch (Exception e) { + errorMessage("closePreviewSession error.", true, e); + } + SurfaceTexture texture = null; + try { + texture = textView.get(id).getSurfaceTexture(); + } catch (Exception e) { + e.printStackTrace(); + videoLogList.add(new mLogMsg("getSurfaceTexture" + CameraId + " is error.")); + } + if (null == texture) { + Log.e(TAG, "Run " + isRun + " texture is null, return"); + return; + } + texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight()); + Surface surface = new Surface(texture); + List surfaces = new ArrayList<>(); + CaptureRequest.Builder mPreviewBuilder; + CameraDevice mCameraDevice; + Surface recorderSurface; + mCameraDevice = cameraDevice.get(id); + mediaRecorder.set(id, setUpMediaRecorder(CameraId)); + recorderSurface = mediaRecorder.get(id).getSurface(); + surfaces.add(surface); + surfaces.add(recorderSurface); + if (mCameraDevice != null) { + mPreviewBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_RECORD); + mPreviewBuilder.addTarget(surface); + mPreviewBuilder.addTarget(recorderSurface); + try { + mCameraDevice.createCaptureSession(surfaces, + new CameraCaptureSession.StateCallback() { + public void onConfigured(@NonNull CameraCaptureSession session) { + try { + if (isCameraOne(CameraId)) + mTimer.schedule(timerTask, 100, 100); + previewSession.set(id, session); + updatePreview(mPreviewBuilder, session, backgroundHandler.get(id)); + if (null != mediaRecorder.get(id)) { + mediaRecorder.get(id).start(); + codeDate.set(id, getCalendarTime()); + Message msg = stopRecordHandler.get(id).obtainMessage(); + msg.obj = codeDate.get(id); + int delay = 0; + if (!isCameraOne(CameraId)) { + for (String c : allCamera) { + delay += id * 600; + if (c.equals(CameraId)) + break; + } + } + if (autoStopRecord) + stopRecordHandler.get(id).sendMessageDelayed(msg, delay_60 + delay); + } + } catch (Exception e) { + e.printStackTrace(); + errorMessage("Camera " + CameraId + " can't record. <============ Crash here", false, e); + } + } + + public void onConfigureFailed(@NonNull CameraCaptureSession Session) { + errorMessage("Camera " + CameraId + " Record onConfigureFailed.", true, null); + } + }, backgroundHandler.get(id)); + } catch (Exception e) { + e.printStackTrace(); + errorMessage("Camera " + CameraId + " CameraCaptureSession.StateCallback() error. <============ Crash here", true, e); + } + } + } catch (Exception e) { + e.printStackTrace(); + errorMessage("Camera " + CameraId + " startRecord error. <============ Crash here", true, e); + } + } else { + if (autoRestart) { + new Handler(getMainLooper()).postDelayed(this::restartApp, delay_3); + } + } + } + + private void checkSdCardFromFileList() { + isSave = !getSDPath().equals(""); + if (isSave) { + try { + StatFs stat = new StatFs(getSDPath()); + long sdAvailSize = stat.getAvailableBlocksLong() * stat.getBlockSizeLong(); + double gigaAvailable = (sdAvailSize >> 30); + if (gigaAvailable < sdData) { + videoLogList.add(new mLogMsg("SD Card is Full.")); + ArrayList tmp = new ArrayList<>(); + File[] fileList = new File(getSDPath()).listFiles(); + assert fileList != null; + for (File file : fileList) { + if (!file.isDirectory() && Utils.getFileExtension(file.toString()).equals("mp4")) + if (checkFile(file.toString(), cameraFile)) + tmp.add(file.toString()); + } + if (tmp.size() >= 6) { + Object[] list = tmp.toArray(); + Arrays.sort(list); + for (int i = 0; i < 6; i++) + delete((String) list[i], SD_Mode); + checkSdCardFromFileList(); + } else { + isError = true; + videoLogList.add(new mLogMsg("MP4 video file not found. <============ Crash here")); + errorMessage("error: At least " + sdData + "gb memory needs to be available to record, please check the SD Card free space.", false, null); + } + } + } catch (Exception e) { + e.printStackTrace(); + if (!getSDPath().equals("")) { + errorMessage("error: At least " + sdData + "gb memory needs to be available to record, please check the SD Card free space.", false, null); + } else { + errorMessage(NO_SD_CARD, false, null); + } + } + } else { + errorMessage(NO_SD_CARD, false, null); + } + } + + private void delete(String path, boolean SdMode) { + File video = new File(path); + try { + if (!path.equals("")) { + if (video.exists()) { + if (SdMode) + videoLogList.add(new mLogMsg("Delete: " + path.split("/")[3], mLog.w)); + else + videoLogList.add(new mLogMsg("Delete: " + path.split("/")[5], mLog.w)); + boolean del = video.delete(); + if (!del) + videoLogList.add(new mLogMsg("Video delete failed.", mLog.e)); + } else { + videoLogList.add(new mLogMsg("Video not find.", mLog.e)); + } + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + private void checkAndClear(String CameraId) { + int id = CameraId.equals(allCamera.get(0)) ? 0 : 1; + try { + if (isRecord) + if (null != cameraFilePath.get(id)) { + for (String f : cameraFilePath.get(id)) { + checkFile(f); + } + cameraFilePath.get(id).clear(); + } + gc(); + } catch (Exception e) { + videoLogList.add(new mLogMsg("CheckFile " + CameraId + " error.", mLog.e)); + } + } + + private MediaRecorder setUpMediaRecorder(String CameraId) { + /* this function will error with camera changed. */ + CamcorderProfile profile = CamcorderProfile.get(CamcorderProfile.QUALITY_1080P); + int id = CameraId.equals(allCamera.get(0)) ? 0 : 1; + int kbps = 1000; + String file; + MediaRecorder mediaRecorder = null; + try { + if (!getSDPath().equals("")) { + String name = getCalendarTime(CameraId) + ".mp4"; + file = getSDPath() + name; + videoLogList.add(new mLogMsg("Create: " + name, mLog.w)); + cameraFile.set(id, file + ""); + cameraFilePath.get(id).add(file); + mediaRecorder = new MediaRecorder(); + if (Open_Audio) videoLogList.add(new mLogMsg("#audio")); + if (Open_Audio) mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); + mediaRecorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT); + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + if (Open_Audio) mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264); + mediaRecorder.setVideoSize(profile.videoFrameWidth, profile.videoFrameHeight); + if (Open_Audio) mediaRecorder.setAudioEncodingBitRate(96 * kbps); + mediaRecorder.setVideoEncodingBitRate(2000 * kbps); + if (Open_Audio) { + mediaRecorder.setAudioChannels(2); + mediaRecorder.setAudioSamplingRate(44100); + } + mediaRecorder.setVideoFrameRate(50); + mediaRecorder.setOutputFile(file); +// mediaRecorder.setPreviewDisplay(surfaceView.get(id).getHolder().getSurface()); + mediaRecorder.prepare(); + } else { + errorMessage("MediaRecorder error. " + NO_SD_CARD + " <============ Crash here", false, null); + return null; + } + } catch (Exception e) { + errorMessage("MediaRecorder " + CameraId + " error. <============ Crash here", false, e); + } + return mediaRecorder; + } + + private void takePreview() { + if (isSave && !isError) { + for (String CameraId : allCamera) { + takePreview(CameraId); + } + } else { + Log.e(TAG, "isSave && !isError"); + stopRecordAndSaveLog(false); + showDialogLog(false); + } + } + + private void takePreview(String CameraId) { + int id = CameraId.equals(allCamera.get(0)) ? 0 : 1; + Log.e(TAG, "takePreview " + CameraId); + videoLogList.add(new mLogMsg("Preview " + CameraId + " Camera.", mLog.i)); + try { + SurfaceTexture texture = null; + try { + texture = textView.get(id).getSurfaceTexture(); + } catch (Exception e) { + e.printStackTrace(); + errorMessage("takePreview " + CameraId + " error. <============ Crash here", true, e); + } + assert texture != null; + texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight()); + Surface surface = new Surface(texture); + CaptureRequest.Builder mPreviewBuilder; + mPreviewBuilder = cameraDevice.get(id).createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW); + mPreviewBuilder.addTarget(surface); + cameraDevice.get(id).createCaptureSession(Collections.singletonList(surface), + new CameraCaptureSession.StateCallback() { + public void onConfigured(@NonNull CameraCaptureSession session) { + try { + previewSession.set(id, session); + updatePreview(mPreviewBuilder, previewSession.get(id), backgroundHandler.get(id)); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void onConfigureFailed( + @NonNull CameraCaptureSession cameraCaptureSession) { + runOnUiThread(() -> + errorMessage("Preview " + CameraId + " onConfigureFailed", true, null)); + } + }, backgroundHandler.get(id)); + } catch (CameraAccessException e) { + e.printStackTrace(); + } + } + + protected void updatePreview(CaptureRequest.Builder mPreviewBuilder, CameraCaptureSession mPreviewSession, Handler backgroundHandler) { + try { + mPreviewBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO); + mPreviewSession.setRepeatingRequest(mPreviewBuilder.build(), null, backgroundHandler); + } catch (Exception e) { + e.printStackTrace(); + errorMessage("setCaptureRequest error.", true, e); + } + } + + private void wifiEnableOrDisable() { + try { + wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE); + wifiManager.setWifiEnabled(WifiManager.WIFI_STATE_ENABLED != wifiManager.getWifiState()); + wifiSuccess++; + } catch (Exception e) { + wifiFail++; + errorMessage("Error wifiEnableOrDisable fail.", false, e); + } + } + + private void btEnableOrDisable() { + try { + mbtAdapter = BluetoothAdapter.getDefaultAdapter(); + if (!mbtAdapter.isEnabled()) { + mbtAdapter.enable(); + } else { + mbtAdapter.disable(); + } + btSuccess++; + } catch (Exception e) { + btFail++; + errorMessage("Error btEnableOrDisable fail.", false, e); + } + } + + private class mTimerTask extends TimerTask { + @SuppressLint("SetTextI18n") + public void run() { + runOnUiThread(() -> { + value += 0.1d; + BigDecimal bi = new BigDecimal(value); + float outputValue = bi.setScale(1, BigDecimal.ROUND_HALF_UP).floatValue(); + if (autoStopRecord && outputValue >= 65) { + errorMessage("Application has timed out.", true, null); + } + ((TextView) findViewById(R.id.record_timer)).setText(Float.toString(outputValue)); + }); + } + } + + private class mSurfaceTextureListener implements TextureView.SurfaceTextureListener { + String cameraId; + + public mSurfaceTextureListener(String cameraId) { + this.cameraId = cameraId; + } + + public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) { + openCamera(cameraId); + } + + public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) { + + } + + public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) { + return false; + } + + public void onSurfaceTextureUpdated(SurfaceTexture surface) { + + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/d160/bit/Config.java b/app/src/main/java/com/d160/bit/Config.java new file mode 100644 index 0000000..dd579f6 --- /dev/null +++ b/app/src/main/java/com/d160/bit/Config.java @@ -0,0 +1,36 @@ +package com.d160.bit; + +import android.content.Context; + +import static com.d160.bit.CameraActivity.*; +import static com.d160.bit.Utils.*; + +public class Config { + + protected Context context; + protected String firstCamera = "0"; + protected String secondCamera = "1"; + protected int numberOfRuns = defaultRun; + + public Config(Context context) { + this.context = context; + } + + public Config(Context context, String firstCamera, String secondCamera, int isRuns) { + this.context = context; + this.firstCamera = firstCamera; + this.secondCamera = secondCamera; + this.numberOfRuns = isRuns; + } + + protected String[] config() { + return new String[]{ + CONFIG_TITLE+ context.getString(R.string.app_name) + "\r\n", + "#CameraID (0:Outer, 1:Inner, 2:External)\r\n", + "firstCameraID = " + firstCamera + "\r\n", + "secondCameraID = " + secondCamera + "\r\n", "\r\n", + "#Total number of runs (1 record is 1 min)\r\n", + "numberOfRuns = " + numberOfRuns + "\r\n" + }; + } +} diff --git a/app/src/main/java/com/askey/record/restartActivity.java b/app/src/main/java/com/d160/bit/RestartActivity.java similarity index 64% rename from app/src/main/java/com/askey/record/restartActivity.java rename to app/src/main/java/com/d160/bit/RestartActivity.java index 5b8c41d..0d3e5bd 100644 --- a/app/src/main/java/com/askey/record/restartActivity.java +++ b/app/src/main/java/com/d160/bit/RestartActivity.java @@ -1,23 +1,26 @@ -package com.askey.record; +package com.d160.bit; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.os.Bundle; -public class restartActivity extends Activity { +public class RestartActivity extends Activity { public static final String EXTRA_MAIN_PID = "RestartActivity.main_pid"; public static final String EXTRA_VIDEO_RUN = "RestartActivity.run"; public static final String EXTRA_VIDEO_FAIL = "RestartActivity.fail"; public static final String EXTRA_VIDEO_RESET = "RestartActivity.reset"; public static final String EXTRA_VIDEO_RECORD = "RestartActivity.record"; public static final String EXTRA_VIDEO_SUCCESS = "RestartActivity.success"; + public static final String EXTRA_VIDEO_WIFI_FAIL = "RestartActivity.wifi.fail"; + public static final String EXTRA_VIDEO_BT_FAIL = "RestartActivity.bt.fail"; + public static final String EXTRA_VIDEO_WIFI_SUCCESS = "RestartActivity.wifi.success"; + public static final String EXTRA_VIDEO_BT_SUCCESS = "RestartActivity.bt.success"; public static Intent createIntent(Context context) { Intent intent = new Intent(); - intent.setClassName(context.getPackageName(), restartActivity.class.getName()); + intent.setClassName(context.getPackageName(), RestartActivity.class.getName()); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - // メインプロセスの PID を Intent に保存しておく intent.putExtra(EXTRA_MAIN_PID, android.os.Process.myPid()); return intent; } @@ -25,27 +28,33 @@ public static Intent createIntent(Context context) { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - // 1. メインプロセスを Kill する Intent intent = getIntent(); int mainPid = intent.getIntExtra(EXTRA_MAIN_PID, -1); int EXTRA_RUN = intent.getIntExtra(EXTRA_VIDEO_RUN, 0); int EXTRA_RESET = intent.getIntExtra(EXTRA_VIDEO_RESET, 0); int EXTRA_FAIL = getIntent().getIntExtra(EXTRA_VIDEO_FAIL, 0); int EXTRA_SUCCESS = getIntent().getIntExtra(EXTRA_VIDEO_SUCCESS, 0); + int EXTRA_WIFI_FAIL = getIntent().getIntExtra(EXTRA_VIDEO_WIFI_FAIL, 0); + int EXTRA_WIFI_SUCCESS = getIntent().getIntExtra(EXTRA_VIDEO_WIFI_SUCCESS, 0); + int EXTRA_BT_FAIL = getIntent().getIntExtra(EXTRA_VIDEO_BT_FAIL, 0); + int EXTRA_BT_SUCCESS = getIntent().getIntExtra(EXTRA_VIDEO_BT_SUCCESS, 0); boolean EXTRA_RECORD = intent.getBooleanExtra(EXTRA_VIDEO_RECORD, false); android.os.Process.killProcess(mainPid); // 2. MainActivity を再起動する Context context = getApplicationContext(); Intent restartIntent = new Intent(Intent.ACTION_MAIN); - restartIntent.setClassName(context.getPackageName(), VideoRecordActivity.class.getName()); + restartIntent.setClassName(context.getPackageName(), CameraActivity.class.getName()); restartIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); restartIntent.putExtra(EXTRA_VIDEO_RUN, EXTRA_RUN); restartIntent.putExtra(EXTRA_VIDEO_RESET, EXTRA_RESET); restartIntent.putExtra(EXTRA_VIDEO_FAIL, EXTRA_FAIL); restartIntent.putExtra(EXTRA_VIDEO_SUCCESS, EXTRA_SUCCESS); + restartIntent.putExtra(EXTRA_VIDEO_WIFI_FAIL, EXTRA_WIFI_FAIL); + restartIntent.putExtra(EXTRA_VIDEO_WIFI_SUCCESS, EXTRA_WIFI_SUCCESS); + restartIntent.putExtra(EXTRA_VIDEO_BT_FAIL, EXTRA_BT_FAIL); + restartIntent.putExtra(EXTRA_VIDEO_BT_SUCCESS, EXTRA_BT_SUCCESS); restartIntent.putExtra(EXTRA_VIDEO_RECORD, EXTRA_RECORD); context.startActivity(restartIntent); - // 3. RestartActivity を終了する finish(); android.os.Process.killProcess(android.os.Process.myPid()); } diff --git a/app/src/main/java/com/d160/bit/Utils.java b/app/src/main/java/com/d160/bit/Utils.java new file mode 100644 index 0000000..c7aed58 --- /dev/null +++ b/app/src/main/java/com/d160/bit/Utils.java @@ -0,0 +1,457 @@ +package com.d160.bit; + +import android.*; +import android.annotation.*; +import android.content.*; +import android.hardware.camera2.*; +import android.media.*; +import android.os.*; +import android.util.*; +import android.view.*; +import android.widget.*; + +import com.d160.view.*; + +import java.io.*; +import java.lang.Process; +import java.text.*; +import java.util.*; +import java.util.concurrent.atomic.*; + +import static android.os.Environment.*; +import static com.d160.bit.CameraActivity.*; + +public class Utils { + //------------------------------------------------------------------------------- + public static final String EXTRA_VIDEO_RUN = "RestartActivity.run"; + public static final String EXTRA_VIDEO_FAIL = "RestartActivity.fail"; + public static final String EXTRA_VIDEO_WIFI_FAIL = "RestartActivity.wifi.fail"; + public static final String EXTRA_VIDEO_BT_FAIL = "RestartActivity.bt.fail"; + public static final String EXTRA_VIDEO_RESET = "RestartActivity.reset"; + public static final String EXTRA_VIDEO_RECORD = "RestartActivity.record"; + public static final String EXTRA_VIDEO_SUCCESS = "RestartActivity.success"; + public static final String EXTRA_VIDEO_WIFI_SUCCESS = "RestartActivity.wifi.success"; + public static final String EXTRA_VIDEO_BT_SUCCESS = "RestartActivity.bt.success"; + //------------------------------------------------------------------------------- + public static final String NO_SD_CARD = "SD card is not available!"; + public static final int defaultRun = 480; + public static final double sdData = 3; + public static int isFinish = defaultRun, isRun = 0, Success = 0, Fail = 0; + public static int wifiSuccess = 0, wifiFail = 0; + public static int btSuccess = 0, btFail = 0; + public static ArrayList videoLogList = null; + public static boolean isCameraReady = false, isRecord = false, + isError = false, isSave = false; + public static String errorMessage = ""; + //------------------------------------------------------------------------------- + public static List allCamera = Arrays.asList(firstCamera, secondCamera); + public static AtomicIntegerArray id_textView = new AtomicIntegerArray(new int[]{R.id.textureView0, R.id.textureView1}); + public static AtomicReferenceArray threadString = new AtomicReferenceArray<>(new String[]{"CameraPreview0", "CameraPreview1"}); + public static AtomicReferenceArray permission = new AtomicReferenceArray<>(new String[]{ + Manifest.permission.CAMERA, Manifest.permission.INTERNET, Manifest.permission.BLUETOOTH, Manifest.permission.RECORD_AUDIO, Manifest.permission.WRITE_EXTERNAL_STORAGE}); + public static AtomicReferenceArray cameraFile = new AtomicReferenceArray<>(new String[]{"", ""}); + public static AtomicReferenceArray isCameraOpened = new AtomicReferenceArray<>(new Boolean[]{false, false}); + public static AtomicReferenceArray> cameraFilePath = new AtomicReferenceArray>(new ArrayList[2]); + public static AtomicReferenceArray codeDate = new AtomicReferenceArray<>(new String[2]); + public static AtomicReferenceArray textView = new AtomicReferenceArray<>(new TextureView[2]); + public static AtomicReferenceArray cameraDevice = new AtomicReferenceArray<>(new CameraDevice[2]); + public static AtomicReferenceArray previewSession = new AtomicReferenceArray<>(new CameraCaptureSession[2]); + public static AtomicReferenceArray stateCallback = new AtomicReferenceArray<>(new CameraDevice.StateCallback[2]); + public static AtomicReferenceArray mediaRecorder = new AtomicReferenceArray<>(new MediaRecorder[2]); + public static AtomicReferenceArray thread = new AtomicReferenceArray<>(new HandlerThread[2]); + public static AtomicReferenceArray backgroundHandler = new AtomicReferenceArray<>(new Handler[2]); + public static AtomicReferenceArray recordHandler = new AtomicReferenceArray<>(new Handler[2]); + public static AtomicReferenceArray stopRecordHandler = new AtomicReferenceArray<>(new Handler[2]); + + //------------------------------------------------------------------------------- + //TODO Default Path + public static String getPath() { + return getStorageDirectory().getPath() + "/emulated/0/DCIM/"; + } + + public static String getSDPath() { + String path = ""; + if (SD_Mode) { + try { + long start = (System.currentTimeMillis() / 1000) % 60; + long end = start + 10; + Runtime run = Runtime.getRuntime(); + String cmd = "ls /storage"; + Process pr = run.exec(cmd); + InputStreamReader input = new InputStreamReader(pr.getInputStream()); + BufferedReader buf = new BufferedReader(input); + String line; + while ((line = buf.readLine()) != null) { + if (!line.equals("self") && !line.equals("emulated") && !line.equals("enterprise") && !line.contains("sdcard")) { + path = "/storage/" + line + "/"; + break; + } + if ((System.currentTimeMillis() / 1000) % 60 > end) { + videoLogList.add(new mLogMsg("getSDPath time out.", mLog.e)); + break; + } + } + buf.close(); + input.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } else { + path = getPath(); + } + return path; + } + + public static int getIsRun() { + return isRun; + } + + public static int getSuccess() { + return Success; + } + + public static int getFail() { + return Fail; + } + + public static int getWifiSuccess() { + return wifiSuccess; + } + + public static int getWifiFail() { + return wifiFail; + } + + public static int getBtSuccess() { + return btSuccess; + } + + public static int getBtFail() { + return btFail; + } + + public static int getReset() { + return onReset; + } + + public static boolean isInteger(String s, boolean zero) { + try { + if (Integer.parseInt(s) <= (zero ? 0 : -1)) { + return false; + } + } catch (Exception e) { + e.printStackTrace(); + return false; + } + return true; + } + + public static void setTestTime(int min) { + if (min == 999) { + Log.e(TAG, "setRecord time: 999."); + videoLogList.add(new mLogMsg("setRecord time: unlimited times.", mLog.d)); + } else { + Log.e(TAG, "setRecord time: " + min + " min."); + videoLogList.add(new mLogMsg("setRecord time: " + min + " min.", mLog.d)); + } + isFinish = min == 999 ? min : min * 2; + } + + public static void checkConfigFile(Context context, boolean first) { + videoLogList.add(new mLogMsg("#checkConfigFile", mLog.v)); + if (!getPath().equals("")) { + isSave = true; + File file = new File(getPath(), configName); + if (!file.exists()) { + try { + if (file.createNewFile()) + videoLogList.add(new mLogMsg("Create the config.", mLog.w)); + else + videoLogList.add(new mLogMsg("Failed to create the config.", mLog.w)); + } catch (Exception e) { + e.printStackTrace(); + } + writeConfigFile(context, file, new Config(context).config()); + } else { + if (!isCameraReady) { + videoLogList.add(new mLogMsg("Find the config file.", mLog.e)); + videoLogList.add(new mLogMsg("#------------------------------", mLog.v)); + } + checkConfigFile(context, new File(getPath(), configName), first); + } + } else { + isSave = false; + } + } + + @SuppressLint("SimpleDateFormat") + public static boolean checkConfigFile(Context context, File file, boolean firstOne) { + try { + String input = readConfigFile(context, file); + boolean reformat = true, isCameraChange = false, update = true; + if (input.length() > 0) { + String[] read = input.split("\r\n"); + int target = 0, t; + String title = CONFIG_TITLE; + String first = "firstCameraID = ", second = "secondCameraID = "; + String code = "numberOfRuns = "; + for (String s : read) + if (s.contains(title)) { + target++; + t = s.indexOf(title) + title.length(); + title = s.substring(t); + break; + } else if (s.contains(first)) { + target++; + t = s.indexOf(first) + first.length(); + first = s.substring(t); + break; + } else if (s.contains(second)) { + target++; + t = s.indexOf(second) + second.length(); + second = s.substring(t); + break; + } else if (s.contains(code)) { + target++; + t = s.indexOf(code) + code.length(); + code = s.substring(t); + break; + } + if (target == 4) { + reformat = false; + if (title.equals(context.getString(R.string.app_name))) { + update = false; + } else { + Log.e(TAG, "Config is updated."); + videoLogList.add(new mLogMsg("Config is updated.", mLog.e)); + reformat = true; + } + if (!first.equals(second)) { + boolean cdr9020 = (first.equals("1") && second.equals("2")) || (first.equals("2") && second.equals("1")); + if (cdr9020) { + Log.e(TAG, "Inner and External can't be used at the same time."); + videoLogList.add(new mLogMsg("Inner and External can't be used at the same time.", mLog.e)); + reformat = true; + } else { + if (isCameraID(first.split("\n")[0], second.split("\n")[0])) { + lastFirstCamera = firstOne ? first : firstCamera; + lastSecondCamera = firstOne ? second : secondCamera; + allCamera.set(0, firstCamera = first); + allCamera.set(1, secondCamera = second); + if (!firstOne) + if (!lastFirstCamera.equals(firstCamera) || !lastSecondCamera.equals(secondCamera)) { + Log.e(TAG, "isCameraChange:" + lastFirstCamera + "-" + firstCamera + "," + lastSecondCamera + "-" + secondCamera); + isCameraChange = true; + } + } else { + Log.e(TAG, "Unknown Camera ID."); + videoLogList.add(new mLogMsg("Unknown Camera ID.", mLog.e)); + reformat = true; + } + } + } else { + Log.e(TAG, "Cannot use the same Camera ID."); + videoLogList.add(new mLogMsg("Cannot use the same Camera ID.", mLog.e)); + reformat = true; + } + if (isInteger(code.split("\n")[0], true)) { + int min = Integer.parseInt(code.split("\n")[0]); + if (min <= 0) { + Log.e(TAG, "The test time must be a positive number."); + videoLogList.add(new mLogMsg("The test time must be a positive number.", mLog.e)); + reformat = true; + } else { + setTestTime(min); + } + } else { + Log.e(TAG, "Unknown Record Times."); + videoLogList.add(new mLogMsg("Unknown Record Times.", mLog.e)); + reformat = true; + } + } else { + Log.e(TAG, "target != 4 & Config is reset."); + } + } + if (update) { + StringBuilder logString = new StringBuilder(LOG_TITLE + context.getString(R.string.app_name) + "\r\n"); + videoLogList.add(new mLogMsg("Reformat the Log file.", mLog.e)); + for (mLogMsg logs : videoLogList) { + DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + logString.append(dateFormat.format(logs.time)).append(" run:") + .append(logs.runTime).append(" -> ").append(logs.msg).append("\r\n"); + } + try { + FileOutputStream output = new FileOutputStream(new File(getPath(), logName), false); + output.write(logString.toString().getBytes()); + output.close(); + videoLogList.clear(); + } catch (Exception e) { + e.printStackTrace(); + videoLogList.add(new mLogMsg("Write LOG failed. <============ error here", mLog.e)); + } + } + if (reformat) { + reformatConfigFile(context, file); + return true; + } else return isCameraChange; + } catch (Exception e) { + e.printStackTrace(); + reformatConfigFile(context, file); + return true; + } + } + + public static boolean isCameraID(String f, String b) { + try { + if (Integer.parseInt(f) <= -1) { + videoLogList.add(new mLogMsg("The Camera ID must be a positive number.", mLog.e)); + return false; + } else { + boolean cameraID; + switch (Integer.parseInt(f)) { + case 0: + case 1: + case 2: + cameraID = true; + break; + default: + cameraID = false; + break; + } + if (!cameraID) { + videoLogList.add(new mLogMsg("The Camera ID is unknown.", mLog.e)); + return false; + } + } + if (Integer.parseInt(b) <= -1) { + videoLogList.add(new mLogMsg("The Camera ID must be a positive number.", mLog.e)); + return false; + } else { + boolean cameraID; + switch (Integer.parseInt(b)) { + case 0: + case 1: + case 2: + cameraID = true; + break; + default: + cameraID = false; + break; + } + if (!cameraID) { + videoLogList.add(new mLogMsg("The Camera ID is unknown.", mLog.e)); + return false; + } + } + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + public static void setConfigFile(Context context, File file, View view, boolean reset) { + EditText editText_1 = view.findViewById(R.id.dialog_editText_1); + EditText editText_2 = view.findViewById(R.id.dialog_editText_2); + EditText editText_3 = view.findViewById(R.id.dialog_editText_3); + int isFinish = defaultRun; + + if (!reset) { + if (isInteger(editText_3.getText().toString(), false)) { + isFinish = Integer.parseInt(editText_3.getText().toString()); + } + } + + writeConfigFile(context, file, ( + !reset ? new Config(context, editText_1.getText().toString(), + editText_2.getText().toString(), isFinish) : new Config(context)).config()); + //toast(context, "Write file is completed.", mLog.i); + } + + public static void reformatConfigFile(Context context, File file) { + //toast(context, "Config file error.", mLog.e); + lastFirstCamera = "0"; + lastSecondCamera = "1"; + allCamera.set(0, firstCamera = lastFirstCamera); + allCamera.set(1, secondCamera = lastSecondCamera); + writeConfigFile(context, file, new Config(context).config()); + videoLogList.add(new mLogMsg("Reformat the Config file.", mLog.e)); + } + + public static String readConfigFile(Context context, File file) { + String tmp = ""; + try { + byte[] buffer = new byte[100]; + int length; + FileInputStream fis = new FileInputStream(file); + BufferedInputStream bis = new BufferedInputStream(fis); + ByteArrayOutputStream bytes = new ByteArrayOutputStream(); + while ((length = bis.read(buffer)) != -1) { + bytes.write(buffer, 0, length); + } + tmp += bytes.toString(); + bytes.close(); + bis.close(); + fis.close(); + } catch (Exception e) { + e.printStackTrace(); + isError = true; + videoLogList.add(new mLogMsg("Read failed. <============ Crash here", mLog.e)); + saveLog(context, false, false); + errorMessage = "Read failed. <============ Crash here"; + videoLogList.add(new mLogMsg("Read failed.", mLog.e)); + tmp += ("App Version:" + context.getString(R.string.app_name) + "\r\n"); + tmp += ("Read failed. <============ Crash here"); + return tmp; + } + return tmp; + } + + public static void writeConfigFile(Context context, File file, String[] str) { + StringBuilder tmp = new StringBuilder(); + for (String s : str) + tmp.append(s); + try { + FileOutputStream output = new FileOutputStream(file); + output.write(tmp.toString().getBytes()); + output.close(); + } catch (Exception e) { + e.printStackTrace(); + isError = true; + videoLogList.add(new mLogMsg("Write failed. <============ Crash here", mLog.e)); + saveLog(context, false, false); + errorMessage = "Write failed. <============ Crash here"; + } + } + + @SuppressLint({"DefaultLocale", "SimpleDateFormat"}) + public static String getCalendarTime() { + Calendar calendar = Calendar.getInstance(); + return new SimpleDateFormat("HHmmss").format(calendar.getTime()) + ""; + } + + @SuppressLint({"DefaultLocale", "SimpleDateFormat"}) + public static String getCalendarTime(String cameraId) { + Calendar calendar = Calendar.getInstance(); + String cm = "c"; + if (cameraId.equals(allCamera.get(0))) + cm = "f"; + if (cameraId.equals(allCamera.get(1))) + cm = "s"; + return "v" + new SimpleDateFormat("yyyyMMddHHmmss").format(calendar.getTime()) + cm; + } + + public static String getFileExtension(String fullName) { + String fileName = new File(fullName).getName(); + int dotIndex = fileName.lastIndexOf('.'); + return (dotIndex == -1) ? "" : fileName.substring(dotIndex + 1); + } + + public static boolean isCameraOne(String cameraId) { + return cameraId.equals(allCamera.get(0)); + } + + public static boolean isLastCamera(String cameraId) { + return cameraId.equals(allCamera.get(1)); + } +} diff --git a/app/src/main/java/com/askey/widget/CustomTextView.java b/app/src/main/java/com/d160/view/CustomTextView.java old mode 100755 new mode 100644 similarity index 95% rename from app/src/main/java/com/askey/widget/CustomTextView.java rename to app/src/main/java/com/d160/view/CustomTextView.java index e6bee87..492b206 --- a/app/src/main/java/com/askey/widget/CustomTextView.java +++ b/app/src/main/java/com/d160/view/CustomTextView.java @@ -1,4 +1,4 @@ -package com.askey.widget; +package com.d160.view; import android.annotation.SuppressLint; import android.content.Context; @@ -7,7 +7,7 @@ import android.util.AttributeSet; import android.widget.TextView; -import com.askey.record.R; +import com.d160.bit.R; @SuppressLint("AppCompatCustomView") public class CustomTextView extends TextView { diff --git a/app/src/main/java/com/askey/widget/HomeListen.java b/app/src/main/java/com/d160/view/HomeListen.java similarity index 96% rename from app/src/main/java/com/askey/widget/HomeListen.java rename to app/src/main/java/com/d160/view/HomeListen.java index 7c99b04..32faee3 100644 --- a/app/src/main/java/com/askey/widget/HomeListen.java +++ b/app/src/main/java/com/d160/view/HomeListen.java @@ -1,4 +1,4 @@ -package com.askey.widget; +package com.d160.view; import android.content.BroadcastReceiver; import android.content.Context; @@ -37,7 +37,7 @@ public void start() { try{ mContext.registerReceiver(mHomeBtnReceiver, mHomeBtnIntentFilter); }catch (Exception e){ - + e.printStackTrace(); } } @@ -45,7 +45,7 @@ public void stop() { try{ mContext.unregisterReceiver(mHomeBtnReceiver); }catch (Exception e){ - + e.printStackTrace(); } } diff --git a/app/src/main/java/com/askey/widget/mListAdapter.java b/app/src/main/java/com/d160/view/mListAdapter.java similarity index 96% rename from app/src/main/java/com/askey/widget/mListAdapter.java rename to app/src/main/java/com/d160/view/mListAdapter.java index fdfb05d..add1f7d 100644 --- a/app/src/main/java/com/askey/widget/mListAdapter.java +++ b/app/src/main/java/com/d160/view/mListAdapter.java @@ -1,4 +1,4 @@ -package com.askey.widget; +package com.d160.view; import android.view.View; import android.view.ViewGroup; diff --git a/app/src/main/java/com/askey/widget/mLog.java b/app/src/main/java/com/d160/view/mLog.java similarity index 60% rename from app/src/main/java/com/askey/widget/mLog.java rename to app/src/main/java/com/d160/view/mLog.java index fa6ee4d..4a44b27 100644 --- a/app/src/main/java/com/askey/widget/mLog.java +++ b/app/src/main/java/com/d160/view/mLog.java @@ -1,4 +1,4 @@ -package com.askey.widget; +package com.d160.view; public enum mLog { v, d, i, w, e diff --git a/app/src/main/java/com/d160/view/mLogMsg.java b/app/src/main/java/com/d160/view/mLogMsg.java new file mode 100644 index 0000000..3770cef --- /dev/null +++ b/app/src/main/java/com/d160/view/mLogMsg.java @@ -0,0 +1,26 @@ +package com.d160.view; + +import com.d160.bit.Utils; + +import java.util.*; + +public class mLogMsg { + public int runTime; + public Date time; + public String msg; + public mLog type; + + public mLogMsg(String msg) { + this.runTime = Utils.getIsRun(); + this.time = Calendar.getInstance().getTime(); + this.msg = msg; + this.type = mLog.d; + } + + public mLogMsg(String msg, mLog type) { + this.runTime = Utils.getIsRun(); + this.time = Calendar.getInstance().getTime(); + this.msg = msg; + this.type = type; + } +} diff --git a/app/src/main/res/drawable/ic_video.xml b/app/src/main/res/drawable/ic_video.xml new file mode 100644 index 0000000..0f8bc6f --- /dev/null +++ b/app/src/main/res/drawable/ic_video.xml @@ -0,0 +1,9 @@ + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_video_record.xml b/app/src/main/res/layout/activity_video_record.xml index 04cf1ff..e576be0 100644 --- a/app/src/main/res/layout/activity_video_record.xml +++ b/app/src/main/res/layout/activity_video_record.xml @@ -2,11 +2,11 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" - tools:context=".VideoRecordActivity" + tools:context=".CameraActivity" tools:ignore="Autofill,ButtonStyle,ContentDescription,HardcodedText,NestedWeights,RtlHardcoded,UselessParent,SpUsage"> @@ -35,7 +35,7 @@ android:layout_weight="1"> @@ -60,55 +60,7 @@ - - - - - - - - - - - - -