Commit a25be043 by Yu-Tung

First Commit

parents
*.iml
.gradle
/local.properties
/.idea/caches
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/assetWizardSettings.xml
.DS_Store
/build
/captures
.externalNativeBuild
.cxx
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<codeStyleSettings language="XML">
<indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="4" />
</indentOptions>
<arrangement>
<rules>
<section>
<rule>
<match>
<AND>
<NAME>xmlns:android</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>xmlns:.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:id</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:name</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>name</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>style</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
<order>ANDROID_ATTRIBUTE_ORDER</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>.*</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
</rules>
</arrangement>
</codeStyleSettings>
</code_scheme>
</component>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<compositeConfiguration>
<compositeBuild compositeDefinitionSource="SCRIPT" />
</compositeConfiguration>
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="resolveModulePerSourceSet" value="false" />
<option name="testRunner" value="PLATFORM" />
</GradleProjectSettings>
</option>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RunConfigurationProducerService">
<option name="ignoredProducers">
<set>
<option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
</set>
</option>
</component>
</project>
\ No newline at end of file
apply plugin: 'com.android.application'
android {
compileSdkVersion 29
buildToolsVersion "29.0.3"
defaultConfig {
applicationId "com.example.audiovisualrecord"
minSdkVersion 24
targetSdkVersion 29
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.2.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
implementation 'androidx.recyclerview:recyclerview:1.1.0'
implementation 'com.google.android.material:material:1.2.0-alpha06'
implementation 'io.reactivex.rxjava2:rxjava:2.0.7'
implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'
implementation 'com.squareup.okhttp3:okhttp:4.7.1'
implementation 'com.squareup.okhttp3:logging-interceptor:4.7.1'
// retrofit
implementation 'com.squareup.retrofit2:retrofit:2.2.0'
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.2.0'
implementation 'com.squareup.retrofit2:converter-gson:2.3.0'
implementation 'com.google.code.gson:gson:2.7'
implementation 'com.github.bumptech.glide:glide:3.6.1'
// FFmpeg
implementation 'com.arthenica:mobile-ffmpeg-full:4.3.2'
}
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
package com.example.audiovisualrecord;
import android.content.Context;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
/**
* Instrumented test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Test
public void useAppContext() {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
assertEquals("com.example.audiovisualrecord", appContext.getPackageName());
}
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.audiovisualrecord">
<uses-feature
android:name="android.hardware.camera"
android:required="true" />
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.AppCompat.Light.NoActionBar">
<activity android:name=".ui.login.LoginActivity" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".ui.main.MainActivity" />
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
</application>
</manifest>
\ No newline at end of file
package com.example.audiovisualrecord;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.util.Log;
import androidx.annotation.NonNull;
import java.io.File;
import java.util.Locale;
public class FileUtil {
/**
* 根据Uri获取图片绝对路径
* @param context context
* @param uri uri
*/
public static String getFileAbsolutePath(Context context, Uri uri) {
if (context == null || uri == null) return null;
// DocumentProvider
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && DocumentsContract.isDocumentUri(context, uri)) {
if (isExternalStorageDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
if ("primary".equalsIgnoreCase(type)) {
return Environment.getExternalStorageDirectory() + "/" + split[1];
}else if ("home".equalsIgnoreCase(type)) {
return Environment.getExternalStorageDirectory() + "/documents/" + split[1];
}
} else if (isDownloadsDocument(uri)) {
// DownloadsProvider
final String id = DocumentsContract.getDocumentId(uri);
if (TextUtils.isEmpty(id)) {
return null;
}
if (id.startsWith("raw:")) {
return id.substring(4);
}
String[] contentUriPrefixesToTry = new String[]{
"content://downloads/public_downloads",
"content://downloads/my_downloads",
"content://downloads/all_downloads"
};
for (String contentUriPrefix : contentUriPrefixesToTry) {
try {
Uri contentUri = ContentUris.withAppendedId(Uri.parse(contentUriPrefix), Long.valueOf(id));
String path = getDataColumn(context, contentUri, null, null);
if (path != null) {
return path;
}
} catch (Exception ignore) {
}
}
try {
String path = getDataColumn(context, uri, null, null);
if (path != null) {
return path;
}
} catch (Exception ignore) {
}
// path could not be retrieved using ContentResolver, therefore copy file to accessible cache using streams
return null;
} else if (isMediaDocument(uri)) {
// MediaProvider
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
Uri contentUri;
switch (type.toLowerCase(Locale.ENGLISH)) {
case "image":
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
break;
case "video":
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
break;
case "audio":
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
break;
default:
contentUri = MediaStore.Files.getContentUri("external");
break;
}
final String selection = MediaStore.MediaColumns._ID +"=?";
final String[] selectionArgs = new String[]{split[1]};
return getDataColumn(context, contentUri, selection, selectionArgs);
}
} else if (ContentResolver.SCHEME_CONTENT.equalsIgnoreCase(uri.getScheme())) {
// MediaStore (and general)
// Return the remote address
if (isGooglePhotosUri(uri)) {
return uri.getLastPathSegment();
}
return getDataColumn(context, uri, null, null);
} else if (ContentResolver.SCHEME_FILE.equalsIgnoreCase(uri.getScheme())) {
// File
return uri.getPath();
}
return null;
}
/**
* 通过游标获取当前文件路径
* @param context context
* @param uri uri
* @param selection selection
* @param selectionArgs selectionArgs
* @return 路径,未找到返回null
*/
public static String getDataColumn(Context context, @NonNull Uri uri, String selection, String[] selectionArgs) {
Cursor cursor = null;
String column = MediaStore.Images.Media.DATA;
String[] projection = {column};
try {
cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
if (cursor != null && cursor.moveToFirst()) {
int index = cursor.getColumnIndexOrThrow(column);
return cursor.getString(index);
}
} catch (Exception ignore) {
Log.e("error", ignore.getMessage());
} finally {
if (cursor != null)
cursor.close();
}
return null;
}
//檔案名
public static String fileName(String path){
if( path == null || path.isEmpty() ) return "";
File file = new File(path);
if( !file.exists() || !file.isFile() ) {
return "";
}
String filename = file.getName();
// String ext = FileKit.getFileExt(filename);
// if( !ext.equalsIgnoreCase(".csv") ){
// return "";
// }
return filename;
}
public static boolean isExternalStorageDocument(Uri uri) {
return "com.android.externalstorage.documents".equals(uri.getAuthority());
}
public static boolean isDownloadsDocument(Uri uri) {
return "com.android.providers.downloads.documents".equals(uri.getAuthority());
}
public static boolean isMediaDocument(Uri uri) {
return "com.android.providers.media.documents".equals(uri.getAuthority());
}
public static boolean isGooglePhotosUri(Uri uri) {
return "com.google.android.apps.photos.content".equals(uri.getAuthority());
}
}
package com.example.audiovisualrecord;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.ClipData;
import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
public class MagicFileChooser {
// TODO ------類別常數------
/**
* 檔案選取器的Activity Request Code。
*/
public static final int ACTIVITY_FILE_CHOOSER = 9973;
// TODO -----物件變數-----
/**
* 儲存使用這個檔案選取器的Activity。
*/
private final Activity activity;
// TODO -----物件變數-----
/**
* 儲存是否正在選取檔案。
*/
private boolean choosing = false;
/**
* 儲存被選到的檔案是否一定要可以讀取。
*/
private boolean mustCanRead;
/**
* 儲存被選到的檔案。
*/
private File[] chosenFiles;
// TODO -----建構子-----
/**
* 建構子,在Activity內使用檔案選取器。
*
* @param activity 傳入使用這個檔案選取器的Activity。
*/
public MagicFileChooser(final Activity activity) {
this.activity = activity;
}
// TODO -----類別方法-----
/**
* 從Uri取得絕對路徑。
*
* @param context 傳入Context
* @param uris 傳入Uri陣列
* @return 傳回絕對路徑字串陣列,若絕對路徑無法取得,則對應的陣列索引位置為null
*/
public static String[] getAbsolutePathsFromUris(final Context context, final Uri[] uris) {
return getAbsolutePathsFromUris(context, uris, false);
}
/**
* 從多個Uri取得絕對路徑。
*
* @param context 傳入Context
* @param uris 傳入Uri陣列
* @param mustCanRead 傳入Uri所指的路徑是否一定要可以讀取
* @return 傳回絕對路徑字串陣列,若絕對路徑無法取得或是無法讀取,則對應的陣列索引位置為null
*/
public static String[] getAbsolutePathsFromUris(final Context context, final Uri[] uris, final boolean mustCanRead) {
if (uris == null) {
return null;
}
final int urisLength = uris.length;
final String[] paths = new String[urisLength];
for (int i = 0; i < urisLength; ++i) {
final Uri uri = uris[i];
paths[i] = getAbsolutePathFromUri(context, uri, mustCanRead);
}
return paths;
}
/**
* 從多個Uri取得File物件。
*
* @param context 傳入Context
* @param uris 傳入Uri陣列
* @return 傳回File物件陣列,若File物件無法建立,則對應的陣列索引位置為null
*/
public static File[] getFilesFromUris(final Context context, final Uri[] uris) {
return getFilesFromUris(context, uris, false);
}
/**
* 從多個Uri取得File物件。
*
* @param context 傳入Context
* @param uris 傳入Uri陣列
* @param mustCanRead 傳入Uri所指的路徑是否一定要可以讀取
* @return 傳回File物件陣列,若File物件無法建立或是檔案路徑無法讀取,則對應的陣列索引位置為null
*/
public static File[] getFilesFromUris(final Context context, final Uri[] uris, final boolean mustCanRead) {
if (uris == null) {
return null;
}
final int urisLength = uris.length;
final File[] files = new File[urisLength];
for (int i = 0; i < urisLength; ++i) {
final Uri uri = uris[i];
files[i] = getFileFromUri(context, uri, mustCanRead);
}
return files;
}
/**
* 從Uri取得絕對路徑。
*
* @param context 傳入Context
* @param uri 傳入Uri物件
* @return 傳回絕對路徑,若絕對路徑無法取得,傳回null
*/
public static String getAbsolutePathFromUri(final Context context, final Uri uri) {
return getAbsolutePathFromUri(context, uri, false);
}
/**
* 從Uri取得絕對路徑。
*
* @param context 傳入Context
* @param uri 傳入Uri物件
* @param mustCanRead 傳入Uri所指的路徑是否一定要可以讀取
* @return 傳回絕對路徑,若絕對路徑無法取得或是無法讀取,傳回null
*/
public static String getAbsolutePathFromUri(final Context context, final Uri uri, final boolean mustCanRead) {
final File file = getFileFromUri(context, uri, mustCanRead);
if (file != null) {
return file.getAbsolutePath();
} else {
return null;
}
}
/**
* 從Uri取得File物件。
*
* @param context 傳入Context
* @param uri 傳入Uri物件
* @return 傳回File物件,若File物件無法建立,傳回null
*/
public static File getFileFromUri(final Context context, final Uri uri) {
return getFileFromUri(context, uri, false);
}
/**
* 從Uri取得File物件。
*
* @param context 傳入Context
* @param uri 傳入Uri物件
* @param mustCanRead 傳入Uri所指的路徑是否一定要可以讀取
* @return 傳回File物件,若File物件無法建立或是檔案路徑無法讀取,傳回null
*/
@SuppressLint("NewApi")
public static File getFileFromUri(final Context context, final Uri uri, final boolean mustCanRead) {
if (uri == null) {
return null;
}
// 判斷是否為Android 4.4之後的版本
final boolean after44 = Build.VERSION.SDK_INT >= 19;
if (after44 && DocumentsContract.isDocumentUri(context, uri)) {
// 如果是Android 4.4之後的版本,而且屬於文件URI
final String authority = uri.getAuthority();
// 判斷Authority是否為本地端檔案所使用的
if ("com.android.externalstorage.documents".equals(authority)) {
// 外部儲存空間
final String docId = DocumentsContract.getDocumentId(uri);
final String[] divide = docId.split(":");
final String type = divide[0];
if ("primary".equals(type)) {
String path = Environment.getExternalStorageDirectory().getAbsolutePath().concat("/").concat(divide[1]);
return createFileObjFromPath(path, mustCanRead);
} else {
String path = "/storage/".concat(type).concat("/").concat(divide[1]);
return createFileObjFromPath(path, mustCanRead);
}
} else if ("com.android.providers.downloads.documents".equals(authority)) {
// 下載目錄
final String docId = DocumentsContract.getDocumentId(uri);
if (docId.startsWith("raw:")) {
final String path = docId.replaceFirst("raw:", "");
return createFileObjFromPath(path, mustCanRead);
}
final Uri downloadUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.parseLong(docId));
String path = queryAbsolutePath(context, downloadUri);
return createFileObjFromPath(path, mustCanRead);
} else if ("com.android.providers.media.documents".equals(authority)) {
// 圖片、影音檔案
final String docId = DocumentsContract.getDocumentId(uri);
final String[] divide = docId.split(":");
final String type = divide[0];
Uri mediaUri = null;
if ("image".equals(type)) {
mediaUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
} else if ("video".equals(type)) {
mediaUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
} else if ("audio".equals(type)) {
mediaUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
} else {
return null;
}
mediaUri = ContentUris.withAppendedId(mediaUri, Long.parseLong(divide[1]));
String path = queryAbsolutePath(context, mediaUri);
return createFileObjFromPath(path, mustCanRead);
}
} else {
// 如果是一般的URI
final String scheme = uri.getScheme();
String path = null;
if ("content".equals(scheme)) {
// 內容URI
path = queryAbsolutePath(context, uri);
} else if ("file".equals(scheme)) {
// 檔案URI
path = uri.getPath();
}
return createFileObjFromPath(path, mustCanRead);
}
return null;
}
/**
* 將路徑轉成File物件。
*
* @param path 傳入檔案路徑
* @return 傳回File物件,若File物件無法建立,傳回null。
*/
public static File createFileObjFromPath(final String path) {
return createFileObjFromPath(path, false);
}
/**
* 將路徑轉成File物件。
*
* @param path 傳入檔案路徑
* @param mustCanRead 傳入檔案路徑是否一定要可以讀取
* @return 傳回File物件,若File物件無法建立或是檔案路徑無法讀取,傳回null
*/
public static File createFileObjFromPath(final String path, final boolean mustCanRead) {
if (path != null) {
try {
File file = new File(path);
if (mustCanRead) {
file.setReadable(true);
if (!file.canRead()) {
return null;
}
}
return file.getAbsoluteFile();
} catch (Exception ex) {
ex.printStackTrace();
}
}
return null;
}
/**
* 查詢MediaStroe Uri對應的絕對路徑。
*
* @param context 傳入Context
* @param uri 傳入MediaStore Uri
* @return 傳回絕對路徑
*/
public static String queryAbsolutePath(final Context context, final Uri uri) {
final String[] projection = {MediaStore.MediaColumns.DATA};
Cursor cursor = null;
try {
cursor = context.getContentResolver().query(uri, projection, null, null, null);
if (cursor != null && cursor.moveToFirst()) {
final int index = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA);
return cursor.getString(index);
}
} catch (final Exception ex) {
ex.printStackTrace();
if (cursor != null) {
cursor.close();
}
}
return null;
}
// TODO -----物件方法-----
/**
* 顯示檔案選取器,選取所有檔案,不設定檔案選取器的標題,僅進行單獨選取,被選到的檔案不一定要可以讀取。
*
* @return 傳回檔案選取器是否開啟成功
*/
public boolean showFileChooser() {
return showFileChooser("*/*");
}
/**
* 顯示檔案選取器,不設定檔案選取器的標題,僅進行單獨選取,被選到的檔案不一定要可以讀取。
*
* @param mimeType 傳入篩選的MIME類型
* @return 傳回檔案選取器是否開啟成功
*/
public boolean showFileChooser(final String mimeType) {
return showFileChooser(mimeType, null);
}
/**
* 顯示檔案選取器,僅進行單獨選取,被選到的檔案不一定要可以讀取。
*
* @param mimeType 傳入篩選的MIME類型
* @param chooserTitle 傳入檔案選取器的標題,若為null則用預設值
* @return 傳回檔案選取器是否開啟成功
*/
public boolean showFileChooser(final String mimeType, final String chooserTitle) {
return showFileChooser(mimeType, chooserTitle, false);
}
/**
* 顯示檔案選取器,被選到的檔案不一定要可以讀取。
*
* @param mimeType 傳入篩選的MIME類型
* @param chooserTitle 傳入檔案選取器的標題,若為null則用預設值
* @param allowMultiple 傳入檔案選取器是否使用複選
* @return 傳回檔案選取器是否開啟成功
*/
public boolean showFileChooser(final String mimeType, final String chooserTitle, final boolean allowMultiple) {
return showFileChooser(mimeType, chooserTitle, allowMultiple, false);
}
/**
* 顯示檔案選取器。
*
* @param mimeType 傳入篩選的MIME類型
* @param chooserTitle 傳入檔案選取器的標題,若為null則用預設值
* @param allowMultiple 傳入檔案選取器是否使用複選
* @param mustCanRead 傳入被選到的檔案是否一定要可以讀取
* @return 傳回檔案選取器是否開啟成功
*/
public boolean showFileChooser(final String mimeType, final String chooserTitle, final boolean allowMultiple, final boolean mustCanRead) {
if (mimeType == null || choosing) {
return false;
}
choosing = true;
// 檢查是否有可用的Activity
final PackageManager packageManager = activity.getPackageManager();
final Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType(mimeType);
final List<ResolveInfo> list = packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
if (list.size() > 0) {
this.mustCanRead = mustCanRead;
// 如果有可用的Activity
final Intent picker = new Intent(Intent.ACTION_GET_CONTENT);
picker.setType(mimeType);
picker.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, allowMultiple);
picker.putExtra(Intent.EXTRA_LOCAL_ONLY, true);
// 使用Intent Chooser
final Intent destIntent = Intent.createChooser(picker, chooserTitle);
activity.startActivityForResult(destIntent, ACTIVITY_FILE_CHOOSER);
return true;
} else {
return false;
}
}
/**
* 當檔案選取器被關閉後,應該要呼叫這個方法,判斷檔案選取器是否有選取到檔案,接著再用getChosenFiles方法來取得選取結果。
*
* @param requestCode 傳入Activity的Request Code
* @param resultCode 傳入Activity的Request Code
* @param data 傳入Activity的data
* @return 傳回檔案選取器是否有選取結果。
*/
public boolean onActivityResult(final int requestCode, final int resultCode, final Intent data) {
if (requestCode == ACTIVITY_FILE_CHOOSER) {
choosing = false;
if (resultCode == Activity.RESULT_OK) {
final Uri uri = data.getData();
if (uri != null) {
// 單選
chosenFiles = getFilesFromUris(activity, new Uri[]{uri}, mustCanRead);
return true;
} else if (Build.VERSION.SDK_INT >= 16) {
// 複選
final ClipData clipData = data.getClipData();
if (clipData != null) {
int count = clipData.getItemCount();
if (count > 0) {
final Uri[] uris = new Uri[count];
for (int i = 0; i < count; ++i) {
uris[i] = clipData.getItemAt(i).getUri();
}
chosenFiles = getFilesFromUris(activity, uris, mustCanRead);
return true;
}
}
}
}
}
return false;
}
/**
* 取得被選取到的檔案。
*
* @return 傳回被選取到的檔案,過濾掉不成功的部份
*/
public File[] getChosenFiles(final boolean filter) {
if (chosenFiles == null) {
return new File[0];
} else {
final ArrayList<File> alFileList = new ArrayList<>();
for (final File chosenFile : chosenFiles) {
if (filter && chosenFile == null) {
continue;
}
alFileList.add(chosenFile);
}
final File[] files = new File[alFileList.size()];
alFileList.toArray(files);
return files;
}
}
/**
* 取得被選取到的檔案。
*
* @return 傳回被選取到的檔案,過濾掉不成功的部份
*/
public File[] getChosenFiles() {
return getChosenFiles(true);
}
}
package com.example.audiovisualrecord.base;
import android.app.AlertDialog;
import android.app.DatePickerDialog;
import android.app.ProgressDialog;
import android.content.ContentUris;
import android.content.Context;
import android.content.DialogInterface;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.annotation.StringRes;
import androidx.appcompat.app.AppCompatActivity;
import com.example.audiovisualrecord.utils.ToastCreator;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.List;
/**
* Created by 5*N on 2017/12/22
*/
public abstract class BaseActivity extends AppCompatActivity implements BaseView {
private ProgressDialog mProgressDialog;
private Calendar mCalendar = Calendar.getInstance();
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public void showProgressDialog(@StringRes int text) {
dismissProgressDialog();
mProgressDialog = new ProgressDialog(this);
mProgressDialog.setMessage(this.getResources().getString(text));
mProgressDialog.setCancelable(false);
mProgressDialog.setCanceledOnTouchOutside(false);
mProgressDialog.show();
}
@Override
public void showItemDialog(List<String> list, DialogInterface.OnClickListener onClickListener) {
new AlertDialog.Builder(this)
.setItems(list.toArray(new String[list.size()]), onClickListener)
.create()
.show();
}
@Override
public void showProgressDialog(String text) {
dismissProgressDialog();
mProgressDialog = new ProgressDialog(this);
mProgressDialog.setMessage(text);
mProgressDialog.setCancelable(false);
mProgressDialog.setCanceledOnTouchOutside(false);
mProgressDialog.show();
}
@Override
public void dismissProgressDialog() {
if (mProgressDialog != null && mProgressDialog.isShowing()) {
mProgressDialog.cancel();
}
}
@Override
public void showDialogCaveatMessage(String title, String message) {
new AlertDialog.Builder(this)
.setTitle(title)
.setMessage(message)
.setPositiveButton(android.R.string.yes, null)
.setIcon(android.R.drawable.ic_dialog_alert)
.show();
}
@Override
public void showDialogCaveatMessage(String message) {
new AlertDialog.Builder(this)
.setTitle(message)
.setPositiveButton(android.R.string.yes, null)
.setIcon(android.R.drawable.ic_dialog_alert)
.show();
}
@Override
public void showDialogMessage(String message) {
new AlertDialog.Builder(this)
.setTitle(message)
.setPositiveButton(android.R.string.yes, null)
.show();
}
@Override
public void showDialogMessage(String title, String message) {
new AlertDialog.Builder(this)
.setTitle(title)
.setMessage(message)
.setPositiveButton(android.R.string.yes, null)
.setIcon(android.R.drawable.ic_dialog_alert)
.show();
}
@Override
public void showDatePickerDialog(DatePickerDialog.OnDateSetListener onDateSetListener) {
DatePickerDialog dialog = new DatePickerDialog(this,
onDateSetListener,
mCalendar.get(Calendar.YEAR),
mCalendar.get(Calendar.MONTH),
mCalendar.get(Calendar.DAY_OF_MONTH));
dialog.show();
}
@Override
public void showSelectDialog(String text, DialogInterface.OnClickListener onClickListener) {
new AlertDialog.Builder(this)
.setMessage(text)
.setPositiveButton("確認", onClickListener)
.setCancelable(false)
.create()
.show();
}
@Override
public String getResourceString(@StringRes int text) {
return getResources().getString(text);
}
@Override
public String getTodayTime() {
String dateformat = "yyyyMMdd";
Calendar mCal = Calendar.getInstance();
SimpleDateFormat df = new SimpleDateFormat(dateformat);
String today = df.format(mCal.getTime());
return today;
}
@Override
public void showToast(@StringRes int text) {
ToastCreator.makeText(this, text, Toast.LENGTH_SHORT);
}
@Override
public void showToast(String text) {
ToastCreator.makeText(this, text, Toast.LENGTH_SHORT);
}
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
@Override
public String getPath(Uri uri) {
// check here to KITKAT or new version
final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
// DocumentProvider
if (isKitKat && DocumentsContract.isDocumentUri(this, uri))
{
// ExternalStorageProvider
if (isExternalStorageDocument(uri))
{
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
if ("primary".equalsIgnoreCase(type))
{
return Environment.getExternalStorageDirectory() + "/"
+ split[1];
}
}
// DownloadsProvider
else if (isDownloadsDocument(uri))
{
final String id = DocumentsContract.getDocumentId(uri);
final Uri contentUri = ContentUris.withAppendedId(
Uri.parse("content://downloads/public_downloads"),
Long.valueOf(id));
return getDataColumn(this, contentUri, null, null);
}
// MediaProvider
else if (isMediaDocument(uri))
{
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
Uri contentUri = null;
if ("image".equals(type))
{
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
}
else if ("video".equals(type))
{
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
}
else if ("audio".equals(type))
{
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
}
final String selection = "_id=?";
final String[] selectionArgs = new String[] { split[1] };
return getDataColumn(this, contentUri, selection,
selectionArgs);
}
}
// MediaStore (and general)
else if ("content".equalsIgnoreCase(uri.getScheme()))
{
// Return the remote address
if (isGooglePhotosUri(uri))
return uri.getLastPathSegment();
return getDataColumn(this, uri, null, null);
}
// File
else if ("file".equalsIgnoreCase(uri.getScheme()))
{
return uri.getPath();
}
return null;
}
/**
* Get the value of the data column for this Uri. This is useful for
* MediaStore Uris, and other file-based ContentProviders.
*
* @param context - The context.
* @param uri - The Uri to query.
* @param selection - (Optional) Filter used in the query.
* @param selectionArgs - (Optional) Selection arguments used in the query.
* @return - The value of the _data column, which is typically a file path.
*/
private static String getDataColumn(Context context, Uri uri,
String selection, String[] selectionArgs)
{
Cursor cursor = null;
final String column = "_data";
final String[] projection = { column };
try
{
cursor = context.getContentResolver().query(uri, projection,
selection, selectionArgs, null);
if (cursor != null && cursor.moveToFirst())
{
final int index = cursor.getColumnIndexOrThrow(column);
return cursor.getString(index);
}
}
finally
{
if (cursor != null)
cursor.close();
}
return null;
}
/**
* @param uri - The Uri to check.
* @return - Whether the Uri authority is ExternalStorageProvider.
*/
private static boolean isExternalStorageDocument(Uri uri)
{
return "com.android.externalstorage.documents".equals(uri.getAuthority());
}
/**
* @param uri - The Uri to check.
* @return - Whether the Uri authority is DownloadsProvider.
*/
private static boolean isDownloadsDocument(Uri uri)
{
return "com.android.providers.downloads.documents".equals(uri.getAuthority());
}
/**
* @param uri - The Uri to check.
* @return - Whether the Uri authority is MediaProvider.
*/
private static boolean isMediaDocument(Uri uri)
{
return "com.android.providers.media.documents".equals(uri.getAuthority());
}
/**
* @param uri - The Uri to check.
* @return - Whether the Uri authority is Google Photos.
*/
private static boolean isGooglePhotosUri(Uri uri)
{
return "com.google.android.apps.photos.content".equals(uri.getAuthority());
}
}
package com.example.audiovisualrecord.base;
/**
* Created by 5*N on 2017/12/22
*/
public interface BaseAttacher<V extends BaseView> {
void onAttached(V view);
void onDetached();
}
package com.example.audiovisualrecord.base;
import android.app.ProgressDialog;
import android.content.ContentUris;
import android.content.Context;
import android.content.DialogInterface;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.annotation.StringRes;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment;
import com.example.audiovisualrecord.utils.ToastCreator;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.List;
/**
* Created by 5*N on 2018/1/12
*/
public abstract class BaseFragment extends Fragment implements BaseView {
private ProgressDialog mProgressDialog;
private Calendar mCalendar = Calendar.getInstance();
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public void showProgressDialog(@StringRes int text) {
dismissProgressDialog();
mProgressDialog = new ProgressDialog(getActivity());
mProgressDialog.setMessage(getActivity().getResources().getString(text));
mProgressDialog.setCancelable(false);
mProgressDialog.setCanceledOnTouchOutside(false);
mProgressDialog.show();
}
@Override
public void dismissProgressDialog() {
if (mProgressDialog != null && mProgressDialog.isShowing()) {
mProgressDialog.cancel();
}
}
@Override
public String getResourceString(@StringRes int text) {
return getResources().getString(text);
}
@Override
public String getTodayTime() {
String dateformat = "yyyyMMdd";
Calendar mCal = Calendar.getInstance();
SimpleDateFormat df = new SimpleDateFormat(dateformat);
String today = df.format(mCal.getTime());
return today;
}
@Override
public void showToast(@StringRes int text) {
ToastCreator.makeText(getActivity(), text, Toast.LENGTH_SHORT);
}
@Override
public void showToast(String text) {
ToastCreator.makeText(getActivity(), text, Toast.LENGTH_SHORT);
}
@Override
public void showItemDialog(List<String> list, DialogInterface.OnClickListener onClickListener) {
new AlertDialog.Builder(getActivity())
.setItems(list.toArray(new String[list.size()]), onClickListener)
.create()
.show();
}
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
@Override
public String getPath(Uri uri) {
// check here to KITKAT or new version
final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
// DocumentProvider
if (isKitKat && DocumentsContract.isDocumentUri(getActivity(), uri))
{
// ExternalStorageProvider
if (isExternalStorageDocument(uri))
{
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
if ("primary".equalsIgnoreCase(type))
{
return Environment.getExternalStorageDirectory() + "/"
+ split[1];
}
}
// DownloadsProvider
else if (isDownloadsDocument(uri))
{
final String id = DocumentsContract.getDocumentId(uri);
final Uri contentUri = ContentUris.withAppendedId(
Uri.parse("content://downloads/public_downloads"),
Long.valueOf(id));
return getDataColumn(getActivity(), contentUri, null, null);
}
// MediaProvider
else if (isMediaDocument(uri))
{
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
Uri contentUri = null;
if ("image".equals(type))
{
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
}
else if ("video".equals(type))
{
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
}
else if ("audio".equals(type))
{
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
}
final String selection = "_id=?";
final String[] selectionArgs = new String[] { split[1] };
return getDataColumn(getActivity(), contentUri, selection,
selectionArgs);
}
}
// MediaStore (and general)
else if ("content".equalsIgnoreCase(uri.getScheme()))
{
// Return the remote address
if (isGooglePhotosUri(uri))
return uri.getLastPathSegment();
return getDataColumn(getActivity(), uri, null, null);
}
// File
else if ("file".equalsIgnoreCase(uri.getScheme()))
{
return uri.getPath();
}
return null;
}
/**
* Get the value of the data column for this Uri. This is useful for
* MediaStore Uris, and other file-based ContentProviders.
*
* @param context - The context.
* @param uri - The Uri to query.
* @param selection - (Optional) Filter used in the query.
* @param selectionArgs - (Optional) Selection arguments used in the query.
* @return - The value of the _data column, which is typically a file path.
*/
private static String getDataColumn(Context context, Uri uri,
String selection, String[] selectionArgs)
{
Cursor cursor = null;
final String column = "_data";
final String[] projection = { column };
try
{
cursor = context.getContentResolver().query(uri, projection,
selection, selectionArgs, null);
if (cursor != null && cursor.moveToFirst())
{
final int index = cursor.getColumnIndexOrThrow(column);
return cursor.getString(index);
}
}
finally
{
if (cursor != null)
cursor.close();
}
return null;
}
/**
* @param uri - The Uri to check.
* @return - Whether the Uri authority is ExternalStorageProvider.
*/
private static boolean isExternalStorageDocument(Uri uri)
{
return "com.android.externalstorage.documents".equals(uri.getAuthority());
}
/**
* @param uri - The Uri to check.
* @return - Whether the Uri authority is DownloadsProvider.
*/
private static boolean isDownloadsDocument(Uri uri)
{
return "com.android.providers.downloads.documents".equals(uri.getAuthority());
}
/**
* @param uri - The Uri to check.
* @return - Whether the Uri authority is MediaProvider.
*/
private static boolean isMediaDocument(Uri uri)
{
return "com.android.providers.media.documents".equals(uri.getAuthority());
}
/**
* @param uri - The Uri to check.
* @return - Whether the Uri authority is Google Photos.
*/
private static boolean isGooglePhotosUri(Uri uri)
{
return "com.google.android.apps.photos.content".equals(uri.getAuthority());
}
}
package com.example.audiovisualrecord.base;
import com.example.audiovisualrecord.utils.api.ApiService;
import com.example.audiovisualrecord.utils.api.ErpAPI;
import com.example.audiovisualrecord.utils.rxjava.SchedulerProvider;
import io.reactivex.disposables.CompositeDisposable;
public class BasePresenter<V extends BaseView> implements BaseAttacher<V> {
private V mView;
private ApiService api;
private ErpAPI erpAPI;
private SchedulerProvider schedulerProvider;
private CompositeDisposable compositeDisposable;
public BasePresenter(ApiService api,
ErpAPI erpAPI,
SchedulerProvider schedulerProvider,
CompositeDisposable compositeDisposable) {
this.api = api;
this.erpAPI=erpAPI;
this.schedulerProvider = schedulerProvider;
this.compositeDisposable = compositeDisposable;
}
public V getView() {
return mView;
}
@Override
public void onAttached(V view) {
mView = view;
}
@Override
public void onDetached() {
mView = null;
}
public ApiService getApiService() {
return api;
}
// public ErpAPI getErpAPI(){
// return erpAPI;
// }
public SchedulerProvider getSchedulerProvider() {
return schedulerProvider;
}
public CompositeDisposable getCompositeDisposable() {
return compositeDisposable;
}
}
package com.example.audiovisualrecord.base;
import android.app.DatePickerDialog;
import android.content.DialogInterface;
import android.net.Uri;
import androidx.annotation.StringRes;
import java.util.List;
/**
* Created by 5*N on 2017/12/22
*/
public interface BaseView {
void init();
void showItemDialog(List<String> list, DialogInterface.OnClickListener onClickListener);
void showProgressDialog(@StringRes int text);
void showProgressDialog(String text);
void dismissProgressDialog();
void showDialogCaveatMessage(String message);
void showDialogMessage(String message);
void showDialogMessage(String title, String message);
void showDialogCaveatMessage(String title, String message);
void showDatePickerDialog(DatePickerDialog.OnDateSetListener onDateSetListener);
void showSelectDialog(String text, DialogInterface.OnClickListener onClickListener);
String getResourceString(@StringRes int text);
String getTodayTime();
void showToast(String text);
void showToast(@StringRes int text);
String getPath(Uri uri);
}
package com.example.audiovisualrecord.ui.chooseitem;
import java.io.Serializable;
public class ChooseDeviceItemData implements Serializable {
private String recordDate="";
private String factoryAreaName ="";
// private String maintenancePlantCompanyId="";
private String factoryAreaId ="";
private String company="";
private String companyId="";
private String productionPlantId="";
private String factoryClassCode ="";
private String factoryClass ="";
private String deviceCategory="";
private String deviceCategryId="";
private String shootType ="";
private String deciceId="";
private String deciceName="";
private String keynote="";
private String filePath="";
private String uploadEmployees="";
private boolean backgroundChange=false;
private boolean checkEndItem=false;
// public String getMaintenancePlantCompanyId() {
// return maintenancePlantCompanyId;
// }
//
// public void setMaintenancePlantCompanyId(String maintenancePlantCompanyId) {
// this.maintenancePlantCompanyId = maintenancePlantCompanyId;
// }
public String getFactoryAreaId() {
return factoryAreaId;
}
public void setFactoryAreaId(String factoryAreaId) {
this.factoryAreaId = factoryAreaId;
}
public String getCompany() {
return company;
}
public void setCompany(String company) {
this.company = company;
}
public String getCompanyId() {
return companyId;
}
public void setCompanyId(String companyId) {
this.companyId = companyId;
}
public String getProductionPlantId() {
return productionPlantId;
}
public void setProductionPlantId(String productionPlantId) {
this.productionPlantId = productionPlantId;
}
public String getShootType() {
return shootType;
}
public void setShootType(String shootType) {
this.shootType = shootType;
}
public String getDeviceCategryId() {
return deviceCategryId;
}
public void setDeviceCategryId(String deviceCategryId) {
this.deviceCategryId = deviceCategryId;
}
public String getDeciceName() {
return deciceName;
}
public void setDeciceName(String deciceName) {
this.deciceName = deciceName;
}
public boolean isBackgroundChange() {
return backgroundChange;
}
public String getRecordDate() {
return recordDate;
}
public void setRecordDate(String recordDate) {
this.recordDate = recordDate;
}
public String getFactoryAreaName() {
return factoryAreaName;
}
public void setFactoryAreaName(String factoryAreaName) {
this.factoryAreaName = factoryAreaName;
}
public String getFactoryClassCode() {
return factoryClassCode;
}
public void setFactoryClassCode(String factoryClassCode) {
this.factoryClassCode = factoryClassCode;
}
public String getFactoryClass() {
return factoryClass;
}
public void setFactoryClass(String factoryClass) {
this.factoryClass = factoryClass;
}
public String getDeviceCategory() {
return deviceCategory;
}
public void setDeviceCategory(String deviceCategory) {
this.deviceCategory = deviceCategory;
}
public String getDeciceId() {
return deciceId;
}
public void setDeciceId(String deciceId) {
this.deciceId = deciceId;
}
public String getKeynote() {
return keynote;
}
public void setKeynote(String keynote) {
this.keynote = keynote;
}
public String getFilePath() {
return filePath;
}
public void setFilePath(String filePath) {
this.filePath = filePath;
}
public String getUploadEmployees() {
return uploadEmployees;
}
public void setUploadEmployees(String uploadEmployees) {
this.uploadEmployees = uploadEmployees;
}
public boolean getBackgroundChange() {
return backgroundChange;
}
public void setBackgroundChange(boolean backgroundChange) {
this.backgroundChange = backgroundChange;
}
public boolean isCheckEndItem() {
return checkEndItem;
}
public void setCheckEndItem(boolean checkEndItem) {
this.checkEndItem = checkEndItem;
}
}
package com.example.audiovisualrecord.ui.login;
import android.Manifest;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import com.example.audiovisualrecord.ui.main.MainActivity;
import com.example.audiovisualrecord.R;
import com.example.audiovisualrecord.base.BaseActivity;
public class LoginActivity extends BaseActivity implements LoginContract.View, View.OnClickListener {
EditText editAccount, editPassword;
Button btnLogin;
private LoginPresenter presenter;
// LoginContract.Presenter<LoginContract.View> mPresenter = new LoginContract.Presenter<LoginContract.View>;
private static final int REQUEST_PERMISSIONS_CODE = 20200410;
private String[] permissions = {
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.CAMERA};
@RequiresApi(api = Build.VERSION_CODES.M)
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.login);
init();
requestPermissions(permissions, REQUEST_PERMISSIONS_CODE);
presenter = new LoginPresenter(this);
}
@Override
public void init() {
editAccount = findViewById(R.id.edit_account);
editPassword = findViewById(R.id.edit_password);
btnLogin = findViewById(R.id.btn_login);
btnLogin.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_login:
// showProgressDialog("登入中");
// new Thread(){
// public void run(){
// try{
// sleep(5000);
// presenter.onLogin("", "");
// dismissProgressDialog();
// }
// catch(Exception e){
// e.printStackTrace();
// }
// finally{
// dismissProgressDialog();
// }
// }
// }.start();
presenter.onLogin("", "");
break;
}
}
private boolean onCheckUserisEmpty() {
if ("".equals(editAccount.getText().toString())) {
showDialogMessage(getResourceString(R.string.login_account_hint));
return false;
}
if ("".equals(editPassword.getText().toString())) {
showDialogMessage(getResourceString(R.string.login_password_hint));
return false;
}
return true;
}
@Override
public void onCompleteLogin(String token) {
Intent intent = new Intent(this, MainActivity.class);
Bundle bag = new Bundle();
bag.putString("token", token);
intent.putExtras(bag);
startActivity(intent);
}
}
package com.example.audiovisualrecord.ui.login;
import com.example.audiovisualrecord.base.BaseAttacher;
import com.example.audiovisualrecord.base.BaseView;
public interface LoginContract {
interface View extends BaseView {
void onCompleteLogin(String token);
}
interface Presenter<V extends View> extends BaseAttacher<V> {
void onLogin(String account,String password);
}
}
package com.example.audiovisualrecord.ui.login;
import android.content.Context;
import android.util.Log;
import com.example.audiovisualrecord.R;
import com.example.audiovisualrecord.utils.api.ApiService;
import com.example.audiovisualrecord.utils.api.HttpMethods;
import com.example.audiovisualrecord.utils.api.apidata.login.LoginRequest;
import com.example.audiovisualrecord.utils.api.apidata.login.LoginResponse;
import com.example.audiovisualrecord.utils.rxjava.SchedulerProvider;
import com.example.audiovisualrecord.utils.rxjava.SchedulerProviderImp;
import com.example.audiovisualrecord.utils.sharepreferences.LoginPreferences;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.observers.DisposableObserver;
public class LoginPresenter<V extends LoginContract.View> implements LoginContract.Presenter<V> {
// LoginPreferences loginPreferences;
private V view;
private String LOGIN_AUTHORIZED_ID = "06cdae9b-fa20-497d-8207-0eb73582623b";
private ApiService api;
SchedulerProviderImp schedulerProviderImp = new SchedulerProviderImp();
private CompositeDisposable compositeDisposable;
public LoginPresenter(V view) {
this.view = view;
api = HttpMethods.getInstance().getApi();
// loginPreferences = new LoginPreferences(context);
compositeDisposable = new CompositeDisposable();
}
@Override
public void onLogin(String account, String password) {
String url = view.getResourceString(R.string.api_on_Login);
LoginRequest mLoginRequest = new LoginRequest(LOGIN_AUTHORIZED_ID, "N000158385", "781122222");
compositeDisposable.add(api.onLogin(url, mLoginRequest)
.subscribeOn(schedulerProviderImp.io())
.observeOn(schedulerProviderImp.ui())
.subscribeWith(new DisposableObserver<LoginResponse>() {
@Override
public void onNext(LoginResponse loginResponse) {
Log.e("next", loginResponse.getmMsg());
if ("True".equals(loginResponse.getmResult())) {
// loginPreferences.setToken(loginResponse.getmToken());
view.onCompleteLogin(loginResponse.getmMsg());
} else {
view.showDialogCaveatMessage("登入失敗");
}
}
@Override
public void onError(Throwable e) {
Log.e("err", e.getMessage());
view.showDialogCaveatMessage("登入失敗");
}
@Override
public void onComplete() {
Log.e("com", "asdasd");
}
})
);
}
@Override
public void onAttached(V view) {
}
@Override
public void onDetached() {
}
}
package com.example.audiovisualrecord.ui.main;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.core.content.FileProvider;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import com.example.audiovisualrecord.FileUtil;
import com.example.audiovisualrecord.MagicFileChooser;
import com.example.audiovisualrecord.R;
import com.example.audiovisualrecord.base.BaseActivity;
import com.example.audiovisualrecord.ui.chooseitem.ChooseDeviceItemData;
import com.example.audiovisualrecord.utils.api.apidata.CORequest.COResponse;
import com.example.audiovisualrecord.utils.api.apidata.searchtype.TYPEResponse;
import com.example.audiovisualrecord.utils.api.searcheqkd.EQKDResponse;
import com.example.audiovisualrecord.utils.api.searchmntfct.MNTFCTResponse;
import com.example.audiovisualrecord.utils.api.searchpmfct.PMFCTResponse;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
public class MainActivity extends BaseActivity implements MainContract.View,View.OnClickListener {
private static final int REQUEST_CAPTURE_IMAGE = 100;
private static final int REQUEST_VIDEO_CAPTURE = 200;
private static final int PICK_IMAGE_FROM_GALLERY_REQUEST_CODE = 300;
private static final int PICK_VIDEO_FROM_GALLERY_REQUEST_CODE = 400;
private static final int PICK_FILE_REQUEST_CODE = 500;
private Button btnCapturePicture, btnRecordVideo, btnGetImageFromGallery, btnGetVideoFromGallery, btnDeviceEdit, btnCentralCloud, btnChoseDevice,btnBasicInformation;
private File photoFile;
// Bundle bag;
String token,imageFilePath;
int countFile = 0;
TextView tvCompany,tvFactory,tvClass,tvUnit,tvShootType;
private MainPresenter mPresenter;
private MainData mMainData;
private ChooseDeviceItemData mChooseDeviceItemData;
private ArrayList<String> dialogString = new ArrayList<>();
private List<String> filepath = new ArrayList<>();
private List<String> filename = new ArrayList<>();
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// bag = getIntent().getExtras();
// token = bag.getString("token");
init();
mPresenter = new MainPresenter(this);
mMainData = new MainData();
mChooseDeviceItemData = new ChooseDeviceItemData();
}
@Override
public void init() {
btnCapturePicture = findViewById(R.id.btnCaptureImage);
btnGetImageFromGallery = findViewById(R.id.btnGetImageFromGallery);
btnGetVideoFromGallery = findViewById(R.id.btnGetVideoFromGallery);
btnRecordVideo = findViewById(R.id.btnRecordVideo);
btnCapturePicture.setOnClickListener(this);
btnGetImageFromGallery.setOnClickListener(this);
btnGetVideoFromGallery.setOnClickListener(this);
btnRecordVideo.setOnClickListener(this);
tvCompany = findViewById(R.id.tv_company);
tvFactory = findViewById(R.id.tv_factory);
tvUnit = findViewById(R.id.tv_unit);
tvClass = findViewById(R.id.tv_class);
tvShootType = findViewById(R.id.tv_shoottype);
tvCompany.setOnClickListener(this);
tvFactory.setOnClickListener(this);
tvUnit.setOnClickListener(this);
tvClass.setOnClickListener(this);
tvShootType.setOnClickListener(this);
}
private void pickImageFromGallery() {
//Create an Intent with action as ACTION_PICK
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
// Sets the type as image/*. This ensures only components of type image are selected
intent.setType("image/*");
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
//We pass an extra array with the accepted mime types. This will ensure only components with these MIME types as targeted.
String[] mimeTypes = {"image/jpeg", "image/png"};
intent.putExtra(Intent.EXTRA_MIME_TYPES, mimeTypes);
// Launching the Intent
startActivityForResult(intent, PICK_IMAGE_FROM_GALLERY_REQUEST_CODE);
}
private void pickVideoFromGallery() {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("video/*");
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
String[] mimeTypes = {"video/mp4", "video/mov"};
intent.putExtra(Intent.EXTRA_MIME_TYPES, mimeTypes);
startActivityForResult(intent, PICK_VIDEO_FROM_GALLERY_REQUEST_CODE);
}
private void openCameraIntent() {
Intent pictureIntent = new Intent(
MediaStore.ACTION_IMAGE_CAPTURE);
settingSystemCamera(pictureIntent);
if (pictureIntent.resolveActivity(getPackageManager()) != null) {
//Create a file to store the image
photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException ex) {
// Error occurred while creating the File
}
if (photoFile != null) {
Uri photoURI = FileProvider.getUriForFile(this, "com.example.audiovisualrecord.provider", photoFile);
pictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
photoURI);
startActivityForResult(pictureIntent,
REQUEST_CAPTURE_IMAGE);
}
}
}
private void openRecordVideoIntent() {
Intent takeVideoIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
PackageManager packageManager = this.getPackageManager();
List<ResolveInfo> listCam = packageManager.queryIntentActivities(takeVideoIntent, 0);
takeVideoIntent.setPackage(listCam.get(0).activityInfo.packageName);
takeVideoIntent.putExtra(MediaStore.EXTRA_SIZE_LIMIT, 10996480L);
if (takeVideoIntent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(takeVideoIntent, REQUEST_VIDEO_CAPTURE);
}
}
private File createImageFile() throws IOException {
String timeStamp =
new SimpleDateFormat("yyyyMMdd_HHmmss",
Locale.getDefault()).format(new Date());
String imageFileName = "IMG_" + timeStamp + "_";
File storageDir =
getExternalFilesDir(Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
imageFilePath = image.getAbsolutePath();
return image;
}
private void settingSystemCamera(Intent intent) {
PackageManager packageManager = MainActivity.this.getPackageManager();
List<ResolveInfo> listCam = packageManager.queryIntentActivities(intent, 0);
intent.setPackage(listCam.get(0).activityInfo.packageName);
}
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CAPTURE_IMAGE && resultCode == RESULT_OK) {
File imgFile = new File(imageFilePath);
//照片的檔案
if (imgFile.exists()) {
Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
try {
FileOutputStream out = new FileOutputStream(imgFile);
myBitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
if (requestCode == REQUEST_VIDEO_CAPTURE && resultCode == RESULT_OK) {
//影片的uri
Uri videoUri = data.getData();
}
if (requestCode == PICK_IMAGE_FROM_GALLERY_REQUEST_CODE && resultCode == RESULT_OK) {
ArrayList<String> uriList = new ArrayList<String>();
if (data.getClipData() != null){
for (int i = 0; i < data.getClipData().getItemCount(); i++) {
uriList.add(getPath(data.getClipData().getItemAt(i).getUri()));
Log.e("gggg", "" + uriList.get(i));
}
}
else if (Build.VERSION.SDK_INT>=16 && data.getClipData()== null){
uriList.add(getPath(data.getData()));
Log.e("eee",getPath(data.getData()));
}
//照片的uri
// onUploadFile(uriList, getResourceString(R.string.on_upload_image));
}
if (requestCode == PICK_VIDEO_FROM_GALLERY_REQUEST_CODE && resultCode == RESULT_OK) {
ArrayList<String> uriList = new ArrayList<String>();
if (data.getClipData() != null) {
Uri selectedVideo = data.getClipData().getItemAt(0).getUri();
int count = data.getClipData().getItemCount();
//count 選取檔案的數量
for (int i = 0; i < count; i++) {
uriList.add(getPath(data.getClipData().getItemAt(i).getUri()));
filename.add(FileUtil.fileName(getPath(data.getClipData().getItemAt(i).getUri())));
Log.e("gggg", "" + uriList.get(i));
Log.e("dddd",""+filename.get(i));
mPresenter.segVideo(uriList.get(i),filename.get(i));
}
Log.e("aaa",count+"");
} else if (Build.VERSION.SDK_INT >= 16 && data.getClipData() == null) {
uriList.clear();
String path = FileUtil.getFileAbsolutePath(this, data.getData());
String name =FileUtil.fileName(path);
mPresenter.segVideo(path,name);
// TODO here====================
// onUploadFile(compressList, getResourceString(R.string.on_upload_vedio));
//影片的uri
}
}
if (requestCode == PICK_FILE_REQUEST_CODE && resultCode == RESULT_OK) {
Uri selectedFile = data.getData();
Log.e("ggggg", "" + selectedFile);
String filePath = MagicFileChooser.getAbsolutePathFromUri(this, selectedFile);
Log.e("filePath", filePath + "");
checkFileTypeAndOpen(filePath, selectedFile);
}
}
//根據副檔名判斷用什麼應用程式開啟
private void checkFileTypeAndOpen(String filePath, Uri selectedFile) {
final Intent intent = new Intent(Intent.ACTION_VIEW);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
if (filePath.contains(".doc")) {
intent.setDataAndType(selectedFile, "application/msword");
} else if (filePath.contains(".ppt")) {
intent.setDataAndType(selectedFile, "application/vnd.ms-powerpoint");
} else if ((filePath.contains(".csv")) || (filePath.contains(".xls"))) {
intent.setDataAndType(selectedFile, "application/vnd.ms-excel");
} else if (filePath.contains(".pdf")) {
intent.setDataAndType(selectedFile, "application/pdf");
} else if (filePath.contains(".txt")) {
intent.setDataAndType(selectedFile, "text/plain");
} else {
intent.setDataAndType(selectedFile, "application/*");
}
PackageManager pm = getPackageManager();
List<ResolveInfo> list = pm.queryIntentActivities(intent, 0);
if (list.size() > 0)
startActivity(intent);
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.btnCaptureImage:
openCameraIntent();
break;
case R.id.btnGetImageFromGallery:
pickImageFromGallery();
break;
case R.id.btnGetVideoFromGallery:
pickVideoFromGallery();
break;
case R.id.btnRecordVideo:
openRecordVideoIntent();
break;
case R.id.tv_company:
mPresenter.onGetComData();
break;
case R.id.tv_factory:
mPresenter.onGetPZData();
break;
case R.id.tv_unit:
if (mChooseDeviceItemData.getFactoryAreaId().equals("")){
showDialogCaveatMessage(getResourceString(R.string.add_device_no_maintenance_plant_error));
}
if(mChooseDeviceItemData.getCompanyId().equals("")){
showDialogCaveatMessage(getResourceString(R.string.add_device_no_company_error));
}
mPresenter.onGetDPData(mChooseDeviceItemData.getCompanyId(),mChooseDeviceItemData.getFactoryAreaId());
break;
case R.id.tv_class:
if (mChooseDeviceItemData.getCompanyId().equals("")){
showDialogCaveatMessage(getResourceString(R.string.add_device_no_company_error));
}
if (mChooseDeviceItemData.getProductionPlantId().equals("")){
showDialogCaveatMessage(getResourceString(R.string.add_device_no_production_plant_error));
}
mPresenter.onGetSHIFTData(mChooseDeviceItemData.getCompanyId(),mChooseDeviceItemData.getProductionPlantId());
break;
case R.id.tv_shoottype:
if (mChooseDeviceItemData.getCompanyId().equals("")){
showDialogCaveatMessage(getResourceString(R.string.add_device_no_company_error));
}
if (mChooseDeviceItemData.getProductionPlantId().equals("")){
showDialogCaveatMessage(getResourceString(R.string.add_device_no_production_plant_error));
}
mPresenter.onGetTYPEData(mChooseDeviceItemData.getCompanyId(),mChooseDeviceItemData.getProductionPlantId()
);
break;
}
}
//如果能改成用retrofit加rxjava最好,已經嘗試過三天的,可能有缺什麼,不過緊急所以先求功能
private void onUploadFile(final ArrayList<String> uriList, String type) {
showProgressDialog(type);
new Thread(new Runnable() {
@Override
public void run() {
OkHttpClient client = new OkHttpClient().newBuilder()
.build();
MediaType mediaType = MediaType.parse("text/plain");
MultipartBody.Builder buildernew = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("AuthorizedId", "1179cf63-9f4c-4060-a0f3-201f108b20c1")
.addFormDataPart("CO", "1")
.addFormDataPart("CONM", "台塑")
.addFormDataPart("PMFCT", "A3")
.addFormDataPart("PMFCTNM", "麥寮AN廠")
.addFormDataPart("EQKD", "PU")
.addFormDataPart("EQKDNM", "泵浦")
.addFormDataPart("EQNO", "P-166")
.addFormDataPart("EQNM", "工業用水泵浦")
.addFormDataPart("RecordDate", "2020/04/06")
.addFormDataPart("RecordSubject", "測試")
.addFormDataPart("UploadEMP", "1")
.addFormDataPart("UploadNM", "新人")
.addFormDataPart("UploadDATETM", "");
for (String path : uriList) {
File uploadFile = new File(path);
buildernew.addFormDataPart("", uploadFile.getName(),
RequestBody.create(MediaType.parse("application/octet-stream"),
uploadFile));
}
RequestBody body = buildernew.build();
Request request = new Request.Builder()
.url("https://cloud.fpcetg.com.tw/FPC/API/MTN/API_MTN/MTN/Upload")
.method("POST", body)
.build();
try {
Response response = client.newCall(request).execute();
Log.e("response", response.body().string());
dismissProgressDialog();
// Log.e("isSuccess",json.get("IsSuccess").toString());
} catch (IOException e) {
e.printStackTrace();
dismissProgressDialog();
showDialogCaveatMessage("上傳失敗");
Log.e("error", "" + e.getMessage());
}
}
}).start();
}
@Override
public void setCOData(List<COResponse> adapterData) {
dialogString.clear();
mMainData.setmCODataList(adapterData);
for (COResponse mCoResponse: adapterData){
dialogString.add(mCoResponse.getcONM());
}
showItemDialog(dialogString,onCompanyDialogItemClick);
}
@Override
public void setPZData(List<MNTFCTResponse> adapterData) {
dialogString.clear();
mMainData.setmMNTFCTDataList(adapterData);
for(MNTFCTResponse mMNTFCTResponse: adapterData){
dialogString.add(mMNTFCTResponse.getmPZNM());
}
showItemDialog(dialogString,onMaintenanceDialogItemClick);
}
@Override
public void setDPNMData(List<PMFCTResponse> adapterData) {
dialogString.clear();
mMainData.setmPMFCTDataList(adapterData);
for(PMFCTResponse mPMFCTResponse: adapterData){
dialogString.add(mPMFCTResponse.getmDPNM());
}
showItemDialog(dialogString,onProductionDialogItemClick);
}
@Override
public void setEQKDData(List<EQKDResponse> adapterData) {
dialogString.clear();
mMainData.setmEQKDDataList(adapterData);
for(EQKDResponse mEQKDResponse: adapterData){
dialogString.add(mEQKDResponse.getmShift());
}
showItemDialog(dialogString,onDeviceCategoryDialogItemClick);
}
@Override
public void setTYPEData(List<TYPEResponse> adapterData) {
dialogString.clear();
mMainData.setmTYPEDataList(adapterData);
for(TYPEResponse mTYPEResponse: adapterData){
dialogString.add(mTYPEResponse.getmType());
}
showItemDialog(dialogString,onShootTypeCategoryDialogItemClick);
}
private DialogInterface.OnClickListener onCompanyDialogItemClick = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
tvCompany.setText(mMainData.getmCODataList().get(which).getcONM());
mChooseDeviceItemData.setCompany(mMainData.getmCODataList().get(which).getcONM());
mChooseDeviceItemData.setCompanyId(mMainData.getmCODataList().get(which).getcO());
}
};
private DialogInterface.OnClickListener onMaintenanceDialogItemClick = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
tvFactory.setText(mMainData.getmMNTFCTDataList().get(which).getmPZNM());
mChooseDeviceItemData.setFactoryAreaName(mMainData.getmMNTFCTDataList().get(which).getmPZNM());
// mChooseDeviceItemData.setMaintenancePlantCompanyId(mMainData.getmMNTFCTDataList().get(which).getmPZ());
mChooseDeviceItemData.setFactoryAreaId(mMainData.getmMNTFCTDataList().get(which).getmPZ());
}
};
private DialogInterface.OnClickListener onProductionDialogItemClick = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
tvUnit.setText(mMainData.getmPMFCTDataList().get(which).getmDPNM());
mChooseDeviceItemData.setFactoryClassCode(mMainData.getmPMFCTDataList().get(which).getmDP());
mChooseDeviceItemData.setFactoryClass(mMainData.getmPMFCTDataList().get(which).getmDPNM());
mChooseDeviceItemData.setProductionPlantId(mMainData.getmPMFCTDataList().get(which).getmPMFCT());
}
};
private DialogInterface.OnClickListener onDeviceCategoryDialogItemClick = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
tvClass.setText(mMainData.getmEQKDDataList().get(which).getmShift());
mChooseDeviceItemData.setDeviceCategory(mMainData.getmEQKDDataList().get(which).getmShift());
// mChooseDeviceItemData.setDeviceCategryId(mMainData.getmEQKDDataList().get(which).getmEQKD());
}
};
private DialogInterface.OnClickListener onShootTypeCategoryDialogItemClick = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
tvShootType.setText(mMainData.getmTYPEDataList().get(which).getmType());
mChooseDeviceItemData.setShootType(mMainData.getmTYPEDataList().get(which).getmType());
}
};
}
package com.example.audiovisualrecord.ui.main;
import com.example.audiovisualrecord.base.BaseView;
import com.example.audiovisualrecord.utils.api.apidata.CORequest.COResponse;
import com.example.audiovisualrecord.utils.api.apidata.searchtype.TYPEResponse;
import com.example.audiovisualrecord.utils.api.searcheqkd.EQKDResponse;
import com.example.audiovisualrecord.utils.api.searchmntfct.MNTFCTResponse;
import com.example.audiovisualrecord.utils.api.searchpmfct.PMFCTResponse;
import java.util.List;
public interface MainContract {
interface View extends BaseView {
void setCOData(List<COResponse> adapterData);
void setPZData(List<MNTFCTResponse> adapterData);
void setDPNMData(List<PMFCTResponse> adapterData);
void setEQKDData(List<EQKDResponse> adapterData);
void setTYPEData(List<TYPEResponse> adapterData);
}
interface Presenter<V extends MainContract.View> {
// void onGetDisposableToken(String DeviceId);
void onGetComData();
void onGetPZData();
void onGetDPData(String CO, String PZ);
void onGetSHIFTData(String CO, String PMFCT);
void segVideo(String path,String name);
void onGetTYPEData(String CO,String PMFCT);
}
}
package com.example.audiovisualrecord.ui.main;
import com.example.audiovisualrecord.utils.api.apidata.CORequest.COResponse;
import com.example.audiovisualrecord.utils.api.apidata.searchtype.TYPEResponse;
import com.example.audiovisualrecord.utils.api.searcheqkd.EQKDResponse;
import com.example.audiovisualrecord.utils.api.searchmntfct.MNTFCTResponse;
import com.example.audiovisualrecord.utils.api.searchpmfct.PMFCTResponse;
import java.util.List;
public class MainData {
// private String mMNTCO="";//保養公司代碼
// private String mMNTFCT="";//保養廠代碼
// private String mCO="";//公司代碼
// private String mPMFCT="";//生產廠代碼
// private String mPMFCTNM="";//生產廠代碼
// private String mEQKD="";//設備類別代碼
// private String mEQKDNM="";//設備類別名稱
// private String mEQNO="";//設備編號
// private String mEQNM="";//設備名稱
// private String mNTCO="";//保養公司代碼
private List<COResponse> mCODataList;
private List<MNTFCTResponse> mMNTFCTDataList;
private List<PMFCTResponse> mPMFCTDataList;
private List<EQKDResponse> mEQKDDataList;
private List<TYPEResponse> mTYPEDataList;
public List<COResponse> getmCODataList() {
return mCODataList;
}
public List<MNTFCTResponse> getmMNTFCTDataList() {
return mMNTFCTDataList;
}
public void setmMNTFCTDataList(List<MNTFCTResponse> mMNTFCTDataList) {
this.mMNTFCTDataList = mMNTFCTDataList;
}
public void setmCODataList(List<COResponse> mCODataList) {
this.mCODataList = mCODataList;
}
public List<PMFCTResponse> getmPMFCTDataList() {
return mPMFCTDataList;
}
public void setmPMFCTDataList(List<PMFCTResponse> mPMFCTDataList) {
this.mPMFCTDataList = mPMFCTDataList;
}
public List<EQKDResponse> getmEQKDDataList() {
return mEQKDDataList;
}
public void setmEQKDDataList(List<EQKDResponse> mEQKDDataList) {
this.mEQKDDataList = mEQKDDataList;
}
public List<TYPEResponse> getmTYPEDataList() {
return mTYPEDataList;
}
public void setmTYPEDataList(List<TYPEResponse> mTYPEDataList) {
this.mTYPEDataList = mTYPEDataList;
}
// public String getmCO() {
// return mMNTCO;
// }
//
// public void setmCO(String mMNTCO) {
// this.mMNTCO = mMNTCO;
// }
//
// public String getmPZ() {
// return mMNTFCT;
// }
//
// public void setmPZ(String mMNTFCT) {
// this.mMNTFCT = mMNTFCT;
// }
//
// public String getmCO() {
// return mCO;
// }
//
// public void setmCO(String mCO) {
// this.mCO = mCO;
// }
//
// public String getmPMFCT() {
// return mPMFCT;
// }
//
// public void setmPMFCT(String mPMFCT) {
// this.mPMFCT = mPMFCT;
// }
//
// public String getmDPNM() {
// return mPMFCTNM;
// }
//
// public void setmDPNM(String mPMFCTNM) {
// this.mPMFCTNM = mPMFCTNM;
// }
//
// public String getmEQKD() {
// return mEQKD;
// }
//
// public void setmEQKD(String mEQKD) {
// this.mEQKD = mEQKD;
// }
//
// public String getmEQKDNM() {
// return mEQKDNM;
// }
//
// public void setmEQKDNM(String mEQKDNM) {
// this.mEQKDNM = mEQKDNM;
// }
//
// public String getmEQNO() {
// return mEQNO;
// }
//
// public void setmEQNO(String mEQNO) {
// this.mEQNO = mEQNO;
// }
//
// public String getmEQNM() {
// return mEQNM;
// }
//
// public void setmEQNM(String mEQNM) {
// this.mEQNM = mEQNM;
// }
//
// public String getmPZ() {
// return mNTCO;
// }
//
// public void setmPZ(String mNTCO) {
// this.mNTCO = mNTCO;
// }
}
package com.example.audiovisualrecord.ui.main;
import android.os.Environment;
import android.text.LoginFilter;
import android.util.Log;
import com.arthenica.mobileffmpeg.Config;
import com.arthenica.mobileffmpeg.FFmpeg;
import com.arthenica.mobileffmpeg.FFprobe;
import com.example.audiovisualrecord.R;
import com.example.audiovisualrecord.utils.api.ApiService;
import com.example.audiovisualrecord.utils.api.HttpMethods;
import com.example.audiovisualrecord.utils.api.apidata.CORequest.CORequest;
import com.example.audiovisualrecord.utils.api.apidata.CORequest.COResultList;
import com.example.audiovisualrecord.utils.api.apidata.searchtype.TYPERequest;
import com.example.audiovisualrecord.utils.api.apidata.searchtype.TYPEResultList;
import com.example.audiovisualrecord.utils.api.searcheqkd.EQKDRequest;
import com.example.audiovisualrecord.utils.api.searcheqkd.EQKDResultList;
import com.example.audiovisualrecord.utils.api.searchmntfct.MNTFCTRequest;
import com.example.audiovisualrecord.utils.api.searchmntfct.MNTFCTResultList;
import com.example.audiovisualrecord.utils.api.searchpmfct.PMFCTRequest;
import com.example.audiovisualrecord.utils.api.searchpmfct.PMFCTResultList;
import com.example.audiovisualrecord.utils.rxjava.SchedulerProviderImp;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.observers.DisposableObserver;
import static com.arthenica.mobileffmpeg.Config.RETURN_CODE_CANCEL;
import static com.arthenica.mobileffmpeg.Config.RETURN_CODE_SUCCESS;
public class MainPresenter<V extends MainContract.View> implements MainContract.Presenter<V> {
// private String KEY_SEARCH_CO = "6c66fcbd-6dfe-45a2-ad6b-cbcda09b25bd";
private String KEY_SEARCH_CO = "3b0f7c72-5479-46c1-b26d-224748e64d7a";
private String KEY_SEARCH_PZ = "78bc27f8-6c1b-4172-ba61-05798001671b";
private String KEY_SEARCH_DP = "1c76477f-1fb0-49fb-a5bd-e75311bbe691";
private String KEY_SEARCH_SHIFT = "3e161e49-30d5-44ce-bbc4-3bcff49f7c37";
private String KEY_SEARCH_TYPE = "145ce81d-7bae-4848-a38a-e0e738385681";
private String USER_ID = "N000158385";
private V view;
private String LOGIN_AUTHORIZED_ID = "acd9be92-46bf-4185-8721-5b60c67f0742";
private ApiService api;
SchedulerProviderImp schedulerProviderImp = new SchedulerProviderImp();
private CompositeDisposable compositeDisposable;
public MainPresenter(V view){
this.view = view;
api = HttpMethods.getInstance().getApi();
compositeDisposable = new CompositeDisposable();
}
@Override
public void onGetComData() {
String url = view.getResourceString(R.string.api_on_getCO);
final CORequest mCORequest = new CORequest(KEY_SEARCH_CO, USER_ID);
compositeDisposable.add(api.getCO(url, mCORequest)
.subscribeOn(schedulerProviderImp.io())
.observeOn(schedulerProviderImp.ui())
.subscribeWith(new DisposableObserver<COResultList>() {
@Override
public void onNext(COResultList mCOResultList) {
view.setCOData(mCOResultList.getcOResponseList());
}
@Override
public void onError(Throwable e) {
view.showDialogCaveatMessage(view.getResourceString(R.string.add_device_error));
}
@Override
public void onComplete() {
}
})
);
}
@Override
public void onGetPZData() {
String url = view.getResourceString(R.string.api_on_getMNTFCT);
MNTFCTRequest mMNTFCTRequest = new MNTFCTRequest(KEY_SEARCH_PZ, USER_ID);
compositeDisposable.add(api.getPZ(url, mMNTFCTRequest)
.subscribeOn(schedulerProviderImp.io())
.observeOn(schedulerProviderImp.ui())
.subscribeWith(new DisposableObserver<MNTFCTResultList>() {
@Override
public void onNext(MNTFCTResultList mMNTFCTResultList) {
view.setPZData(mMNTFCTResultList.getmNTFCTResponse());
}
@Override
public void onError(Throwable e) {
view.showDialogCaveatMessage(view.getResourceString(R.string.add_device_error));
}
@Override
public void onComplete() {
}
})
);
}
@Override
public void onGetDPData(String CO, String PZ) {
final PMFCTRequest mPMFCTRequest = new PMFCTRequest(KEY_SEARCH_DP, USER_ID, CO, PZ);
String url = view.getResourceString(R.string.api_on_getDP);
compositeDisposable.add(api.getDP(url, mPMFCTRequest)
.subscribeOn(schedulerProviderImp.io())
.observeOn(schedulerProviderImp.ui())
.subscribeWith(new DisposableObserver<PMFCTResultList>() {
@Override
public void onNext(PMFCTResultList mPMFCTResultList) {
if (mPMFCTResultList.getmPMFCTResponseList().size() < 1) {
view.showDialogCaveatMessage(view.getResourceString(R.string.get_pmfct_error_no_data));
}else{
view.setDPNMData(mPMFCTResultList.getmPMFCTResponseList());
}
}
@Override
public void onError(Throwable e) {
view.showDialogCaveatMessage(view.getResourceString(R.string.add_device_error));
}
@Override
public void onComplete() {
}
})
);
}
@Override
public void onGetSHIFTData(String CO, String PMFCT) {
EQKDRequest mEQKDRequest = new EQKDRequest(KEY_SEARCH_SHIFT, USER_ID, CO, PMFCT);
String url = view.getResourceString(R.string.api_on_getSHIFT);
compositeDisposable.add(api.getEQKD(url, mEQKDRequest)
.subscribeOn(schedulerProviderImp.io())
.observeOn(schedulerProviderImp.ui())
.subscribeWith(new DisposableObserver<EQKDResultList>() {
@Override
public void onNext(EQKDResultList mEQKDResultList) {
if (mEQKDResultList.getmEQKDResponseList().size() < 1) {
view.showDialogCaveatMessage(view.getResourceString(R.string.get_shift_error_no_data));
}else{
view.setEQKDData(mEQKDResultList.getmEQKDResponseList());
}
}
@Override
public void onError(Throwable e) {
view.showDialogCaveatMessage(view.getResourceString(R.string.add_device_error));
}
@Override
public void onComplete() {
}
})
);
}
@Override
public void onGetTYPEData(String CO, String PMFCT) {
final TYPERequest mTypeRequest = new TYPERequest(KEY_SEARCH_TYPE,USER_ID,CO, PMFCT);
String url = view.getResourceString(R.string.api_on_getTYPE);
compositeDisposable.add(api.getTYPE(url,mTypeRequest)
.subscribeOn(schedulerProviderImp.io())
.observeOn(schedulerProviderImp.ui())
.subscribeWith(new DisposableObserver<TYPEResultList>() {
@Override
public void onNext(TYPEResultList mTYPEResultList) {
if (mTYPEResultList.getmTYPEResponseList().size() < 1) {
view.showDialogCaveatMessage(view.getResourceString(R.string.get_type_error_no_data));
}else{
view.setTYPEData(mTYPEResultList.getmTYPEResponseList());
}
}
@Override
public void onError(Throwable e) {
view.showDialogCaveatMessage(view.getResourceString(R.string.add_device_error));
}
@Override
public void onComplete() {
}
})
);
}
@Override
public void segVideo(String path,String name) {
File video = new File(path);
int sizeLimit = 50 * 1024 * 1024;
Log.e("size", video.length() + "");
// Log.e("path2", );
int duration = (int) (FFprobe.getMediaInformation(path).getDuration() / 1000); //影片秒數
int startTime = 0;
int segTime = 30; //分割秒數
int loop = 0;
if (duration % segTime != 0) {
loop = duration / segTime + 1;
} else {
loop = duration / segTime;
}
if (video.length() > sizeLimit) {
for (int i = 0; i < loop; i++) {
int rc = FFmpeg.execute("-ss " + startTime + " -i " + path + " -t " + segTime + " " + Environment.getExternalStorageDirectory().toString() + "/seg_" +i +name + ".mp4");
if (rc == RETURN_CODE_SUCCESS) {
Log.i(Config.TAG, "Command execution completed successfully.");
} else if (rc == RETURN_CODE_CANCEL) {
Log.i(Config.TAG, "Command execution cancelled by user.");
} else {
Log.i(Config.TAG, String.format("Command execution failed with rc=%d and the output below.", rc));
Config.printLastCommandOutput(Log.INFO);
}
startTime += segTime;
}
} else {
//沒超過
}
}
// @Override
// public void onGetDisposableToken(String DeviceId) {
// String authorizedId ="fec40e7e-48c2-4226-81ca-5044b72a8e1f";
// String url = getView().getResourceString(R.string.api_on_DisposableToken);
// DisposableTokenRequest mDisposableTokenRequest=new DisposableTokenRequest(authorizedId,mLoginPreferencesProvider.getToken(),DeviceId);
// getCompositeDisposable().add(getApiService().onDisposableToken(url, mDisposableTokenRequest)
// .subscribeOn(getSchedulerProvider().io())
// .observeOn(getSchedulerProvider().ui())
// .subscribeWith(new DisposableObserver<DisposableTokenResponse>() {
// @Override
// public void onNext(DisposableTokenResponse disposableTokenResponse) {
// Log.e("wwwww","getmResult:"+disposableTokenResponse.getmResult());
// Log.e("wwwww","getmErrMsg:"+disposableTokenResponse.getmErrMsg());
// Log.e("wwwww","getmDisposableToken:"+disposableTokenResponse.getmDisposableToken());
//
// }
//
// @Override
// public void onError(Throwable e) {
//
// }
//
// @Override
// public void onComplete() {
//
// }
// })
// );
// }
}
package com.example.audiovisualrecord.utils;
import android.content.Context;
import android.widget.Toast;
public class ToastCreator {
private static Toast toast;
public static void makeText(final Context context,
final String text,
final int duration) {
if (toast == null) {
toast = Toast.makeText(context, text, duration);
} else {
toast.setText(text);
toast.setDuration(duration);
}
toast.show();
}
public static void makeText(final Context context,
final int resId,
final int duration) {
String text = context.getResources().getString(resId);
if (toast == null) {
toast = Toast.makeText(context, text, duration);
} else {
toast.setText(text);
toast.setDuration(duration);
}
toast.show();
}
}
package com.example.audiovisualrecord.utils.api;
import com.example.audiovisualrecord.utils.api.apidata.CORequest.CORequest;
import com.example.audiovisualrecord.utils.api.apidata.CORequest.COResultList;
import com.example.audiovisualrecord.utils.api.apidata.login.LoginRequest;
import com.example.audiovisualrecord.utils.api.apidata.login.LoginResponse;
import com.example.audiovisualrecord.utils.api.apidata.searchtype.TYPERequest;
import com.example.audiovisualrecord.utils.api.apidata.searchtype.TYPEResultList;
import com.example.audiovisualrecord.utils.api.searcheqkd.EQKDRequest;
import com.example.audiovisualrecord.utils.api.searcheqkd.EQKDResultList;
import com.example.audiovisualrecord.utils.api.searchmntfct.MNTFCTRequest;
import com.example.audiovisualrecord.utils.api.searchmntfct.MNTFCTResultList;
import com.example.audiovisualrecord.utils.api.searchpmfct.PMFCTRequest;
import com.example.audiovisualrecord.utils.api.searchpmfct.PMFCTResultList;
import io.reactivex.Observable;
import retrofit2.http.Body;
import retrofit2.http.POST;
import retrofit2.http.Url;
public interface ApiService {
@POST
Observable<COResultList> getCO(@Url String url, @Body CORequest mCORequest);
@POST
Observable<MNTFCTResultList> getPZ(@Url String url, @Body MNTFCTRequest mMNTFCTRequest);
@POST
Observable<PMFCTResultList> getDP(@Url String url, @Body PMFCTRequest mPMFCTRequest);
@POST
Observable<EQKDResultList> getEQKD(@Url String url, @Body EQKDRequest mEQKDRequest);
@POST
Observable<TYPEResultList>getTYPE(@Url String url, @Body TYPERequest mTypeRequest);
@POST
Observable<LoginResponse> onLogin(@Url String url, @Body LoginRequest mLoginRequest);
}
package com.example.audiovisualrecord.utils.api;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class DataResponse {
@SerializedName("title")
@Expose
private String titlewefwefew;
@SerializedName("content")
@Expose
private String content;
@SerializedName("poster")
@Expose
private String poster;
@SerializedName("url")
@Expose
private String url;
public String getTitle() {
return titlewefwefew;
}
public void setTitle(String title) {
this.titlewefwefew = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getPoster() {
return poster;
}
public void setPoster(String poster) {
this.poster = poster;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
}
package com.example.audiovisualrecord.utils.api;
import java.util.List;
import io.reactivex.Observable;
import retrofit2.http.GET;
public interface ErpAPI {
@GET("xiaohua.json")
Observable<List<DataResponse>> getData();
}
package com.example.audiovisualrecord.utils.api;
import java.util.concurrent.TimeUnit;
import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;
public class HttpMethods {
private static final String BASE_URL = "https://cloud.fpcetg.com.tw/FPC/API/MTN/API_MTN/MTN/";
private static final int TIME_OUT=4;
private Retrofit retrofit;
private ApiService apiService;
private HttpMethods() {
/**
* 构造函数私有化
* 并在构造函数中进行retrofit的初始化
*/
OkHttpClient client=new OkHttpClient();
client.newBuilder().connectTimeout(TIME_OUT, TimeUnit.SECONDS);
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
apiService=retrofit.create(ApiService.class);
}
private static class sinalInstance {
public static final HttpMethods instance = new HttpMethods();
}
public static HttpMethods getInstance(){
return sinalInstance.instance;
}
public ApiService getApi(){
return retrofit.create(ApiService.class);
}
}
package com.example.audiovisualrecord.utils.api.apidata.CORequest;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class CORequest {
@SerializedName("AuthorizedId")
@Expose
private String authorizedId;
@SerializedName("IdNo")
@Expose
private String idNo;
public CORequest(String authorizedId, String idNo) {
this.authorizedId=authorizedId;
this.idNo=idNo;
}
public String getAuthorizedId() {
return authorizedId;
}
public void setAuthorizedId(String authorizedId) {
this.authorizedId = authorizedId;
}
public String getIdNo() {
return idNo;
}
public void setIdNo(String idNo) {
this.idNo = idNo;
}
}
package com.example.audiovisualrecord.utils.api.apidata.CORequest;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class COResponse {
@SerializedName("CO")
@Expose
private String cO;
@SerializedName("CONM")
@Expose
private String cONM;
public String getcO() {
return cO;
}
public void setcO(String cO) {
this.cO = cO;
}
public String getcONM() {
return cONM;
}
public void setcONM(String cONM) {
this.cONM = cONM;
}
}
package com.example.audiovisualrecord.utils.api.apidata.CORequest;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
import java.util.List;
public class COResultList {
@SerializedName("ResultList")
@Expose
private List<COResponse> cOResponseList;
public List<COResponse> getcOResponseList() {
return cOResponseList;
}
public void setcOResponseList(List<COResponse> cOResponseList) {
this.cOResponseList = cOResponseList;
}
}
package com.example.audiovisualrecord.utils.api.apidata.login;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class LoginRequest {
@SerializedName("AuthorizedId")
@Expose
private String authorizedId;
@SerializedName("IdNo")
@Expose
private String mIdNo;
@SerializedName("Password")
@Expose
private String mPassword;
public LoginRequest(String authorizedId, String account, String password) {
this.authorizedId=authorizedId;
this.mIdNo =account;
this.mPassword=password;
}
public String getAuthorizedId() {
return authorizedId;
}
public void setAuthorizedId(String authorizedId) {
this.authorizedId = authorizedId;
}
public String getmIdNo() {
return mIdNo;
}
public void setmIdNo(String mIdNo) {
this.mIdNo = mIdNo;
}
public String getmPassword() {
return mPassword;
}
public void setmPassword(String mPassword) {
this.mPassword = mPassword;
}
}
package com.example.audiovisualrecord.utils.api.apidata.login;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class LoginResponse {
@SerializedName("Result")
@Expose
private String mResult;
@SerializedName("Msg")
@Expose
private String mMsg;
// @SerializedName("Token")
// @Expose
// private String mToken;
// @SerializedName("ErrMsg")
// @Expose
// private String mErrMsg;
public String getmResult() {
return mResult;
}
public void setmResult(String mResult) {
this.mResult = mResult;
}
// public String getmToken() {
// return mToken;
// }
//
// public void setmToken(String mToken) {
// this.mToken = mToken;
// }
//
// public String getmErrMsg() {
// return mErrMsg;
// }
//
// public void setmErrMsg(String mErrMsg) {
// this.mErrMsg = mErrMsg;
// }
public String getmMsg() {
return mMsg;
}
public void setmMsg(String mMsg) {
this.mMsg = mMsg;
}
}
package com.example.audiovisualrecord.utils.api.apidata.searchtype;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class TYPERequest {
@SerializedName("AuthorizedId")
@Expose
private String authorizedId;
@SerializedName("IdNo")
@Expose
private String idNo;
@SerializedName("CO")
@Expose
private String mCO;
@SerializedName("PMFCT")
@Expose
private String mPMFCT;
public TYPERequest(String authorizedId, String idNo, String mCO, String mPMFCT) {
this.authorizedId=authorizedId;
this.idNo=idNo;
this.mCO=mCO;
this.mPMFCT=mPMFCT;
}
public String getAuthorizedId() {
return authorizedId;
}
public void setAuthorizedId(String authorizedId) {
this.authorizedId = authorizedId;
}
public String getIdNo() {
return idNo;
}
public void setIdNo(String idNo) {
this.idNo = idNo;
}
public String getmCO() {
return mCO;
}
public void setmCO(String mCO) {
this.mCO = mCO;
}
public String getmPMFCT() {
return mPMFCT;
}
public void setmPMFCT(String mPMFCT) {
this.mPMFCT = mPMFCT;
}
}
package com.example.audiovisualrecord.utils.api.apidata.searchtype;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class TYPEResponse {
@SerializedName("Type")
@Expose
private String mType;
public String getmType() {
return mType;
}
public void setmType(String mType) {
this.mType = mType;
}
}
package com.example.audiovisualrecord.utils.api.apidata.searchtype;
import com.example.audiovisualrecord.utils.api.searcheqkd.EQKDResponse;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
import java.util.List;
public class TYPEResultList {
@SerializedName("ResultList")
@Expose
private List<TYPEResponse> mTYPEResponseList;
public List<TYPEResponse> getmTYPEResponseList() {
return mTYPEResponseList;
}
public void setmTYPEResponseList(List<TYPEResponse> mTYPEResponseList) {
this.mTYPEResponseList = mTYPEResponseList;
}
}
package com.example.audiovisualrecord.utils.api.searcheqkd;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class EQKDRequest {
@SerializedName("AuthorizedId")
@Expose
private String authorizedId;
@SerializedName("IdNo")
@Expose
private String idNo;
@SerializedName("CO")
@Expose
private String mCO;
@SerializedName("PMFCT")
@Expose
private String mPMFCT;
public EQKDRequest(String authorizedId, String idNo, String mCO, String mPMFCT) {
this.authorizedId=authorizedId;
this.idNo=idNo;
this.mCO=mCO;
this.mPMFCT=mPMFCT;
}
public String getAuthorizedId() {
return authorizedId;
}
public void setAuthorizedId(String authorizedId) {
this.authorizedId = authorizedId;
}
public String getIdNo() {
return idNo;
}
public void setIdNo(String idNo) {
this.idNo = idNo;
}
public String getmCO() {
return mCO;
}
public void setmCO(String mCO) {
this.mCO = mCO;
}
public String getmPMFCT() {
return mPMFCT;
}
public void setmPMFCT(String mPMFCT) {
this.mPMFCT = mPMFCT;
}
}
package com.example.audiovisualrecord.utils.api.searcheqkd;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class EQKDResponse {
@SerializedName("Shift")
@Expose
private String mShift;
public String getmShift() {
return mShift;
}
public void setmShift(String mShift) {
this.mShift = mShift;
}
}
package com.example.audiovisualrecord.utils.api.searcheqkd;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
import java.util.List;
public class EQKDResultList {
@SerializedName("ResultList")
@Expose
private List<EQKDResponse> mEQKDResponseList;
public List<EQKDResponse> getmEQKDResponseList() {
return mEQKDResponseList;
}
public void setmEQKDResponseList(List<EQKDResponse> mEQKDResponseList) {
this.mEQKDResponseList = mEQKDResponseList;
}
}
package com.example.audiovisualrecord.utils.api.searchmntfct;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class MNTFCTRequest {
@SerializedName("AuthorizedId")
@Expose
private String authorizedId;
@SerializedName("IdNo")
@Expose
private String idNo;
public MNTFCTRequest(String authorizedId, String idNo) {
this.authorizedId=authorizedId;
this.idNo=idNo;
}
public String getAuthorizedId() {
return authorizedId;
}
public void setAuthorizedId(String authorizedId) {
this.authorizedId = authorizedId;
}
public String getIdNo() {
return idNo;
}
public void setIdNo(String idNo) {
this.idNo = idNo;
}
}
package com.example.audiovisualrecord.utils.api.searchmntfct;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class MNTFCTResponse {
@SerializedName("PZ")
@Expose
private String mPZ;
@SerializedName("PZNM")
@Expose
private String mPZNM;
public String getmPZ() {
return mPZ;
}
public void setmPZ(String mPZ) {
this.mPZ = mPZ;
}
public String getmPZNM() {
return mPZNM;
}
public void setmPZNM(String mPZNM) {
this.mPZNM = mPZNM;
}
}
package com.example.audiovisualrecord.utils.api.searchmntfct;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
import java.util.List;
public class MNTFCTResultList {
@SerializedName("ResultList")
@Expose
private List<MNTFCTResponse> mNTFCTResponse;
public List<MNTFCTResponse> getmNTFCTResponse() {
return mNTFCTResponse;
}
public void setmNTFCTResponse(List<MNTFCTResponse> mNTFCTResponse) {
this.mNTFCTResponse = mNTFCTResponse;
}
}
package com.example.audiovisualrecord.utils.api.searchpmfct;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class PMFCTRequest {
@SerializedName("AuthorizedId")
@Expose
private String authorizedId;
@SerializedName("IdNo")
@Expose
private String idNo;
@SerializedName("CO")
@Expose
private String mCO;
@SerializedName("PZ")
@Expose
private String mPZ;
public PMFCTRequest(String authorizedId, String idNo, String mCO, String mPZ) {
this.authorizedId=authorizedId;
this.idNo=idNo;
this.mCO = mCO;
this.mPZ = mPZ;
}
public String getAuthorizedId() {
return authorizedId;
}
public void setAuthorizedId(String authorizedId) {
this.authorizedId = authorizedId;
}
public String getIdNo() {
return idNo;
}
public void setIdNo(String idNo) {
this.idNo = idNo;
}
public String getmCO() {
return mCO;
}
public void setmCO(String mCO) {
this.mCO = mCO;
}
public String getmPZ() {
return mPZ;
}
public void setmPZ(String mPZ) {
this.mPZ = mPZ;
}
}
package com.example.audiovisualrecord.utils.api.searchpmfct;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class PMFCTResponse {
@SerializedName("CO")
@Expose
private String mCO;
@SerializedName("PZ")
@Expose
private String mPZ;
@SerializedName("PMFCT")
@Expose
private String mPMFCT;
@SerializedName("DP")
@Expose
private String mDP;
@SerializedName("DPNM")
@Expose
private String mDPNM;
public String getmPZ() {
return mPZ;
}
public void setmPZ(String mPZ) {
this.mPZ = mPZ;
}
public String getmDP() {
return mDP;
}
public void setmDP(String mDP) {
this.mDP = mDP;
}
public String getmCO() {
return mCO;
}
public void setmCO(String mCO) {
this.mCO = mCO;
}
public String getmPMFCT() {
return mPMFCT;
}
public void setmPMFCT(String mPMFCT) {
this.mPMFCT = mPMFCT;
}
public String getmDPNM() {
return mDPNM;
}
public void setmDPNM(String mDPNM) {
this.mDPNM = mDPNM;
}
}
package com.example.audiovisualrecord.utils.api.searchpmfct;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
import java.util.List;
public class PMFCTResultList {
@SerializedName("ResultList")
@Expose
private List<PMFCTResponse> mPMFCTResponseList;
public List<PMFCTResponse> getmPMFCTResponseList() {
return mPMFCTResponseList;
}
public void setmPMFCTResponseList(List<PMFCTResponse> mPMFCTResponseList) {
this.mPMFCTResponseList = mPMFCTResponseList;
}
}
package com.example.audiovisualrecord.utils.rxjava;
import io.reactivex.Scheduler;
/**
* Created by 5*N on 2017/12/31
*/
public interface SchedulerProvider {
Scheduler ui();
Scheduler computation();
Scheduler io();
Scheduler newThread();
}
package com.example.audiovisualrecord.utils.rxjava;
import io.reactivex.Scheduler;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
/**
* Created by 5*N on 2017/12/31
*/
public class SchedulerProviderImp implements SchedulerProvider {
public SchedulerProviderImp() {
}
@Override
public Scheduler ui() {
return AndroidSchedulers.mainThread();
}
@Override
public Scheduler computation() {
return Schedulers.computation();
}
@Override
public Scheduler io() {
return Schedulers.io();
}
@Override
public Scheduler newThread() {
return Schedulers.newThread();
}
}
package com.example.audiovisualrecord.utils.sharepreferences;
import android.content.Context;
/**
* Created by 5*N on 2018/1/1.
*/
public class LoginPreferences extends PreferencesHelper implements LoginPreferencesProvider {
private final String SP_FiLE_NAME = LoginPreferences.class.getName();
private final String PERSON_ID = "PERSON_ID";
private final String PERSON_NAME = "PERSON_NAME";
private final String FACTORY_NUMBER="FACTORY_NUMBER";
private final String PERSON_PASSWORD="PERSON_PASSWORD";
private final String TOKEN="TOKEN";
public LoginPreferences(Context context) {
super(context);
}
@Override
public String getClassName() {
return SP_FiLE_NAME;
}
@Override
public void setPersonPassword(String mPassword) {
save(Type.STRING, PERSON_PASSWORD, mPassword);
}
@Override
public void setToken(String token) {
save(Type.STRING, TOKEN, token);
}
@Override
public void setPersonId(String mPersonId) {
save(Type.STRING, PERSON_ID, mPersonId);
}
@Override
public void setPersonName(String mName) {
save(Type.STRING, PERSON_NAME, mName);
}
@Override
public void setFactoryNumber(String mNumber) {
save(Type.STRING, FACTORY_NUMBER, mNumber);
}
@Override
public String getPersonId() {
return (String) get(Type.STRING, PERSON_ID);
}
@Override
public String getPersonName() {
return (String) get(Type.STRING, PERSON_NAME);
}
@Override
public String getFactoryNumber() {
return (String) get(Type.STRING, FACTORY_NUMBER);
}
@Override
public String getPersonPassword() {
return (String) get(Type.STRING, PERSON_PASSWORD); }
@Override
public String getToken() {
return (String) get(Type.STRING, TOKEN); }
}
package com.example.audiovisualrecord.utils.sharepreferences;
/**
* Created by 5*N on 2018/1/1.
*/
public interface LoginPreferencesProvider {
void setPersonPassword(String mPassword);
void setToken(String token);
void setPersonId(String mPersonId);
void setPersonName(String mName);
void setFactoryNumber(String mNumber);
String getPersonId();
String getPersonName();
String getFactoryNumber();
String getPersonPassword();
String getToken();
}
package com.example.audiovisualrecord.utils.sharepreferences;
import android.content.Context;
import android.content.SharedPreferences;
import java.util.HashSet;
/**
* Created by ameng on 2016/6/20.
*/
public abstract class PreferencesHelper {
private Context context;
public PreferencesHelper(Context context) {
this.context = context;
}
public abstract String getClassName();
public Context getContext() {
return context;
}
public void save(Type type, String key, Object vale) {
SharedPreferences store = context.getSharedPreferences(getClassName(), Context.MODE_PRIVATE);
SharedPreferences.Editor editor = store.edit();
if (type == Type.STRING) {
editor.putString(key, (String) vale);
} else if (type == Type.FLOAT) {
editor.putFloat(key, (Float) vale);
} else if (type == Type.INT) {
editor.putInt(key, (Integer) vale);
} else if (type == Type.LONG) {
editor.putLong(key, (Long) vale);
} else if (type == type.BOOLEAN) {
editor.putBoolean(key, (Boolean) vale);
} else if (type == type.STRING_SET) {
editor.putStringSet(key, (HashSet<String>) vale);
} else {
throw new RuntimeException("Must use base type(String, Float, Double, Integer, Long), type from input is " + type.getClass().getName() + ".");
}
editor.commit();
}
public Object get(Type type, String key) {
SharedPreferences store = context.getSharedPreferences(getClassName(), Context.MODE_PRIVATE);
if (type == Type.STRING) {
return store.getString(String.valueOf(key), "");
} else if (type == Type.FLOAT) {
return store.getFloat(String.valueOf(key), 0);
} else if (type == Type.DOUBLE) {
return Double.valueOf(store.getString(String.valueOf(key), String.valueOf(0.0)));
} else if (type == Type.INT) {
return store.getInt(String.valueOf(key), 0);
} else if (type == Type.LONG) {
return store.getLong(String.valueOf(key), 0);
} else if (type == type.BOOLEAN) {
return store.getBoolean(key, false);
} else if (type == type.STRING_SET) {
return store.getStringSet(key, new HashSet<String>());
} else {
throw new RuntimeException("Must use base type(String, Float, Double, Integer, Long), type from input is " + type.getClass().getName() + ".");
}
}
public static class Type {
public static final Type STRING = new Type();
public static final Type FLOAT = new Type();
public static final Type DOUBLE = new Type();
public static final Type INT = new Type();
public static final Type LONG = new Type();
public static final Type BOOLEAN = new Type();
public static final Type STRING_SET = new Type();
}
}
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path
android:fillType="evenOdd"
android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z"
android:strokeWidth="1"
android:strokeColor="#00000000">
<aapt:attr name="android:fillColor">
<gradient
android:endX="78.5885"
android:endY="90.9159"
android:startX="48.7653"
android:startY="61.0927"
android:type="linear">
<item
android:color="#44000000"
android:offset="0.0" />
<item
android:color="#00000000"
android:offset="1.0" />
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z"
android:strokeWidth="1"
android:strokeColor="#00000000" />
</vector>
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/greenhulk"/>
<stroke
android:width="5.0dip"
android:color="@color/linearlayoutFrame" />
</shape>
\ No newline at end of file
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/grey" />
</shape>
\ No newline at end of file
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<stroke
android:width="2dp"
android:color="@android:color/black" />
</shape>
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path
android:fillColor="#008577"
android:pathData="M0,0h108v108h-108z" />
<path
android:fillColor="#00000000"
android:pathData="M9,0L9,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,0L19,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,0L29,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,0L39,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,0L49,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,0L59,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,0L69,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,0L79,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M89,0L89,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M99,0L99,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,9L108,9"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,19L108,19"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,29L108,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,39L108,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,49L108,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,59L108,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,69L108,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,79L108,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,89L108,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,99L108,99"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,29L89,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,39L89,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,49L89,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,59L89,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,69L89,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,79L89,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,19L29,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,19L39,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,19L49,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,19L59,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,19L69,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,19L79,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
</vector>
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/background"
>
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guide_line_horizontal_12"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.12" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guide_line_horizontal_20"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.20" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guide_line_horizontal_28"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.28" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guide_line_horizontal_36"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.36" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guide_line_horizontal_44"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.44" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guide_line_horizontal_55"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.55" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guide_line_horizontal_78"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.78" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guide_line_vertical_5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.05" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guide_line_vertical_10"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.1" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guide_line_vertical_40"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.4" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guide_line_vertical_45"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.45" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guide_line_vertical_90"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.9" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guide_line_vertical_95"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.95" />
<!-- 選擇區域 -->
<Button
android:id="@+id/tv_company"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@drawable/p2_conpany"
app:layout_constraintHeight_percent="0.07"
app:layout_constraintWidth_percent="0.84"
app:layout_constraintTop_toBottomOf="@+id/guide_line_horizontal_12"
app:layout_constraintStart_toEndOf="@id/guide_line_vertical_10"
/>
<TextView
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintWidth_percent="0.45"
app:layout_constraintHeight_percent="0.05"
android:textColor="@color/black"
app:layout_constraintTop_toTopOf="@+id/tv_company"
app:layout_constraintBottom_toBottomOf="@id/tv_company"
app:layout_constraintStart_toEndOf="@id/guide_line_vertical_40"
/>
<Button
android:id="@+id/tv_factory"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@drawable/p2_factory"
app:layout_constraintHeight_percent="0.07"
app:layout_constraintWidth_percent="0.84"
app:layout_constraintTop_toBottomOf="@+id/guide_line_horizontal_20"
app:layout_constraintStart_toEndOf="@id/guide_line_vertical_10"
/>
<TextView
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintWidth_percent="0.45"
app:layout_constraintHeight_percent="0.05"
android:textColor="@color/black"
app:layout_constraintTop_toTopOf="@+id/tv_factory"
app:layout_constraintBottom_toBottomOf="@id/tv_factory"
app:layout_constraintStart_toEndOf="@id/guide_line_vertical_40"
/>
<Button
android:id="@+id/tv_unit"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@drawable/p2_unit"
app:layout_constraintHeight_percent="0.07"
app:layout_constraintWidth_percent="0.84"
app:layout_constraintTop_toBottomOf="@+id/guide_line_horizontal_28"
app:layout_constraintStart_toEndOf="@id/guide_line_vertical_10"
/>
<TextView
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintWidth_percent="0.35"
app:layout_constraintHeight_percent="0.05"
android:textColor="@color/black"
app:layout_constraintTop_toTopOf="@+id/tv_unit"
app:layout_constraintBottom_toBottomOf="@id/tv_unit"
app:layout_constraintStart_toEndOf="@id/guide_line_vertical_45"
/>
<Button
android:id="@+id/tv_class"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@drawable/p2_class"
app:layout_constraintHeight_percent="0.07"
app:layout_constraintWidth_percent="0.84"
app:layout_constraintTop_toBottomOf="@+id/guide_line_horizontal_36"
app:layout_constraintStart_toEndOf="@id/guide_line_vertical_10"
/>
<TextView
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintWidth_percent="0.45"
app:layout_constraintHeight_percent="0.05"
android:textColor="@color/black"
app:layout_constraintTop_toTopOf="@+id/tv_class"
app:layout_constraintBottom_toBottomOf="@id/tv_class"
app:layout_constraintStart_toEndOf="@id/guide_line_vertical_40"
/>
<Button
android:id="@+id/tv_shoottype"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@drawable/p2_shoottype"
app:layout_constraintHeight_percent="0.07"
app:layout_constraintWidth_percent="0.84"
app:layout_constraintTop_toBottomOf="@+id/guide_line_horizontal_44"
app:layout_constraintStart_toEndOf="@id/guide_line_vertical_10"
/>
<TextView
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintWidth_percent="0.45"
app:layout_constraintHeight_percent="0.05"
android:textColor="@color/black"
app:layout_constraintTop_toTopOf="@+id/tv_shoottype"
app:layout_constraintBottom_toBottomOf="@id/tv_shoottype"
app:layout_constraintStart_toEndOf="@id/guide_line_vertical_40"
/>
<!-- 建立現場資料 -->
<View
android:id="@+id/view_create_live_data"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@drawable/bg_create_field_data"
app:layout_constraintEnd_toStartOf="@id/guide_line_vertical_95"
app:layout_constraintHeight_percent="0.17"
app:layout_constraintStart_toEndOf="@id/guide_line_vertical_5"
app:layout_constraintTop_toBottomOf="@id/guide_line_horizontal_55" />
<TextView
android:id="@+id/text_create"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/create"
android:textStyle="bold"
android:textColor="@color/black"
android:textSize="23sp"
app:layout_constraintVertical_chainStyle="packed"
app:layout_constraintStart_toStartOf="@id/view_create_live_data"
app:layout_constraintEnd_toEndOf="@id/view_create_live_data"
app:layout_constraintTop_toTopOf="@id/view_create_live_data"
app:layout_constraintBottom_toTopOf="@id/text_live_data"/>
<TextView
android:id="@+id/text_live_data"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/live_data"
android:textStyle="bold"
android:textColor="@color/black"
android:textSize="23sp"
app:layout_constraintTop_toBottomOf="@id/text_create"
app:layout_constraintStart_toStartOf="@id/view_create_live_data"
app:layout_constraintEnd_toEndOf="@id/view_create_live_data"
app:layout_constraintBottom_toBottomOf="@id/view_create_live_data"/>
<Button
android:id="@+id/btnCaptureImage"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@drawable/bg_photo_button"
app:layout_constraintBottom_toBottomOf="@id/view_create_live_data"
app:layout_constraintHeight_percent="0.12"
app:layout_constraintStart_toEndOf="@id/guide_line_vertical_10"
app:layout_constraintTop_toTopOf="@id/view_create_live_data"
app:layout_constraintWidth_percent="0.2" />
<Button
android:id="@+id/btnRecordVideo"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@drawable/bg_record_button"
app:layout_constraintBottom_toBottomOf="@id/view_create_live_data"
app:layout_constraintEnd_toStartOf="@id/guide_line_vertical_90"
app:layout_constraintHeight_percent="0.12"
app:layout_constraintTop_toTopOf="@id/view_create_live_data"
app:layout_constraintWidth_percent="0.2" />
<!-- 資料上傳 -->
<View
android:id="@+id/view_data_upload"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@drawable/bg_data_upload"
app:layout_constraintEnd_toStartOf="@id/guide_line_vertical_95"
app:layout_constraintHeight_percent="0.2"
app:layout_constraintStart_toEndOf="@id/guide_line_vertical_5"
app:layout_constraintTop_toBottomOf="@id/guide_line_horizontal_78" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/data_upload"
android:textStyle="bold"
android:textColor="@color/black"
android:textSize="23sp"
app:layout_constraintTop_toTopOf="@id/view_data_upload"
app:layout_constraintBottom_toBottomOf="@id/view_data_upload"
app:layout_constraintStart_toStartOf="@id/view_data_upload"
app:layout_constraintEnd_toEndOf="@id/view_data_upload"/>
<Button
android:id="@+id/btnGetImageFromGallery"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@drawable/bg_upload_photo_button"
app:layout_constraintBottom_toBottomOf="@id/view_data_upload"
app:layout_constraintHeight_percent="0.12"
app:layout_constraintStart_toEndOf="@id/guide_line_vertical_10"
app:layout_constraintTop_toTopOf="@id/view_data_upload"
app:layout_constraintWidth_percent="0.2" />
<Button
android:id="@+id/btnGetVideoFromGallery"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@drawable/bg_upload_video_button"
app:layout_constraintBottom_toBottomOf="@id/view_data_upload"
app:layout_constraintEnd_toStartOf="@id/guide_line_vertical_90"
app:layout_constraintHeight_percent="0.12"
app:layout_constraintTop_toTopOf="@id/view_data_upload"
app:layout_constraintVertical_bias="0.509"
app:layout_constraintWidth_percent="0.2" />
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bg_login">
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guide_line_horizontal_12"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.12"/>
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guide_line_horizontal_45"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.45"/>
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guide_line_horizontal_56"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.56"/>
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guide_line_horizontal_68"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.68"/>
<EditText
android:id="@+id/edit_account"
android:layout_width="0dp"
android:layout_height="0dp"
android:hint="@string/login_account_hint"
android:textColorHint="@color/white"
android:paddingStart="100dp"
app:layout_constraintWidth_percent="0.9"
app:layout_constraintHeight_percent="0.08"
android:background="@drawable/bg_login_account"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/guide_line_horizontal_45"
android:paddingLeft="100dp" />
<EditText
android:id="@+id/edit_password"
android:layout_width="0dp"
android:layout_height="0dp"
android:hint="@string/login_password_hint"
android:textColorHint="@color/white"
android:paddingStart="100dp"
android:background="@drawable/bg_login_password"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintWidth_percent="0.9"
app:layout_constraintHeight_percent="0.08"
app:layout_constraintTop_toBottomOf="@id/guide_line_horizontal_56"
android:paddingLeft="100dp" />
<Button
android:id="@+id/btn_login"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintWidth_percent="0.3"
app:layout_constraintHeight_percent="0.16"
app:layout_constraintTop_toBottomOf="@id/guide_line_horizontal_68"
app:layout_constraintBottom_toBottomOf="parent"
android:background="@drawable/bg_login_button"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#008577</color>
<color name="colorPrimaryDark">#00574B</color>
<color name="colorAccent">#D81B60</color>
<color name="white">#ffffff</color><!--白色 -->
<color name="ivory">#fffff0</color><!--象牙色 -->
<color name="lightyellow">#ffffe0</color><!--亮黄色 -->
<color name="yellow">#ffff00</color><!--黄色 -->
<color name="snow">#fffafa</color><!--雪白色 -->
<color name="floralwhite">#fffaf0</color><!--花白色 -->
<color name="lemonchiffon">#fffacd</color><!--柠檬绸色 -->
<color name="cornsilk">#fff8dc</color><!--米绸色 -->
<color name="seaShell">#fff5ee</color><!--海贝色 -->
<color name="lavenderblush">#fff0f5</color><!--淡紫红 -->
<color name="papayawhip">#ffefd5</color><!--番木色 -->
<color name="blanchedalmond">#ffebcd</color><!--白杏色 -->
<color name="mistyrose">#ffe4e1</color><!--浅玫瑰色 -->
<color name="bisque">#ffe4c4</color><!--桔黄色 -->
<color name="moccasin">#ffe4b5</color><!--鹿皮色 -->
<color name="navajowhite">#ffdead</color><!--纳瓦白 -->
<color name="peachpuff">#ffdab9</color><!--桃色 -->
<color name="gold">#ffd700</color><!--金色 -->
<color name="pink">#ffc0cb</color><!--粉红色 -->
<color name="lightpink">#ffb6c1</color><!--亮粉红色 -->
<color name="orange">#ffa500</color><!--橙色 -->
<color name="lightsalmon">#ffa07a</color><!--亮肉色 -->
<color name="darkorange">#ff8c00</color><!--暗桔黄色 -->
<color name="coral">#ff7f50</color><!--珊瑚色 -->
<color name="hotpink">#ff69b4</color><!--热粉红色 -->
<color name="tomato">#ff6347</color><!--西红柿色 -->
<color name="orangered">#ff4500</color><!--红橙色 -->
<color name="deeppink">#ff1493</color><!--深粉红色 -->
<color name="fuchsia">#ff00ff</color><!--紫红色 -->
<color name="magenta">#ff00ff</color><!--红紫色 -->
<color name="red">#ff0000</color><!--红色 -->
<color name="oldlace">#fdf5e6</color><!--老花色 -->
<color name="lightgoldenrodyellow">#fafad2</color><!--亮金黄色 -->
<color name="linen">#faf0e6</color><!--亚麻色 -->
<color name="antiquewhite">#faebd7</color><!--古董白 -->
<color name="salmon">#fa8072</color><!--鲜肉色 -->
<color name="ghostwhite">#f8f8ff</color><!--幽灵白 -->
<color name="mintcream">#f5fffa</color><!--薄荷色 -->
<color name="whitesmoke">#f5f5f5</color><!--烟白色 -->
<color name="beige">#f5f5dc</color><!--米色 -->
<color name="wheat">#f5deb3</color><!--浅黄色 -->
<color name="sandybrown">#f4a460</color><!--沙褐色 -->
<color name="azure">#f0ffff</color><!--天蓝色 -->
<color name="honeydew">#f0fff0</color><!--蜜色 -->
<color name="aliceblue">#f0f8ff</color><!--艾利斯兰 -->
<color name="khaki">#f0e68c</color><!--黄褐色 -->
<color name="lightcoral">#f08080</color><!--亮珊瑚色 -->
<color name="palegoldenrod">#eee8aa</color><!--苍麒麟色 -->
<color name="violet">#ee82ee</color><!--紫罗兰色 -->
<color name="darksalmon">#e9967a</color><!--暗肉色 -->
<color name="lavender">#e6e6fa</color><!--淡紫色 -->
<color name="lightcyan">#e0ffff</color><!--亮青色 -->
<color name="burlywood">#deb887</color><!--实木色 -->
<color name="plum">#dda0dd</color><!--洋李色 -->
<color name="gainsboro">#dcdcdc</color><!--淡灰色 -->
<color name="crimson">#dc143c</color><!--暗深红色 -->
<color name="palevioletred">#db7093</color><!--苍紫罗兰色 -->
<color name="goldenrod">#daa520</color><!--金麒麟色 -->
<color name="orchid">#da70d6</color><!--淡紫色 -->
<color name="thistle">#d8bfd8</color><!--蓟色 -->
<color name="lightgray">#d3d3d3</color><!--亮灰色 -->
<color name="lightgrey">#d3d3d3</color><!--亮灰色 -->
<color name="tan">#d2b48c</color><!--茶色 -->
<color name="chocolate">#d2691e</color><!--巧可力色 -->
<color name="peru">#cd853f</color><!--秘鲁色 -->
<color name="indianred">#cd5c5c</color><!--印第安红 -->
<color name="mediumvioletred">#c71585</color><!--中紫罗兰色 -->
<color name="silver">#c0c0c0</color><!--银色 -->
<color name="darkkhaki">#bdb76b</color><!--暗黄褐色 -->
<color name="rosybrown">#bc8f8f</color><!--褐玫瑰红 -->
<color name="mediumorchid">#ba55d3</color><!--中粉紫色 -->
<color name="darkgoldenrod">#b8860b</color><!--暗金黄色 -->
<color name="firebrick">#b22222</color><!--火砖色 -->
<color name="powderblue">#b0e0e6</color><!--粉蓝色 -->
<color name="lightsteelblue">#b0c4de</color><!--亮钢兰色 -->
<color name="paleturquoise">#afeeee</color><!--苍宝石绿 -->
<color name="greenyellow">#adff2f</color><!--黄绿色 -->
<color name="lightblue">#add8e6</color><!--亮蓝色 -->
<color name="darkgray">#a9a9a9</color><!--暗灰色 -->
<color name="darkgrey">#a9a9a9</color><!--暗灰色 -->
<color name="brown">#a52a2a</color><!--褐色 -->
<color name="sienna">#a0522d</color><!--赭色 -->
<color name="darkorchid">#9932cc</color><!--暗紫色 -->
<color name="palegreen">#98fb98</color><!--苍绿色 -->
<color name="darkviolet">#9400d3</color><!--暗紫罗兰色 -->
<color name="mediumpurple">#9370db</color><!--中紫色 -->
<color name="lightgreen">#90ee90</color><!--亮绿色 -->
<color name="darkseagreen">#8fbc8f</color><!--暗海兰色 -->
<color name="saddlebrown">#8b4513</color><!--重褐色 -->
<color name="darkmagenta">#8b008b</color><!--暗洋红 -->
<color name="darkred">#8b0000</color><!--暗红色 -->
<color name="blueviolet">#8a2be2</color><!--紫罗兰蓝色 -->
<color name="lightskyblue">#87cefa</color><!--亮天蓝色 -->
<color name="skyblue">#87ceeb</color><!--天蓝色 -->
<color name="gray">#808080</color><!--灰色 -->
<color name="grey">#808080</color><!--灰色 -->
<color name="olive">#808000</color><!--橄榄色 -->
<color name="purple">#800080</color><!--紫色 -->
<color name="maroon">#800000</color><!--粟色 -->
<color name="aquamarine">#7fffd4</color><!--碧绿色 -->
<color name="chartreuse">#7fff00</color><!--黄绿色 -->
<color name="lawngreen">#7cfc00</color><!--草绿色 -->
<color name="mediumslateblue">#7b68ee</color><!--中暗蓝色 -->
<color name="lightslategray">#778899</color><!--亮蓝灰 -->
<color name="lightslategrey">#778899</color><!--亮蓝灰 -->
<color name="slategray">#708090</color><!--灰石色 -->
<color name="slategrey">#708090</color><!--灰石色 -->
<color name="olivedrab">#6b8e23</color><!--深绿褐色 -->
<color name="slateblue">#6a5acd</color><!--石蓝色 -->
<color name="dimgray">#696969</color><!--暗灰色 -->
<color name="dimgrey">#696969</color><!--暗灰色 -->
<color name="mediumaquamarine">#66cdaa</color><!--中绿色 -->
<color name="cornflowerblue">#6495ed</color><!--菊兰色 -->
<color name="cadetblue">#5f9ea0</color><!--军兰色 -->
<color name="darkolivegreen">#556b2f</color><!--暗橄榄绿 -->
<color name="indigo">#4b0082</color><!--靛青色 -->
<color name="mediumturquoise">#48d1cc</color><!--中绿宝石 -->
<color name="darkslateblue">#483d8b</color><!--暗灰蓝色 -->
<color name="steelblue">#4682b4</color><!--钢兰色 -->
<color name="royalblue">#4169e1</color><!--皇家蓝 -->
<color name="turquoise">#40e0d0</color><!--青绿色 -->
<color name="mediumseagreen">#3cb371</color><!--中海蓝 -->
<color name="limegreen">#32cd32</color><!--橙绿色 -->
<color name="darkslategray">#2f4f4f</color><!--暗瓦灰色 -->
<color name="darkslategrey">#2f4f4f</color><!--暗瓦灰色 -->
<color name="seagreen">#2e8b57</color><!--海绿色 -->
<color name="forestgreen">#228b22</color><!--森林绿 -->
<color name="lightseagreen">#20b2aa</color><!--亮海蓝色 -->
<color name="dodgerblue">#1e90ff</color><!--闪兰色 -->
<color name="midnightblue">#191970</color><!--中灰兰色 -->
<color name="aqua">#00ffff</color><!--浅绿色 -->
<color name="cyan">#00ffff</color><!--青色 -->
<color name="springgreen">#00ff7f</color><!--春绿色 -->
<color name="lime">#00ff00</color><!--酸橙色 -->
<color name="mediumspringgreen">#00fa9a</color><!--中春绿色 -->
<color name="darkturquoise">#00ced1</color><!--暗宝石绿 -->
<color name="deepskyblue">#00bfff</color><!--深天蓝色 -->
<color name="darkcyan">#008b8b</color><!--暗青色 -->
<color name="teal">#008080</color><!--水鸭色 -->
<color name="green">#008000</color><!--绿色 -->
<color name="darkgreen">#006400</color><!--暗绿色 -->
<color name="blue">#0000ff</color><!--蓝色 -->
<color name="mediumblue">#0000cd</color><!--中兰色 -->
<color name="darkblue">#00008b</color><!--暗蓝色 -->
<color name="navy">#000080</color><!--海军色 -->
<color name="black">#000000</color><!--黑色 -->
<color name="greenhulk">#FFCBA0</color>
<color name="titleblue">#4472C4</color>
<color name="linearlayoutFrame">#2F528F</color>
</resources>
<resources>
<string name="app_name">影音紀錄APP</string>
<string name="select_file">設備文件檢視</string>
<string name="login_account">帳號</string>
<string name="login_password">密碼</string>
<string name="login_btn_login">登入</string>
<string name="login_account_hint">請輸入帳號</string>
<string name="login_password_hint">請輸入密碼</string>
<string name="open_camera_for_capture">拍照</string>
<string name="open_camera_for_video">錄影</string>
<string name="updata_video">錄影上傳</string>
<string name="updata_picture">拍照上傳</string>
<string name="device">設備ID:</string>
<string name="fetch">擷取</string>
<string name="device_company">&#160;&#160;&#160;&#160;&#160;&#160;&#160;司:&#160;</string>
<string name="job_site">作業廠處:&#160;</string>
<string name="production_plant">&#160;&#160;廠:&#160;</string>
<string name="route_code">路線代號:&#160;</string>
<string name="route_name">路線名稱:&#160;</string>
<string name="device_category">設備類別:&#160;</string>
<string name="device_number">設備編號:&#160;</string>
<string name="device_name">設備名稱:&#160;</string>
<string name="create">建立</string>
<string name="live_data">現場資料</string>
<string name="data_upload">資料上傳</string>
<string name="record_date">紀錄日期:&#160;</string>
<string name="maintenance_plant">&#160;&#160;廠:&#160;</string>
<string name="file">&#160;&#160;&#160;&#160;&#160;&#160;&#160;案:&#160;</string>
<string name="browse">瀏覽</string>
<string name="upload">上傳</string>
<string name="upload_person">上傳人員:&#160;</string>
<string name="on_upload_image">照片上傳中</string>
<string name="on_upload_vedio">影片上傳中</string>
<!--chooseDevice部分-->
<string name="add_device_error_on_choose_device_activity">新增失敗</string>
<!--api使用部分-->
<string name="api_base_url">https://cloud.fpcetg.com.tw/FPC/API/MTN/API_MTN/MTN/</string>
<string name="api_erp_url">http://api.laifudao.com/open/</string>
<string name="api_on_getCO">https://cloud.fpcetg.com.tw/FPC/API/FM/SopRecord_API/INFO/SearchCO</string>
<string name="api_on_getMNTFCT">https://cloud.fpcetg.com.tw/FPC/API/FM/SopRecord_API/INFO/SearchPZ</string>
<string name="api_on_getDP">https://cloud.fpcetg.com.tw/FPC/API/FM/SopRecord_API/INFO/SearchDP</string>
<string name="api_on_getSHIFT">https://cloud.fpcetg.com.tw/FPC/API/FM/SopRecord_API/INFO/SearchSHIFT</string>
<string name="api_on_getTYPE">https://cloud.fpcetg.com.tw/FPC/API/FM/SopRecord_API/INFO/SearchTYPE</string>
<string name="api_on_getEQNO">SearchEQNO</string>
<string name="api_on_Login">https://cloud.fpcetg.com.tw/FPC/API/FM/SopRecord_API/INFO/Access</string>
<string name="api_on_DisposableToken">DisposableToken</string>
<!--addDevice部分-->
<string name="get_pmfct_error_no_data">廠課無資料</string>
<string name="get_shift_error_no_data">班別查無資料</string>
<string name="get_type_error_no_data">錄影類型查無資料</string>
<string name="get_eqno_error_no_data">設備編號查無資料</string>
<string name="add_device_no_maintenance_plant_error">請選擇廠區</string>
<string name="add_device_no_company_error">請選擇公司</string>
<string name="add_device_no_production_plant_error">請選擇廠課</string>
<string name="add_device_no_device_categry_error">請選擇設備類別</string>
<string name="add_device_no_data_maintenance_plant">保養廠還未填寫</string>
<string name="add_device_no_data_company">公司還未填寫</string>
<string name="add_device_no_data_production_plant">生產廠還未填寫</string>
<string name="add_device_no_data_device_categry">設備類別還未填寫</string>
<string name="add_device_no_data_device_id">設備編號還未填寫</string>
<string name="add_device_no_data_keynote">主旨說明還未填寫</string>
<string name="add_device_no_data_file">檔案還未選擇</string>
<string name="add_device_error">查詢資料失敗,請重試或檢查網路狀態,或檢查資料是否正確</string>
</resources>
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<paths>
<root-path
name="/"
path="/" />
</paths>
\ No newline at end of file
package com.example.audiovisualrecord;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* Example local unit test, which will execute on the development machine (host).
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
public class ExampleUnitTest {
@Test
public void addition_isCorrect() {
assertEquals(4, 2 + 2);
}
}
\ No newline at end of file
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.5.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
google()
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx1536m
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
# AndroidX package structure to make it clearer which packages are bundled with the
# Android operating system, and which are packaged with your app's APK
# https://developer.android.com/topic/libraries/support-library/androidx-rn
android.useAndroidX=true
# Automatically convert third-party libraries to use AndroidX
android.enableJetifier=true
#Tue May 19 16:31:39 GMT+08:00 2020
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip
#!/usr/bin/env sh
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=$(save "$@")
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
include ':app'
rootProject.name='AudiovisualRecord'
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment