master
lijie 2023-07-27 17:05:43 +08:00
commit 8d3945977c
87 changed files with 3575 additions and 0 deletions

15
.gitignore vendored Normal file
View File

@ -0,0 +1,15 @@
*.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
local.properties

3
.idea/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
# Default ignored files
/shelf/
/workspace.xml

6
.idea/compiler.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<bytecodeTargetLevel target="11" />
</component>
</project>

20
.idea/gradle.xml Normal file
View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleMigrationSettings" migrationVersion="1" />
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="testRunner" value="GRADLE" />
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleJvm" value="corretto-11" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" />
</set>
</option>
</GradleProjectSettings>
</option>
</component>
</project>

6
.idea/kotlinc.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="KotlinJpsPluginSettings">
<option name="version" value="1.6.21" />
</component>
</project>

37
.idea/misc.xml Normal file
View File

@ -0,0 +1,37 @@
<project version="4">
<component name="DesignSurface">
<option name="filePathToZoomLevelMap">
<map>
<entry key="..\:/Project/Code/Android/AfricanFinance/app/src/main/res/drawable/bg_checkbox.xml" value="0.491" />
<entry key="..\:/Project/Code/Android/AfricanFinance/app/src/main/res/drawable/curse_sharp.xml" value="0.393" />
<entry key="..\:/Project/Code/Android/AfricanFinance/app/src/main/res/drawable/edittext_active_sharp.xml" value="0.393" />
<entry key="..\:/Project/Code/Android/AfricanFinance/app/src/main/res/drawable/edittext_normal_sharp.xml" value="0.393" />
<entry key="..\:/Project/Code/Android/AfricanFinance/app/src/main/res/drawable/ic_home_black_24dp.xml" value="0.331" />
<entry key="..\:/Project/Code/Android/AfricanFinance/app/src/main/res/drawable/ic_launcher_background.xml" value="0.491" />
<entry key="..\:/Project/Code/Android/AfricanFinance/app/src/main/res/drawable/ic_login_bg.xml" value="0.331" />
<entry key="..\:/Project/Code/Android/AfricanFinance/app/src/main/res/drawable/ic_notifications_black_24dp.xml" value="0.491" />
<entry key="..\:/Project/Code/Android/AfricanFinance/app/src/main/res/drawable/round_btn_sharp.xml" value="0.491" />
<entry key="..\:/Project/Code/Android/AfricanFinance/app/src/main/res/drawable/round_btn_sharp_empty.xml" value="0.331" />
<entry key="..\:/Project/Code/Android/AfricanFinance/app/src/main/res/drawable/round_code_sharp.xml" value="0.491" />
<entry key="..\:/Project/Code/Android/AfricanFinance/app/src/main/res/drawable/selector_edit_text.xml" value="0.393" />
<entry key="..\:/Project/Code/Android/AfricanFinance/app/src/main/res/drawable/selector_round_btn_sharp.xml" value="0.331" />
<entry key="..\:/Project/Code/Android/AfricanFinance/app/src/main/res/layout/actionbar_custom.xml" value="0.4510474561778538" />
<entry key="..\:/Project/Code/Android/AfricanFinance/app/src/main/res/layout/activity_first.xml" value="0.30739299610894943" />
<entry key="..\:/Project/Code/Android/AfricanFinance/app/src/main/res/layout/activity_login.xml" value="0.3227875160324925" />
<entry key="..\:/Project/Code/Android/AfricanFinance/app/src/main/res/layout/activity_main.xml" value="0.19251824817518248" />
<entry key="..\:/Project/Code/Android/AfricanFinance/app/src/main/res/layout/activity_register.xml" value="0.5346303501945525" />
<entry key="..\:/Project/Code/Android/AfricanFinance/app/src/main/res/layout/activity_register_success.xml" value="0.18041898247114152" />
<entry key="..\:/Project/Code/Android/AfricanFinance/app/src/main/res/layout/fragment_dashboard.xml" value="0.18041898247114152" />
<entry key="..\:/Project/Code/Android/AfricanFinance/app/src/main/res/layout/fragment_home.xml" value="0.18041898247114152" />
<entry key="..\:/Project/Code/Android/AfricanFinance/app/src/main/res/layout/fragment_notifications.xml" value="0.18041898247114152" />
<entry key="..\:/Project/Code/Android/AfricanFinance/app/src/main/res/menu/bottom_nav_menu.xml" value="0.18041898247114152" />
</map>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="corretto-11" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>

6
.idea/vcs.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

7
app/.gitignore vendored Normal file
View File

@ -0,0 +1,7 @@
/build
.idea
gradlew
gradlew.bat
.DS_Store
*.iml
.gradle

75
app/build.gradle Normal file
View File

@ -0,0 +1,75 @@
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'kotlin-android-extensions'
id 'kotlin-kapt'
}
static def releaseTime() {
return "" + new Date().format("yyyyMMddHHmm", TimeZone.getTimeZone("Asia/Shanghai"))
}
android {
compileSdk 32
defaultConfig {
applicationId "com.cmx.hydrology"
minSdk 21
targetSdk 29
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
android.applicationVariants.all { variant ->
variant.outputs.all {
outputFileName = "hydrology" + versionName + "_" + versionCode + "_" + releaseTime() + ".apk"
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
buildFeatures {
viewBinding true
}
}
dependencies {
implementation(fileTree("libs"))
implementation 'androidx.work:work-runtime:2.7.1'
implementation 'androidx.appcompat:appcompat:1.3.0'
implementation 'com.google.android.material:material:1.4.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.3.1'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1'
implementation 'androidx.navigation:navigation-fragment:2.3.5'
implementation 'androidx.navigation:navigation-ui:2.3.5'
implementation 'androidx.annotation:annotation:1.2.0'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
implementation 'com.google.code.gson:gson:2.6.2'
implementation 'com.squareup.retrofit2:retrofit:2.4.0'
implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
implementation 'com.github.GrenderG:Toasty:1.5.2'
implementation 'com.squareup.okhttp3:logging-interceptor:3.8.1'
implementation 'com.github.lsxiao.Apollo:core:1.0.2'
implementation 'com.github.lsxiao.Apollo:ipc:1.0.2'
kapt "com.github.lsxiao.Apollo:processor:1.0.2"
//Apollo
annotationProcessor "com.github.lsxiao.Apollo:processor:1.0.2"
implementation "io.reactivex.rxjava2:rxjava:2.2.4"
implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'
implementation 'com.github.nanchen2251:CompressHelper:1.0.5'
implementation 'com.scwang.wave:MultiWaveHeader:1.0.0-andx'
}

21
app/proguard-rules.pro vendored Normal file
View File

@ -0,0 +1,21 @@
# 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

View File

@ -0,0 +1,83 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.cmx.hydrology">
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!--在SDCard中创建与删除文件权限-->
<uses-permission
android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"
tools:ignore="ProtectedPermissions" />
<uses-permission
android:name="android.permission.LOCAL_MAC_ADDRESS"
tools:ignore="ProtectedPermissions" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission
android:name="android.permission.READ_PRIVILEGED_PHONE_STATE"
tools:ignore="ProtectedPermissions" />
<uses-permission android:name="android.permission.USE_BIOMETRIC" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
tools:ignore="ScopedStorage" />
<uses-permission
android:name="android.permission.QUERY_ALL_PACKAGES"
tools:ignore="QueryAllPackagesPermission" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature
android:name="android.hardware.camera"
android:required="true" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<application
android:name=".activity.MyApplication"
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/icon_logo"
android:label="@string/app_name"
android:requestLegacyExternalStorage="true"
android:supportsRtl="true"
android:theme="@style/Theme.AfricanFinance"
android:usesCleartextTraffic="true"
tools:targetApi="31">
<activity
android:name=".activity.WebActivity"
android:exported="false"
android:windowSoftInputMode="stateAlwaysHidden|adjustResize" />
<activity
android:name=".activity.LoginActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".activity.MainActivity"
android:exported="true"
android:label="@string/app_name"></activity>
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.cmx.hydrology.fileProvider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
</application>
</manifest>

View File

@ -0,0 +1,75 @@
package com.cmx.hydrology.activity;
import android.os.Bundle;
import android.webkit.WebResourceError;
import android.webkit.WebResourceRequest;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import androidx.appcompat.app.AppCompatActivity;
import com.cmx.hydrology.view.BaseLoadingDialog;
import com.lsxiao.apollo.core.Apollo;
import com.lsxiao.apollo.core.contract.ApolloBinder;
public class BaseActivity extends AppCompatActivity {
private static final String TAG = "BaseActivity";
private BaseLoadingDialog mBaseLoadingDialog;
private ApolloBinder mApolloBinder;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mBaseLoadingDialog = new BaseLoadingDialog(this);
mApolloBinder = Apollo.bind(this);
}
public void showDialog() {
if (!mBaseLoadingDialog.isShowing()) {
mBaseLoadingDialog.show();
}
}
public void disDialog() {
if (mBaseLoadingDialog.isShowing()) {
mBaseLoadingDialog.dismiss();
}
}
public void setWeb(WebView mWebView) {
mWebView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
//使用WebView加载显示url
view.loadUrl(url);
//返回true
return true;
}
@Override
public void onPageFinished(WebView view, String url) {
disDialog();
}
@Override
public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
disDialog();
}
}
);
}
@Override
protected void onDestroy() {
super.onDestroy();
if (mApolloBinder != null) {
mApolloBinder.unbind();
}
}
}

View File

@ -0,0 +1,92 @@
package com.cmx.hydrology.activity;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import androidx.annotation.RequiresApi;
import com.cmx.hydrology.databinding.ActivityLoginBinding;
import com.cmx.hydrology.model.LoginBean;
import com.cmx.hydrology.model.LoginRes;
import com.cmx.hydrology.retrofit.RetrofitAPIManager;
import com.cmx.hydrology.utils.MyUtils;
import com.cmx.hydrology.utils.SpUtils;
import es.dmoral.toasty.Toasty;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public class LoginActivity extends BaseActivity {
private ActivityLoginBinding binding;
@RequiresApi(api = Build.VERSION_CODES.M)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityLoginBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
MyUtils.setFullscreen(this, true, true);
binding.btnLogin.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(LoginActivity.this, MainActivity.class);
startActivity(intent);
finish();
// if (TextUtils.isEmpty(binding.edtUsername.getText().toString().trim())) {
// Toasty.info(LoginActivity.this, "请输入用户名").show();
// return;
// }
// if (TextUtils.isEmpty(binding.edtPassword.getText().toString().trim())) {
// Toasty.info(LoginActivity.this, "请输入密码").show();
// return;
// }
// toLogin();
}
});
}
/**
*
*/
private void toLogin() {
showDialog();
LoginBean LoginBean = new LoginBean();
LoginBean.setUsername(binding.edtUsername.getText().toString().trim());
LoginBean.setPassword(binding.edtPassword.getText().toString().trim());
Call<LoginRes> call = RetrofitAPIManager.provideClientApi().login(LoginBean);
call.enqueue(new Callback<LoginRes>() {
@Override
public void onResponse(Call<LoginRes> call, Response<LoginRes> response) {
disDialog();
if (response.isSuccessful() && response.body().getCode() == 0) {
SpUtils.putString(LoginActivity.this, "token", response.body().getAccess_token());
SpUtils.putString(LoginActivity.this, "admin", response.body().getIs_admin());
Intent intent = new Intent(LoginActivity.this, MainActivity.class);
startActivity(intent);
finish();
} else {
Toasty.error(LoginActivity.this, response.body().getMessage()).show();
}
}
@Override
public void onFailure(Call<LoginRes> call, Throwable t) {
disDialog();
Toasty.info(LoginActivity.this, "登录失败").show();
}
});
}
@Override
public void onDestroy() {
super.onDestroy();
binding = null;
}
}

View File

@ -0,0 +1,114 @@
package com.cmx.hydrology.activity;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import androidx.annotation.RequiresApi;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import androidx.navigation.ui.NavigationUI;
import com.cmx.hydrology.R;
import com.cmx.hydrology.constant.Events;
import com.cmx.hydrology.databinding.ActivityMainBinding;
import com.google.android.material.bottomnavigation.BottomNavigationView;
import com.lsxiao.apollo.core.Apollo;
import com.lsxiao.apollo.core.annotations.Receive;
public class MainActivity extends BaseActivity {
private ActivityMainBinding binding;
private BottomNavigationView navView;
private NavController navController;
@RequiresApi(api = Build.VERSION_CODES.M)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
navView = findViewById(R.id.nav_view);
navController = Navigation.findNavController(this, R.id.nav_host_fragment_activity_main);
NavigationUI.setupWithNavController(binding.navView, navController);
}
/**
* tabbar
*/
@Receive(Events.JS_OPEN_TABBAR_SHOW)
public void showTab() {
binding.navView.setVisibility(View.VISIBLE);
}
/**
* tabbar
*/
@Receive(Events.JS_OPEN_TABBAR_HIDE)
public void hideTab() {
binding.navView.setVisibility(View.GONE);
}
/**
* web
*/
@Receive(Events.JS_OPEN_OPEN_WEB)
public void openWeb(String url) {
Intent intent = new Intent(this, WebActivity.class);
intent.putExtra("url", url);
startActivity(intent);
}
/**
* tab
*/
@Receive(Events.JS_OPEN_TAB)
public void ckTab(String mode) {
Apollo.emit(Events.JS_OPEN_CLOSE_WEB);
switch (mode) {
case "1":
Menu menu = navView.getMenu();
MenuItem menuItem = menu.getItem(0); // 将index替换为您想要点击的项目的索引
menuItem.setChecked(true);
navController.navigate(R.id.navigation_home);
break;
case "2":
Menu menu2 = navView.getMenu();
MenuItem menuItem2 = menu2.getItem(1); // 将index替换为您想要点击的项目的索引
menuItem2.setChecked(true);
navController.navigate(R.id.navigation_msg);
break;
case "3":
Menu menu3 = navView.getMenu();
MenuItem menuItem3 = menu3.getItem(2); // 将index替换为您想要点击的项目的索引
menuItem3.setChecked(true);
navController.navigate(R.id.navigation_map);
break;
case "4":
Menu menu4 = navView.getMenu();
MenuItem menuItem4 = menu4.getItem(3); // 将index替换为您想要点击的项目的索引
menuItem4.setChecked(true);
navController.navigate(R.id.navigation_my);
break;
}
}
/**
* 退
*/
@Receive(Events.JS_OPEN_LOGOUT)
public void exit() {
Apollo.emit(Events.JS_OPEN_CLOSE_WEB);
finish();
Intent intent = new Intent(this, LoginActivity.class);
startActivity(intent);
}
}

View File

@ -0,0 +1,40 @@
package com.cmx.hydrology.activity;
import android.app.Application;
import android.content.Context;
import com.lsxiao.apollo.core.Apollo;
import io.reactivex.android.schedulers.AndroidSchedulers;
public class MyApplication extends Application {
private static MyApplication mInstance;
private static String mToken;
@Override
public void onCreate() {
super.onCreate();
mInstance = this;
Apollo.init(AndroidSchedulers.mainThread(), this);
}
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
}
public static MyApplication getmInstance() {
return mInstance;
}
public static String getmToken() {
return mToken;
}
public static void setmToken(String mToken) {
MyApplication.mToken = mToken;
}
}

View File

@ -0,0 +1,179 @@
package com.cmx.hydrology.activity;
import android.app.Activity;
import android.content.ClipData;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import androidx.annotation.Nullable;
import com.cmx.hydrology.databinding.ActivityWebBinding;
import com.cmx.hydrology.utils.AndroidtoJs;
import com.cmx.hydrology.utils.L;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class WebActivity extends BaseActivity {
private WebView mWebView;
private ActivityWebBinding binding;
private String url;
public static final int REQUEST_CODE_LIVENESS = 209;
public static final int TRUST_LEVEL = 50;
private ValueCallback<Uri[]> mUploadMessage;
private String mCameraPhotoPath = null;
private long size = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityWebBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
url = getIntent().getStringExtra("url");
// MyUtils.setFullscreen(this, true, true);//影响键盘 模式 页面遮挡
// MyUtils.setAndroidNativeLightStatusBar(this, true);//影响键盘 模式 页面遮挡
mWebView = binding.wvRegister;
WebSettings webSettings = mWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
webSettings.setDomStorageEnabled(true);
mWebView.addJavascriptInterface(new AndroidtoJs(), "AndroidtoJs");
mWebView.loadUrl(url);
showDialog();
setWeb(mWebView);
mWebView.setWebChromeClient(new PQChromeClient());
}
// @Receive(Events.JS_OPEN_CLOSE_WEB)
// public void fin() {
// finish();
// }
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 101 && mUploadMessage != null) {
try {
String file_path = mCameraPhotoPath.replace("file:", "");
File file = new File(file_path);
size = file.length();
if (!(data != null || size > 0)) {
mUploadMessage.onReceiveValue(null);
mUploadMessage = null;
return;
}
if (data != null || mCameraPhotoPath != null) {
Integer count = 1;
ClipData images = null;
try {
images = data.getClipData();
} catch (Exception e) {
Log.e("Error11!", e.getLocalizedMessage());
}
if (images == null && data != null && data.getDataString() != null) {
count = data.getDataString().length();
} else if (images != null) {
count = images.getItemCount();
}
Uri[] results = new Uri[count];
// Check that the response is a good one
if (resultCode == Activity.RESULT_OK) {
if (size != 0) {
// If there is not data, then we may have taken a photo
if (mCameraPhotoPath != null) {
results = new Uri[]{Uri.parse(mCameraPhotoPath)};
}
} else if (data.getClipData() == null) {
results = new Uri[]{Uri.parse(data.getDataString())};
} else {
for (int i = 0; i < images.getItemCount(); i++) {
results[i] = images.getItemAt(i).getUri();
}
}
}
mUploadMessage.onReceiveValue(results);
mUploadMessage = null;
}
} catch (Exception e) {
Log.e("Error22!", "Error while opening image file" + e.getLocalizedMessage());
}
}
}
public class PQChromeClient extends WebChromeClient {
// For Android 5.0+
public boolean onShowFileChooser(WebView view, ValueCallback<Uri[]> filePath, WebChromeClient.FileChooserParams fileChooserParams) {
L.e("点击》》", "11");
// Double check that we don't have any existing callbacks
if (mUploadMessage != null) {
L.e("点击》》", "22");
mUploadMessage.onReceiveValue(null);
}
mUploadMessage = filePath;
Log.e("FileCooserParams => ", filePath.toString());
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
// Create the File where the photo should go
File photoFile = null;
try {
photoFile = createImageFile();
takePictureIntent.putExtra("PhotoPath", mCameraPhotoPath);
} catch (IOException ex) {
// Error occurred while creating the File
Log.e("test", "Unable to create Image File", ex);
}
// Continue only if the File was successfully created
if (photoFile != null) {
mCameraPhotoPath = "file:" + photoFile.getAbsolutePath();
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
} else {
takePictureIntent = null;
}
}
Intent contentSelectionIntent = new Intent(Intent.ACTION_GET_CONTENT);
contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE);
contentSelectionIntent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
contentSelectionIntent.setType("image/*");
Intent[] intentArray;
if (takePictureIntent != null) {
intentArray = new Intent[]{takePictureIntent};
} else {
intentArray = new Intent[2];
}
Intent chooserIntent = new Intent(Intent.ACTION_CHOOSER);
chooserIntent.putExtra(Intent.EXTRA_INTENT, contentSelectionIntent);
chooserIntent.putExtra(Intent.EXTRA_TITLE, "Image Chooser");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray);
startActivityForResult(Intent.createChooser(chooserIntent, "Select images"), 101);
return true;
}
}
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
File imageFile = File.createTempFile(imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */);
return imageFile;
}
}

View File

@ -0,0 +1,42 @@
package com.cmx.hydrology.constant
/**
* @author LIJIE
*/
interface Events {
companion object {
const val WEB_SERVER_URL = "http://8.222.137.126:80"
const val SERVER_URL = "http://192.168.110.174:8000"
/**
* tabbar显示
*/
const val JS_OPEN_TABBAR_SHOW = "js_open_tabbar_show"
/**
* tabbar隐藏
*/
const val JS_OPEN_TABBAR_HIDE = "js_open_tabbat_hide"
/**
* 打开一个新web界面
*/
const val JS_OPEN_OPEN_WEB = "js_open_open_web"
/**
* 关闭web界面
*/
const val JS_OPEN_CLOSE_WEB = "js_open_close_web"
/**
* 退出登录
*/
const val JS_OPEN_LOGOUT = "js_open_logout"
/**
* 切换tab
*/
const val JS_OPEN_TAB = "js_open_tab"
}
}

View File

@ -0,0 +1,22 @@
package com.cmx.hydrology.model;
public class LoginBean {
String username;
String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}

View File

@ -0,0 +1,51 @@
package com.cmx.hydrology.model;
public class LoginRes {
/**
* code : 0
* message :
* access_token : 1914936f8c87fddd11836ebebb65317bb7f57506
* is_admin : 1
*/
private int code;
private String message;
private String access_token;
private String is_admin;
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getAccess_token() {
return access_token;
}
public void setAccess_token(String access_token) {
this.access_token = access_token;
}
public String getIs_admin() {
return is_admin;
}
public void setIs_admin(String is_admin) {
this.is_admin = is_admin;
}
}

View File

@ -0,0 +1,47 @@
package com.cmx.hydrology.retrofit;
import com.google.gson.reflect.TypeToken;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Callback;
public class ApiRequtest<T> {
private static final String TAG = ApiRequtest.class.getSimpleName();
private TypeToken<T> mResultType;
public ApiRequtest (Call<ResponseBody> call, TypeToken<T> resultType, final ApiResponse.Listener<ApiResult<T>> listener, final ApiResponse.ErrorListener errorListener){
mResultType = resultType;
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, retrofit2.Response<ResponseBody> response) {
try {
ResponseBody responseBody = response.body();
if(responseBody != null){
String jsonString = response.body().string();
final ApiResult<T> result = new ApiResult<>(new JSONObject(jsonString), mResultType);
listener.onResponse(result);
}
}catch (IOException e){
}catch (JSONException e) {
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
errorListener.onErrorResponse(t);
}
});
}
}

View File

@ -0,0 +1,19 @@
package com.cmx.hydrology.retrofit;
public class ApiResponse<T> {
/**
* network request error response
*/
public interface ErrorListener {
void onErrorResponse(Throwable requestError);
}
/**
* network request success response result
* @param <T> data result
*/
public interface Listener<T> {
void onResponse(T result);
}
}

View File

@ -0,0 +1,104 @@
package com.cmx.hydrology.retrofit;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import org.json.JSONObject;
/**
*
*/
public class ApiResult<T> {
private final static String TAG = ApiResult.class.getSimpleName();
public static final int OK = 0;
public Boolean success = true;
private Integer code = OK;
private String msg="";
private T result;
private String msgJson;
private static Gson gson = new Gson();
public ApiResult() {
super();
// TODO Auto-generated constructor stub
}
public ApiResult(JSONObject jsonObject, TypeToken<T> typeToken) {
super();
try{
if (jsonObject.has("errcode")){
code = jsonObject.getInt("errcode");
if (code != OK) {
if (jsonObject.has("errmsg")) {
msg = jsonObject.getString("errmsg");
}
success = false;
}
}else{
}
if (code == OK){
try {
result = gson.fromJson(jsonObject.toString(), typeToken.getType());
}catch (Exception ex){
}
}
}catch (Exception e) {
// TODO: handle exception
}
}
private T testDefault(String msg){
Gson gson = new Gson();
result = gson.fromJson(msg,new TypeToken<T>(){}.getType());
return result;
}
private T test(String msg, TypeToken<T> typeToken){
Gson gson = new Gson();
result = gson.fromJson(msg,typeToken.getType());
return result;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public T getResult() {
return result;
}
public void setResult(T result) {
this.result = result;
}
public Boolean getSuccess() {
return success;
}
public void setSuccess(Boolean success) {
this.success = success;
}
public String getMsgJson() {
return msgJson;
}
}

View File

@ -0,0 +1,22 @@
package com.cmx.hydrology.retrofit;
import com.cmx.hydrology.model.LoginBean;
import com.cmx.hydrology.model.LoginRes;
import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.POST;
/**
* Created by
*/
public interface ApiService {
/**
*
*
* @param body
* @return
*/
@POST("/login")
Call<LoginRes> login(@Body LoginBean body);
}

View File

@ -0,0 +1,71 @@
package com.cmx.hydrology.retrofit;
import static com.cmx.hydrology.constant.Events.SERVER_URL;
import android.util.Log;
import com.cmx.hydrology.activity.MyApplication;
import com.cmx.hydrology.utils.SpUtils;
import com.google.gson.reflect.TypeToken;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.concurrent.TimeUnit;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Call;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
/**
* Created by TTLock on 2018/9/5.
*/
public class RetrofitAPIManager {
public static ApiService provideClientApi() {
Retrofit retrofit = new Retrofit.Builder().client(genericClient()).baseUrl(SERVER_URL).addConverterFactory(GsonConverterFactory.create()).build();
return retrofit.create(ApiService.class);
}
public static OkHttpClient genericClient() {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
@Override
public void log(String message) {
// try {
// String text = URLDecoder.decode(message, "utf-8");
// Log.e("OKHttp-----", text);
// } catch (UnsupportedEncodingException e) {
// e.printStackTrace();
Log.e("OKHttp-----", message);
// }
}
});
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient httpClient = new OkHttpClient.Builder().connectTimeout(35, TimeUnit.SECONDS).readTimeout(35, TimeUnit.SECONDS).writeTimeout(35, TimeUnit.SECONDS).addInterceptor(interceptor).addInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request original = chain.request();
Request.Builder requestBuilder = original.newBuilder().header("token", SpUtils.getString(MyApplication.getmInstance(), "token"));
Request request = requestBuilder.build();
return chain.proceed(request);
}
}).build();
return httpClient;
}
public static <T> ApiRequtest enqueue(Call<ResponseBody> call, TypeToken<T> resultType, ApiResponse.Listener<ApiResult<T>> listener, ApiResponse.ErrorListener errorListener) {
ApiRequtest<T> request = new ApiRequtest<>(call, resultType, listener, errorListener);
return request;
}
}

View File

@ -0,0 +1,9 @@
package com.cmx.hydrology.retrofit;
/**
* Created by Administrator on 2018/1/17 0017.
*/
public interface onRequestResponse {
void onResult(boolean success);
}

View File

@ -0,0 +1,9 @@
package com.cmx.hydrology.retrofit;
/**
* Created by Administrator on 2018/1/17 0017.
*/
public interface onServerRequestCallBack {
void onResult(int resultCode);
}

View File

@ -0,0 +1,226 @@
package com.cmx.hydrology.ui;
import android.app.Activity;
import android.content.ClipData;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebResourceError;
import android.webkit.WebResourceRequest;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import com.cmx.hydrology.databinding.FragmentHomeBinding;
import com.cmx.hydrology.utils.AndroidtoJs;
import com.cmx.hydrology.utils.MyUtils;
import com.cmx.hydrology.view.BaseLoadingDialog;
import com.lsxiao.apollo.core.Apollo;
import com.lsxiao.apollo.core.contract.ApolloBinder;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class HomeFragment extends Fragment {
private FragmentHomeBinding binding;
private BaseLoadingDialog mBaseLoadingDialog;
private WebView mWebView;
private ApolloBinder mApolloBinder;
private ValueCallback<Uri[]> mUploadMessage;
private String mCameraPhotoPath = null;
private long size = 0;
private static final int INPUT_FILE_REQUEST_CODE = 1;
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
binding = FragmentHomeBinding.inflate(inflater, container, false);
mBaseLoadingDialog = new BaseLoadingDialog(getActivity());
View root = binding.getRoot();
MyUtils.setFullscreen(requireActivity(), false, false);
MyUtils.setAndroidNativeLightStatusBar(requireActivity(), true);
mWebView = binding.wvHome;
mApolloBinder = Apollo.bind(this);
WebSettings webSettings = mWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
webSettings.setDomStorageEnabled(true);
webSettings.setAllowFileAccess(true);//文件访问
webSettings.setAllowFileAccessFromFileURLs(true);
mWebView.addJavascriptInterface(new AndroidtoJs(), "AndroidtoJs");
mWebView.loadUrl("https://cmx.bskies.cc:8000/cmx-hydrology-h5/#/home");
showDialog();
mWebView.setWebChromeClient(new PQChromeClient());
mWebView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
//使用WebView加载显示url
view.loadUrl(url);
//返回true
return true;
}
@Override
public void onPageFinished(WebView view, String url) {
disDialog();
}
@Override
public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
disDialog();
}
}
);
return root;
}
@Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
if (mApolloBinder != null) {
mApolloBinder.unbind();
}
}
public void showDialog() {
mBaseLoadingDialog = new BaseLoadingDialog(getActivity());
if (!mBaseLoadingDialog.isShowing()) {
mBaseLoadingDialog.show();
}
}
public void disDialog() {
if (mBaseLoadingDialog.isShowing()) {
mBaseLoadingDialog.dismiss();
}
}
public class PQChromeClient extends WebChromeClient {
// For Android 5.0+
public boolean onShowFileChooser(WebView view, ValueCallback<Uri[]> filePath, WebChromeClient.FileChooserParams fileChooserParams) {
// Double check that we don't have any existing callbacks
if (mUploadMessage != null) {
mUploadMessage.onReceiveValue(null);
}
mUploadMessage = filePath;
Log.e("FileCooserParams => ", filePath.toString());
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getActivity().getPackageManager()) != null) {
// Create the File where the photo should go
File photoFile = null;
try {
photoFile = createImageFile();
takePictureIntent.putExtra("PhotoPath", mCameraPhotoPath);
} catch (IOException ex) {
// Error occurred while creating the File
Log.e("test", "Unable to create Image File", ex);
}
// Continue only if the File was successfully created
if (photoFile != null) {
mCameraPhotoPath = "file:" + photoFile.getAbsolutePath();
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
} else {
takePictureIntent = null;
}
}
Intent contentSelectionIntent = new Intent(Intent.ACTION_GET_CONTENT);
contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE);
contentSelectionIntent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
contentSelectionIntent.setType("image/*");
Intent[] intentArray;
if (takePictureIntent != null) {
intentArray = new Intent[]{takePictureIntent};
} else {
intentArray = new Intent[2];
}
Intent chooserIntent = new Intent(Intent.ACTION_CHOOSER);
chooserIntent.putExtra(Intent.EXTRA_INTENT, contentSelectionIntent);
chooserIntent.putExtra(Intent.EXTRA_TITLE, "Image Chooser");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray);
startActivityForResult(Intent.createChooser(chooserIntent, "Select images"), 1);
return true;
}
}
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
File imageFile = File.createTempFile(imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */);
return imageFile;
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode != INPUT_FILE_REQUEST_CODE || mUploadMessage == null) {
super.onActivityResult(requestCode, resultCode, data);
return;
}
try {
String file_path = mCameraPhotoPath.replace("file:", "");
File file = new File(file_path);
size = file.length();
if (data != null || mCameraPhotoPath != null) {
Integer count = 1;
ClipData images = null;
try {
images = data.getClipData();
} catch (Exception e) {
Log.e("Error!", e.getLocalizedMessage());
}
if (images == null && data != null && data.getDataString() != null) {
count = data.getDataString().length();
} else if (images != null) {
count = images.getItemCount();
}
Uri[] results = new Uri[count];
// Check that the response is a good one
if (resultCode == Activity.RESULT_OK) {
if (size != 0) {
// If there is not data, then we may have taken a photo
if (mCameraPhotoPath != null) {
results = new Uri[]{Uri.parse(mCameraPhotoPath)};
}
} else if (data.getClipData() == null) {
results = new Uri[]{Uri.parse(data.getDataString())};
} else {
for (int i = 0; i < images.getItemCount(); i++) {
results[i] = images.getItemAt(i).getUri();
}
}
}
mUploadMessage.onReceiveValue(results);
mUploadMessage = null;
}
} catch (Exception e) {
Log.e("Error!", "Error while opening image file" + e.getLocalizedMessage());
}
}
}

View File

@ -0,0 +1,93 @@
package com.cmx.hydrology.ui;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebResourceError;
import android.webkit.WebResourceRequest;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import com.cmx.hydrology.databinding.FragmentMapBinding;
import com.cmx.hydrology.utils.AndroidtoJs;
import com.cmx.hydrology.utils.MyUtils;
import com.cmx.hydrology.view.BaseLoadingDialog;
import com.lsxiao.apollo.core.Apollo;
import com.lsxiao.apollo.core.contract.ApolloBinder;
public class MapFragment extends Fragment {
private FragmentMapBinding binding;
private BaseLoadingDialog mBaseLoadingDialog;
private WebView mWebView;
private ApolloBinder mApolloBinder;
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
binding = FragmentMapBinding.inflate(inflater, container, false);
mBaseLoadingDialog = new BaseLoadingDialog(getActivity());
View root = binding.getRoot();
mApolloBinder = Apollo.bind(this);
MyUtils.setFullscreen(requireActivity(), false, false);
MyUtils.setAndroidNativeLightStatusBar(requireActivity(), true);
mWebView = binding.wvMine;
WebSettings webSettings = mWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
webSettings.setDomStorageEnabled(true);
mWebView.addJavascriptInterface(new AndroidtoJs(), "AndroidtoJs");
// mWebView.loadUrl(SERVER_URL + "/nigeria/?lang=English#/my");
// showDialog();
mWebView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
//使用WebView加载显示url
view.loadUrl(url);
//返回true
return true;
}
@Override
public void onPageFinished(WebView view, String url) {
disDialog();
}
@Override
public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
disDialog();
}
}
);
return root;
}
@Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
if (mApolloBinder != null) {
mApolloBinder.unbind();
}
}
public void showDialog() {
mBaseLoadingDialog = new BaseLoadingDialog(getActivity());
if (!mBaseLoadingDialog.isShowing()) {
mBaseLoadingDialog.show();
}
}
public void disDialog() {
if (mBaseLoadingDialog.isShowing()) {
mBaseLoadingDialog.dismiss();
}
}
}

View File

@ -0,0 +1,232 @@
package com.cmx.hydrology.ui;
import android.app.Activity;
import android.content.ClipData;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebResourceError;
import android.webkit.WebResourceRequest;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import com.cmx.hydrology.databinding.FragmentMsgBinding;
import com.cmx.hydrology.utils.AndroidtoJs;
import com.cmx.hydrology.utils.MyUtils;
import com.cmx.hydrology.view.BaseLoadingDialog;
import com.lsxiao.apollo.core.Apollo;
import com.lsxiao.apollo.core.contract.ApolloBinder;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class MsgFragment extends Fragment {
private FragmentMsgBinding binding;
private BaseLoadingDialog mBaseLoadingDialog;
private WebView mWebView;
private ApolloBinder mApolloBinder;
private ValueCallback<Uri[]> mUploadMessage;
private String mCameraPhotoPath = null;
private long size = 0;
private static final int INPUT_FILE_REQUEST_CODE = 1;
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
binding = FragmentMsgBinding.inflate(inflater, container, false);
mBaseLoadingDialog = new BaseLoadingDialog(getActivity());
View root = binding.getRoot();
MyUtils.setFullscreen(requireActivity(), false, false);
MyUtils.setAndroidNativeLightStatusBar(requireActivity(), true);
mWebView = binding.wvLoan;
mApolloBinder = Apollo.bind(this);
WebSettings webSettings = mWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
webSettings.setDomStorageEnabled(true);
webSettings.setAllowFileAccess(true);//文件访问
webSettings.setAllowFileAccessFromFileURLs(true);
mWebView.addJavascriptInterface(new AndroidtoJs(), "AndroidtoJs");
// mWebView.loadUrl(SERVER_URL + "/nigeria/?lang=English#/loans");
// showDialog();
mWebView.setWebChromeClient(new PQChromeClient());
mWebView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
//使用WebView加载显示url
view.loadUrl(url);
//返回true
return true;
}
@Override
public void onPageFinished(WebView view, String url) {
disDialog();
}
@Override
public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
disDialog();
}
}
);
return root;
}
@Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
if (mApolloBinder != null) {
mApolloBinder.unbind();
}
}
public void showDialog() {
mBaseLoadingDialog = new BaseLoadingDialog(getActivity());
if (!mBaseLoadingDialog.isShowing()) {
mBaseLoadingDialog.show();
}
}
public void disDialog() {
if (mBaseLoadingDialog.isShowing()) {
mBaseLoadingDialog.dismiss();
}
}
public class PQChromeClient extends WebChromeClient {
// For Android 5.0+
public boolean onShowFileChooser(WebView view, ValueCallback<Uri[]> filePath, WebChromeClient.FileChooserParams fileChooserParams) {
// Double check that we don't have any existing callbacks
if (mUploadMessage != null) {
mUploadMessage.onReceiveValue(null);
}
mUploadMessage = filePath;
Log.e("FileCooserParams => ", filePath.toString());
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getActivity().getPackageManager()) != null) {
// Create the File where the photo should go
File photoFile = null;
try {
photoFile = createImageFile();
takePictureIntent.putExtra("PhotoPath", mCameraPhotoPath);
} catch (IOException ex) {
// Error occurred while creating the File
Log.e("test", "Unable to create Image File", ex);
}
// Continue only if the File was successfully created
if (photoFile != null) {
mCameraPhotoPath = "file:" + photoFile.getAbsolutePath();
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
} else {
takePictureIntent = null;
}
}
Intent contentSelectionIntent = new Intent(Intent.ACTION_GET_CONTENT);
contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE);
contentSelectionIntent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
contentSelectionIntent.setType("image/*");
Intent[] intentArray;
if (takePictureIntent != null) {
intentArray = new Intent[]{takePictureIntent};
} else {
intentArray = new Intent[2];
}
Intent chooserIntent = new Intent(Intent.ACTION_CHOOSER);
chooserIntent.putExtra(Intent.EXTRA_INTENT, contentSelectionIntent);
chooserIntent.putExtra(Intent.EXTRA_TITLE, "Image Chooser");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray);
startActivityForResult(Intent.createChooser(chooserIntent, "Select images"), 1);
return true;
}
}
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
File imageFile = File.createTempFile(imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */);
return imageFile;
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode != INPUT_FILE_REQUEST_CODE || mUploadMessage == null) {
super.onActivityResult(requestCode, resultCode, data);
return;
}
try {
String file_path = mCameraPhotoPath.replace("file:", "");
File file = new File(file_path);
size = file.length();
} catch (Exception e) {
Log.e("Error!", "Error while opening image file" + e.getLocalizedMessage());
}
if (data != null || mCameraPhotoPath != null) {
Integer count = 1;
ClipData images = null;
try {
images = data.getClipData();
} catch (Exception e) {
Log.e("Error!", e.getLocalizedMessage());
}
if (images == null && data != null && data.getDataString() != null) {
count = data.getDataString().length();
} else if (images != null) {
count = images.getItemCount();
}
Uri[] results = new Uri[count];
// Check that the response is a good one
if (resultCode == Activity.RESULT_OK) {
if (size != 0) {
// If there is not data, then we may have taken a photo
if (mCameraPhotoPath != null) {
results = new Uri[]{Uri.parse(mCameraPhotoPath)};
}
} else if (data.getClipData() == null) {
results = new Uri[]{Uri.parse(data.getDataString())};
} else {
for (int i = 0; i < images.getItemCount(); i++) {
results[i] = images.getItemAt(i).getUri();
}
}
}
mUploadMessage.onReceiveValue(results);
mUploadMessage = null;
}
}
}

View File

@ -0,0 +1,93 @@
package com.cmx.hydrology.ui;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebResourceError;
import android.webkit.WebResourceRequest;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import com.cmx.hydrology.databinding.FragmentMyBinding;
import com.cmx.hydrology.utils.AndroidtoJs;
import com.cmx.hydrology.utils.MyUtils;
import com.cmx.hydrology.view.BaseLoadingDialog;
import com.lsxiao.apollo.core.Apollo;
import com.lsxiao.apollo.core.contract.ApolloBinder;
public class MyFragment extends Fragment {
private FragmentMyBinding binding;
private BaseLoadingDialog mBaseLoadingDialog;
private WebView mWebView;
private ApolloBinder mApolloBinder;
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
binding = FragmentMyBinding.inflate(inflater, container, false);
mBaseLoadingDialog = new BaseLoadingDialog(getActivity());
View root = binding.getRoot();
mApolloBinder = Apollo.bind(this);
MyUtils.setFullscreen(requireActivity(), false, false);
MyUtils.setAndroidNativeLightStatusBar(requireActivity(), true);
mWebView = binding.wvMine;
WebSettings webSettings = mWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
webSettings.setDomStorageEnabled(true);
mWebView.addJavascriptInterface(new AndroidtoJs(), "AndroidtoJs");
// mWebView.loadUrl(SERVER_URL + "/nigeria/?lang=English#/my");
// showDialog();
mWebView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
//使用WebView加载显示url
view.loadUrl(url);
//返回true
return true;
}
@Override
public void onPageFinished(WebView view, String url) {
disDialog();
}
@Override
public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
disDialog();
}
}
);
return root;
}
@Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
if (mApolloBinder != null) {
mApolloBinder.unbind();
}
}
public void showDialog() {
mBaseLoadingDialog = new BaseLoadingDialog(getActivity());
if (!mBaseLoadingDialog.isShowing()) {
mBaseLoadingDialog.show();
}
}
public void disDialog() {
if (mBaseLoadingDialog.isShowing()) {
mBaseLoadingDialog.dismiss();
}
}
}

View File

@ -0,0 +1,89 @@
package com.cmx.hydrology.utils;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.util.Log;
import android.webkit.JavascriptInterface;
import com.cmx.hydrology.activity.MyApplication;
import com.cmx.hydrology.constant.Events;
import com.lsxiao.apollo.core.Apollo;
public class AndroidtoJs {
private static final String TAG = "cmx_AndroidtoJs";
// 定义JS需要调用的方法
// 被JS调用的方法必须加入@JavascriptInterface注解
@JavascriptInterface
public String getAppToken() {
L.e("JS--", "getAppToken()");
return SpUtils.getString(MyApplication.getmInstance(), "token");
}
/**
*
*
* @return
*/
@JavascriptInterface
public String getUser() {
L.e("JS--", "getUser()");
return SpUtils.getString(MyApplication.getmInstance(), "admin");
}
@JavascriptInterface
public String getAppVersion() {
L.e("JS--", "getAppVersion()");
String versionname;//版本号
try {
PackageManager pm = MyApplication.getmInstance().getApplicationContext().getPackageManager();
PackageInfo pi = pm.getPackageInfo(MyApplication.getmInstance().getApplicationContext().getPackageName(), 0);
versionname = "V" + pi.versionName;
} catch (PackageManager.NameNotFoundException e) {
versionname = "未知";
}
Log.e(TAG, "getAppVersion=" + versionname);
return versionname;
}
@JavascriptInterface
public void existApp() {
L.e("JS--", "existApp()");
Apollo.emit(Events.JS_OPEN_LOGOUT);
}
@JavascriptInterface
public void showTab() {//tabbar显示
L.e("JS--", "showTab()");
Apollo.emit(Events.JS_OPEN_TABBAR_SHOW);
}
@JavascriptInterface
public void hideTab() {//tabbar隐藏
L.e("JS--", "hideTab()");
Apollo.emit(Events.JS_OPEN_TABBAR_HIDE);
}
@JavascriptInterface
public void openWeb(String url) {//打开一个新的web界面
L.e("JS--", "openWeb()" + url);
Apollo.emit(Events.JS_OPEN_OPEN_WEB, url);
}
@JavascriptInterface
public void closeWeb() {//关闭那个新的web界面
L.e("JS--", "closeWeb()");
Apollo.emit(Events.JS_OPEN_CLOSE_WEB);
}
@JavascriptInterface
public void checkTab(String mode) {//关闭注册/忘记密码
L.e("JS--", "checkTab()");
Apollo.emit(Events.JS_OPEN_TAB, mode);
}
}

View File

@ -0,0 +1,92 @@
package com.cmx.hydrology.utils;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;
import android.provider.MediaStore;
import android.util.Base64;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListAdapter;
import android.widget.ListView;
import java.io.File;
import java.lang.reflect.Method;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class L {
private L() {
throw new UnsupportedOperationException("cannot be instantiated");
}
public static boolean isDebug = true;
private static String TAG = "LjTestLog";
public static String getTAG() {
return TAG;
}
public static void setTAG(String TAG) {
L.TAG = TAG;
}
public static void setDebugMode(boolean debug) {
isDebug = debug;
}
public static void i(String msg) {
if (isDebug)
Log.i(TAG, msg);
}
public static void d(String msg) {
if (isDebug)
Log.d(TAG, msg);
}
public static void e(String msg) {
if (isDebug)
Log.e(TAG, msg);
}
public static void v(String msg) {
if (isDebug)
Log.v(TAG, msg);
}
public static void i(String tag, String msg) {
if (isDebug)
Log.i(tag, msg);
}
public static void d(String tag, String msg) {
if (isDebug)
Log.d(tag, msg);
}
public static void e(String tag, String msg) {
if (isDebug)
Log.e(tag, msg);
}
public static void v(String tag, String msg) {
if (isDebug)
Log.v(tag, msg);
}
}

View File

@ -0,0 +1,220 @@
package com.cmx.hydrology.utils;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.graphics.Color;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.StatFs;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.Method;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Locale;
public class MyUtils {
private static final String TAG = "cmx_" + MyUtils.class.getSimpleName();
public static void setNavigationStatusColor(Activity activity, int color) {
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
activity.getWindow().setNavigationBarColor(color);
activity.getWindow().setStatusBarColor(color);
}
public static void setFullscreen(Activity activity, boolean isShowStatusBar, boolean isShowNavigationBar) {
int uiOptions = View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
if (!isShowStatusBar) {
uiOptions |= View.SYSTEM_UI_FLAG_FULLSCREEN;
}
if (!isShowNavigationBar) {
uiOptions |= View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
}
activity.getWindow().getDecorView().setSystemUiVisibility(uiOptions);
setNavigationStatusColor(activity, Color.TRANSPARENT);
}
public static void setAndroidNativeLightStatusBar(Activity activity, boolean dark) {
View decor = activity.getWindow().getDecorView();
if (dark) {
decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
} else {
decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
}
}
private static String getVersionName(Activity activity) throws Exception {
PackageManager packageManager = activity.getPackageManager();
// getPackageName()是你当前类的包名0代表是获取版本信息
PackageInfo packInfo = packageManager.getPackageInfo(activity.getPackageName(), 0);
String version = packInfo.versionName;
return version;
}
public static void getDeviceInfo(Activity activity) throws Exception {
String model = android.os.Build.MODEL;
String carrier = android.os.Build.MANUFACTURER;
String version = getVersionName(activity);
String lang = getSystemLanguage();
String brand = getPhoneBrand();
String releaseVersion = getVersionRelease();
int sdkVersion = getSdkVersion();
Log.e(TAG, "model=" + model + ", carrier=" + carrier + ", version=" + version + ", lang=" + lang + ", brand=" + brand + ", releaseVersion=" + releaseVersion + ",sdk version=" + sdkVersion);
}
public static String getSystemLanguage() {
return Locale.getDefault().getLanguage();
}
public static Locale[] getSystemLanguageList() {
return Locale.getAvailableLocales();
}
public static String getPhoneBrand() {
return Build.BRAND;
}
public static String getVersionRelease() {
return Build.VERSION.RELEASE;
}
public static int getSdkVersion() {
return Build.VERSION.SDK_INT;
}
public static String getSerialNum() {
String serial = "unknown";
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {//9.0+
serial = Build.getSerial();
} else if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N) {//8.0+
serial = Build.SERIAL;
} else {//8.0-
Class<?> c = Class.forName("android.os.SystemProperties");
Method get = c.getMethod("get", String.class);
serial = (String) get.invoke(c, "ro.serialno");
}
} catch (Exception e) {
Log.e("序列号》》", e.toString());
e.printStackTrace();
}
Log.e("序列号》》", serial);
return serial;
}
public static File createTempImageFile(Context context) {
File destFolder = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
destFolder.mkdirs();
String dateTimeString = System.currentTimeMillis() + "";
File imageFile = null;
try {
imageFile = File.createTempFile(dateTimeString + "-", ".jpg", destFolder);
} catch (IOException e) {
Log.e("文件失败>>>", e.toString());
throw new RuntimeException(e);
}
return imageFile;
}
public static String getTotalRam() {
String path = "/proc/meminfo";
String ramMemorySize = null;
int totalRam = 0;
try {
FileReader fileReader = new FileReader(path);
BufferedReader br = new BufferedReader(fileReader, 4096);
ramMemorySize = br.readLine().split("\\s+")[1];
br.close();
} catch (Exception e) {
e.printStackTrace();
}
if (ramMemorySize != null) {
totalRam = (int) Math.ceil((Float.valueOf(Float.parseFloat(ramMemorySize) / (1024 * 1024)).doubleValue()));
}
return totalRam + "";
}
public static String getTotalRom() {
File dataDir = Environment.getDataDirectory();
StatFs stat = new StatFs(dataDir.getPath());
long blockSize = stat.getBlockSizeLong();
long totalBlocks = stat.getBlockCountLong();
long size = totalBlocks * blockSize;
long GB = 1024 * 1024 * 1024;
final long[] deviceRomMemoryMap = {2 * GB, 4 * GB, 8 * GB, 16 * GB, 32 * GB, 64 * GB, 128 * GB, 256 * GB, 512 * GB, 1024 * GB, 2048 * GB};
String[] displayRomSize = {"2GB", "4GB", "8GB", "16GB", "32GB", "64GB", "128GB", "256GB", "512GB", "1024GB", "2048GB"};
int i;
for (i = 0; i < deviceRomMemoryMap.length; i++) {
if (size <= deviceRomMemoryMap[i]) {
break;
}
if (i == deviceRomMemoryMap.length) {
i--;
}
}
return displayRomSize[i].replace("GB", "");
}
/**
* sha256
*
* @param str
* @return
*/
public static String getSha256Str(String str) {
MessageDigest messageDigest;
String encodeStr = "";
try {
messageDigest = MessageDigest.getInstance("SHA-256");
messageDigest.update(str.getBytes(StandardCharsets.UTF_8));
encodeStr = byte2Hex(messageDigest.digest());
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return encodeStr;
}
/**
* sha256 byte16
*
* @param bytes
* @return
*/
private static String byte2Hex(byte[] bytes) {
StringBuilder stringBuilder = new StringBuilder();
String temp;
for (byte aByte : bytes) {
temp = Integer.toHexString(aByte & 0xFF);
if (temp.length() == 1) {
//1得到一位的进行补0操作
stringBuilder.append("0");
}
stringBuilder.append(temp);
}
return stringBuilder.toString();
}
}

View File

@ -0,0 +1,24 @@
package com.cmx.hydrology.utils;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.view.WindowManager;
public class SpUtils {
private static final String SP_NAME = "SP_USER_DATA";
public static void putString(Context context, String key, String val) {
SharedPreferences sp = context.getSharedPreferences(SP_NAME, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.putString(key, val);
editor.commit();
}
public static String getString(Context context, String key) {
SharedPreferences sp = context.getSharedPreferences(SP_NAME, Context.MODE_PRIVATE);
return sp.getString(key, "");
}
}

View File

@ -0,0 +1,8 @@
package com.cmx.hydrology.utils;
public class StaticFinalData {
public static final String LOGOUT = "LOGOUT";
public static final String UPLOAD_FACE = "UPLOAD_FACE";
public static final String UPLOAD_FACE_OVER = "UPLOAD_FACE_OVER";
public static final String CHANGE_TAB = "CHANGE_TAB";
}

View File

@ -0,0 +1,37 @@
package com.cmx.hydrology.view;
import android.animation.ObjectAnimator;
import android.app.Dialog;
import android.content.Context;
import android.os.Bundle;
import android.view.animation.LinearInterpolator;
import android.widget.ImageView;
import com.cmx.hydrology.R;
public class BaseLoadingDialog extends Dialog {
private ImageView load;
public BaseLoadingDialog(Context context) {
super(context, R.style.CustomDialog);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.dialog_confirm);
load = findViewById(R.id.iv_load);
ObjectAnimator animator = ObjectAnimator.ofFloat(load, "rotationY", 0, 360);
animator.setDuration(3000);
animator.setInterpolator(new LinearInterpolator());
animator.setRepeatCount(-1);
animator.start();
setCancelable(true);
setCanceledOnTouchOutside(true);
}
}

View File

@ -0,0 +1,30 @@
<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:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
<aapt:attr name="android:fillColor">
<gradient
android:endX="85.84757"
android:endY="92.4963"
android:startX="42.9492"
android:startY="49.59793"
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="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
android:strokeWidth="1"
android:strokeColor="#00000000" />
</vector>

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
</selector>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<size android:width="1dp" />
<solid android:color="#08CD49" />
</shape>
</item>
</layer-list>

View File

@ -0,0 +1,5 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#ff333333" />
<corners android:radius="5dp" />
</shape>

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<solid android:color="#ffeff8f3" />
<corners
android:bottomLeftRadius="10dp"
android:bottomRightRadius="10dp"
android:topLeftRadius="10dp"
android:topRightRadius="10dp" />
<stroke
android:width="1dip"
android:color="@color/base_col" />
</shape>
</item>
</layer-list>

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<solid android:color="#fffafafa" />
<corners
android:bottomLeftRadius="10dp"
android:bottomRightRadius="10dp"
android:topLeftRadius="10dp"
android:topRightRadius="10dp" />
<stroke
android:width="1dip"
android:color="#D8D8D8" />
</shape>
</item>
</layer-list>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M3,13h8L11,3L3,3v10zM3,21h8v-6L3,15v6zM13,21h8L21,11h-8v10zM13,3v6h8L21,3h-8z" />
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M10,20v-6h4v6h5v-8h3L12,3 2,12h3v8z" />
</vector>

View File

@ -0,0 +1,170 @@
<?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="#3DDC84"
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>

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
android:angle="-90"
android:endColor="@color/base_col"
android:startColor="@color/base_col"
android:type="linear"
android:useLevel="true" />
<corners android:radius="8dp" />
</shape>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M12,22c1.1,0 2,-0.9 2,-2h-4c0,1.1 0.89,2 2,2zM18,16v-5c0,-3.07 -1.64,-5.64 -4.5,-6.32L13.5,4c0,-0.83 -0.67,-1.5 -1.5,-1.5s-1.5,0.67 -1.5,1.5v0.68C7.63,5.36 6,7.92 6,11v5l-2,2v1h16v-1l-2,-2z" />
</vector>

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:angle="-90"
android:endColor="#ff3fe77d"
android:startColor="#ff00be47"
android:type="linear"
android:useLevel="true" />
<corners
android:bottomLeftRadius="47dp"
android:bottomRightRadius="47dp"
android:topLeftRadius="47dp"
android:topRightRadius="47dp" />
</shape>

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<stroke
android:width="1dip"
android:color="#B1B2B2" />
<solid android:color="@color/white" />
<corners
android:bottomLeftRadius="47dp"
android:bottomRightRadius="47dp"
android:topLeftRadius="47dp"
android:topRightRadius="47dp" />
</shape>

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!--获取到焦点状态-->
<item android:drawable="@drawable/edittext_active_sharp" android:state_focused="true" />
<!--默认状态-->
<item android:drawable="@drawable/edittext_normal_sharp" />
</selector>

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!--获取到焦点状态-->
<item android:drawable="@drawable/round_btn_sharp" android:state_focused="true" />
<!--默认状态-->
<item android:drawable="@drawable/round_btn_sharp" />
</selector>

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="55dp"
>
<TextView
android:id="@+id/action_bar_title"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="注册"
android:textColor="@android:color/black"
android:textSize="16sp"
android:gravity="center"
android:layout_marginEnd="55dp"/>
</LinearLayout>

View File

@ -0,0 +1,47 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_marginTop="28dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="User Agreement"
android:textSize="24sp"
android:textStyle="bold" />
<ImageView
android:id="@+id/tv_title_back"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginLeft="5dp"
android:padding="8dp"
android:src="@mipmap/icon_title_back" />
</RelativeLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="15dp"
android:text="@string/user_agreement_det"
android:textSize="16sp" />
</ScrollView>
</LinearLayout>

View File

@ -0,0 +1,96 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="280dp">
<com.scwang.wave.MultiWaveHeader
android:id="@+id/waveHeader"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:mwhCloseColor="@color/base_col"
app:mwhStartColor="@color/base_col"
app:mwhVelocity="5" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:layout_width="60dp"
android:layout_height="60dp"
android:src="@mipmap/icon_logo" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="10dp"
android:text="水文数字孪生"
android:textColor="@color/white"
android:textSize="22sp" />
<View
android:layout_width="match_parent"
android:layout_height="50dp" />
</LinearLayout>
</RelativeLayout>
<EditText
android:id="@+id/edt_username"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_marginStart="30dp"
android:layout_marginTop="60dp"
android:layout_marginEnd="30dp"
android:background="@drawable/selector_edit_text"
android:cursorVisible="true"
android:drawablePadding="10dp"
android:hint="请输入用户名"
android:paddingStart="10dip"
android:singleLine="true"
android:textColorHint="#919191"
android:textSize="16sp" />
<EditText
android:id="@+id/edt_password"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_marginStart="30dp"
android:layout_marginTop="35dp"
android:layout_marginEnd="30dp"
android:background="@drawable/selector_edit_text"
android:cursorVisible="true"
android:drawablePadding="10dp"
android:hint="请输入密码"
android:inputType="textPassword"
android:paddingStart="10dip"
android:singleLine="true"
android:textColorHint="#919191"
android:textSize="16sp" />
<Button
android:id="@+id/btn_login"
android:layout_width="match_parent"
android:layout_height="54dp"
android:layout_marginLeft="30dp"
android:layout_marginTop="80dp"
android:layout_marginRight="30dp"
android:layout_marginBottom="30dp"
android:background="@drawable/ic_login_bg"
android:text="登 录"
android:textColor="@android:color/white"
android:textSize="18sp" />
</LinearLayout>

View File

@ -0,0 +1,34 @@
<?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:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="32dp">
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/nav_view"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="0dp"
android:layout_marginEnd="0dp"
android:background="?android:attr/windowBackground"
app:labelVisibilityMode="labeled"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:menu="@menu/bottom_nav_menu" />
<fragment
android:id="@+id/nav_host_fragment_activity_main"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:layout_constraintBottom_toTopOf="@id/nav_view"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="@navigation/mobile_navigation" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".activity.RegisterActivity">
<LinearLayout
android:id="@+id/ll_register"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="32dp"
android:orientation="vertical">
<WebView
android:id="@+id/wv_register"
android:layout_width="match_parent"
android:layout_height="match_parent">
</WebView>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,9 @@
<?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"
tools:context=".activity.RegisterSuccessActivity">
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<WebView
android:id="@+id/wv_register"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>

View File

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
android:gravity="center"
android:orientation="vertical"
android:paddingLeft="60dp"
android:paddingRight="60dp">
<ImageView
android:id="@+id/iv_load"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_marginTop="40dp"
android:scaleType="fitXY"
android:src="@mipmap/icon_logo" />
<TextView
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_marginTop="10dp"
android:layout_marginBottom="20dp"
android:gravity="center"
android:text="loading ..."
android:textColor="@color/black"
android:textSize="16sp" />
</LinearLayout>

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/ll_home"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<WebView
android:id="@+id/wv_home"
android:layout_width="match_parent"
android:layout_height="match_parent">
</WebView>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,21 @@
<?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"
tools:context=".ui.MapFragment">
<LinearLayout
android:id="@+id/ll_mine"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<WebView
android:id="@+id/wv_mine"
android:layout_width="match_parent"
android:layout_height="match_parent">
</WebView>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,21 @@
<?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"
tools:context=".ui.MsgFragment">
<LinearLayout
android:id="@+id/ll_loan"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<WebView
android:id="@+id/wv_loan"
android:layout_width="match_parent"
android:layout_height="match_parent">
</WebView>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,21 @@
<?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"
tools:context=".ui.MapFragment">
<LinearLayout
android:id="@+id/ll_mine"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<WebView
android:id="@+id/wv_mine"
android:layout_width="match_parent"
android:layout_height="match_parent">
</WebView>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/navigation_home"
android:icon="@drawable/ic_home_black_24dp"
android:title="站点" />
<item
android:id="@+id/navigation_msg"
android:icon="@drawable/ic_dashboard_black_24dp"
android:title="消息" />
<item
android:id="@+id/navigation_map"
android:icon="@drawable/ic_notifications_black_24dp"
android:title="地图" />
<item
android:id="@+id/navigation_my"
android:icon="@drawable/ic_notifications_black_24dp"
android:title="我的" />
</menu>

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<navigation 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:id="@+id/mobile_navigation"
app:startDestination="@+id/navigation_home">
<fragment
android:id="@+id/navigation_home"
android:name="com.cmx.hydrology.ui.HomeFragment"
android:label="站点"
tools:layout="@layout/fragment_home" />
<fragment
android:id="@+id/navigation_msg"
android:name="com.cmx.hydrology.ui.MsgFragment"
android:label="消息"
tools:layout="@layout/fragment_msg" />
<fragment
android:id="@+id/navigation_map"
android:name="com.cmx.hydrology.ui.MapFragment"
android:label="地图"
tools:layout="@layout/fragment_map" />
<fragment
android:id="@+id/navigation_my"
android:name="com.cmx.hydrology.ui.MyFragment"
android:label="我的"
tools:layout="@layout/fragment_my" />
</navigation>

View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<navigation 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:id="@+id/nav_graph"
app:startDestination="@id/FirstFragment">
<fragment
android:id="@+id/FirstFragment"
android:name="com.cmx.wanhui.ui.FirstFragment"
android:label="@string/first_fragment_label"
tools:layout="@layout/fragment_first">
<action
android:id="@+id/action_FirstFragment_to_SecondFragment"
app:destination="@id/SecondFragment" />
</fragment>
<fragment
android:id="@+id/SecondFragment"
android:name="com.cmx.wanhui.ui.SecondFragment"
android:label="@string/second_fragment_label"
tools:layout="@layout/fragment_second">
<action
android:id="@+id/action_SecondFragment_to_FirstFragment"
app:destination="@id/FirstFragment" />
</fragment>
</navigation>

View File

@ -0,0 +1,4 @@
<resources>
<dimen name="activity_horizontal_margin">48dp</dimen>
<dimen name="fab_margin">48dp</dimen>
</resources>

View File

@ -0,0 +1,16 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Theme.AfricanFinance" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
<!-- Primary brand color. -->
<item name="colorPrimary">@color/purple_200</item>
<item name="colorPrimaryVariant">@color/purple_700</item>
<item name="colorOnPrimary">@color/black</item>
<!-- Secondary brand color. -->
<item name="colorSecondary">@color/teal_200</item>
<item name="colorSecondaryVariant">@color/teal_200</item>
<item name="colorOnSecondary">@color/black</item>
<!-- Status bar color. -->
<item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
<!-- Customize your theme here. -->
</style>
</resources>

View File

@ -0,0 +1,4 @@
<resources>
<dimen name="activity_horizontal_margin">200dp</dimen>
<dimen name="fab_margin">200dp</dimen>
</resources>

View File

@ -0,0 +1,4 @@
<resources>
<dimen name="activity_horizontal_margin">48dp</dimen>
<dimen name="fab_margin">48dp</dimen>
</resources>

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="purple_200">#FFBB86FC</color>
<color name="purple_500">#FF6200EE</color>
<color name="purple_700">#FF3700B3</color>
<color name="teal_200">#FF03DAC5</color>
<color name="teal_700">#FF018786</color>
<color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color>
<color name="CurseColor">#2FDF98</color>
<color name="green_theme_light">#2FDF98</color>
<color name="base_col">#11D183</color>
</resources>

View File

@ -0,0 +1,6 @@
<resources>
<!-- Default screen margins, per the Android Design guidelines. -->
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
<dimen name="fab_margin">16dp</dimen>
</resources>

View File

@ -0,0 +1,55 @@
<resources>
<string name="app_name">水文监测</string>
<string name="title_home">Home</string>
<string name="title_dashboard">Loan</string>
<string name="title_notifications">Mine</string>
<string name="title_activity_login">Login</string>
<string name="prompt_email">Email</string>
<string name="prompt_password">Password</string>
<string name="action_sign_in">Sign in or register</string>
<string name="action_sign_in_short">Sign in</string>
<string name="welcome">"Welcome !"</string>
<string name="invalid_username">Not a valid username</string>
<string name="invalid_password">Password must be >5 characters</string>
<string name="login_failed">"Login failed"</string>
<string name="title_activity_register_result">RegisterResultActivity</string>
<!-- Strings used for fragments for navigation -->
<string name="first_fragment_label">First Fragment</string>
<string name="second_fragment_label">Second Fragment</string>
<string name="next">Next</string>
<string name="previous">Previous</string>
<string name="hello_first_fragment">Hello first fragment</string>
<string name="hello_second_fragment">Hello second fragment. Arg: %1$s</string>
<string name="login">Sign in</string>
<string name="password">Password</string>
<string name="username">Username</string>
<string name="agreeprotocol">我已阅读并同意《非洲金融用户协议》</string>
<string name="register">Sign up</string>
<string name="login_name_empty">Please enter the user name</string>
<string name="login_psd_empty">Please enter the password</string>
<string name="login_agreement">请阅读并同意协议</string>
<string name="user_agreement_det">Terms &amp; Conditions \n
By downloading or using the app, these terms will automatically apply to you you should make sure therefore that you read them carefully before using the app. Youre not allowed to copy or modify the app, any part of the app, or our trademarks in any way. Youre not allowed to attempt to extract the source code of the app, and you also shouldnt try to translate the app into other languages or make derivative versions. The app itself, and all the trademarks, copyright, database rights, and other intellectual property rights related to it, still belong to Fintech.\n
Fintech is committed to ensuring that the app is as useful and efficient as possible. For that reason, we reserve the right to make changes to the app or to charge for its services, at any time and for any reason. We will never charge you for the app or its services without making it very clear to you exactly what youre paying for.\n
The InstaCredit app stores and processes personal data that you have provided to us, to provide our Service. Its your responsibility to keep your phone and access to the app secure. We therefore recommend that you do not jailbreak or root your phone, which is the process of removing software restrictions and limitations imposed by the official operating system of your device. It could make your phone vulnerable to malware/viruses/malicious programs, compromise your phones security features and it could mean that the InstaCredit app wont work properly or at all.\n
The app does use third-party services that declare their Terms and Conditions.
Link to Terms and Conditions of third-party service providers used by the app
• Google Play Services
You should be aware that there are certain things that Fintech will not take responsibility for. Certain functions of the app will require the app to have an active internet connection. The connection can be Wi-Fi or provided by your mobile network provider, but Fintech cannot take responsibility for the app not working at full functionality if you dont have access to Wi-Fi, and you dont have any of your data allowance left.\n
If youre using the app outside of an area with Wi-Fi, you should remember that the terms of the agreement with your mobile network provider will still apply. As a result, you may be charged by your mobile provider for the cost of data for the duration of the connection while accessing the app, or other third-party charges. In using the app, youre accepting responsibility for any such charges, including roaming data charges if you use the app outside of your home territory (i.e. region or country) without turning off data roaming. If you are not the bill payer for the device on which youre using the app, please be aware that we assume that you have received permission from the bill payer for using the app.\n
Along the same lines, Fintech cannot always take responsibility for the way you use the app i.e. You need to make sure that your device stays charged if it runs out of battery and you cant turn it on to avail the Service, Fintech cannot accept responsibility.\n
With respect to Fintechs responsibility for your use of the app, when youre using the app, its important to bear in mind that although we endeavor to ensure that it is updated and correct at all times, we do rely on third parties to provide information to us so that we can make it available to you. Fintech accepts no liability for any loss, direct or indirect, you experience as a result of relying wholly on this functionality of the app.\n
At some point, we may wish to update the app. The app is currently available on Android the requirements for the system(and for any additional systems we decide to extend the availability of the app to) may change, and youll need to download the updates if you want to keep using the app. Fintech does not promise that it will always update the app so that it is relevant to you and/or works with the Android version that you have installed on your device. However, you promise to always accept updates to the application when offered to you, We may also wish to stop providing the app, and may terminate use of it at any time without giving notice of termination to you. Unless we tell you otherwise, upon any termination, (a) the rights and licenses granted to you in these terms will end; (b) you must stop using the app, and (if needed) delete it from your device.\n
Changes to This Terms and Conditions\n
We may update our Terms and Conditions from time to time. Thus, you are advised to review this page periodically for any changes. We will notify you of any changes by posting the new Terms and Conditions on this page.
These terms and conditions are effective as of 2023-06-17\n
Contact Us\n
If you have any questions or suggestions about our Terms and Conditions, do not hesitate to contact us at eric.xia@cusper.io.
This Terms and Conditions page was generated by App Privacy Policy Generator
</string>
</resources>

View File

@ -0,0 +1,17 @@
<resources>
<!-- 自定义dialog的样式 -->
<style name="CustomDialog">
<item name="android:windowFrame">@null</item><!--边框-->
<item name="android:windowIsFloating">true</item><!--是否浮现在activity之上-->
<item name="android:windowIsTranslucent">false</item><!--半透明-->
<item name="android:windowNoTitle">true</item><!--无标题-->
<item name="android:windowBackground">@drawable/dialog_custom_bg</item><!--背景透明-->
<item name="android:backgroundDimEnabled">true</item><!--模糊-->
<item name="android:backgroundDimAmount">0.6</item>
</style>
</resources>

View File

@ -0,0 +1,21 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Theme.AfricanFinance" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Primary brand color. -->
<item name="colorPrimary">@color/green_theme_light</item>
<item name="colorPrimaryVariant">@color/green_theme_light</item>
<item name="colorOnPrimary">@color/white</item>
<!-- Secondary brand color. -->
<item name="colorSecondary">@color/green_theme_light</item>
<item name="colorSecondaryVariant">@color/green_theme_light</item>
<item name="colorOnSecondary">@color/black</item>
<!-- Status bar color. -->
<item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
<!-- Customize your theme here. -->
</style>
<style name="Theme.AfricanFinance.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
</resources>

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?><!--
Sample backup rules file; uncomment and customize as necessary.
See https://developer.android.com/guide/topics/data/autobackup
for details.
Note: This file is ignored for devices older that API 31
See https://developer.android.com/about/versions/12/backup-restore
-->
<full-backup-content>
<!--
<include domain="sharedpref" path="."/>
<exclude domain="sharedpref" path="device.xml"/>
-->
</full-backup-content>

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?><!--
Sample data extraction rules file; uncomment and customize as necessary.
See https://developer.android.com/about/versions/12/backup-restore#xml-changes
for details.
-->
<data-extraction-rules>
<cloud-backup>
<!-- TODO: Use <include> and <exclude> to control what is backed up.
<include .../>
<exclude .../>
-->
</cloud-backup>
<!--
<device-transfer>
<include .../>
<exclude .../>
</device-transfer>
-->
</data-extraction-rules>

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="cmxdownload" path="cmxdownload" />
<external-path
name="app_update_external"
path="/" />
<external-cache-path
name="app_update_cache"
path="/" />
</paths>

15
build.gradle Normal file
View File

@ -0,0 +1,15 @@
buildscript {
ext.kotlin_version = '1.4.21'
repositories {
google()
jcenter()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.31"
classpath 'com.android.tools.build:gradle:7.1.2'
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}

22
gradle.properties Normal file
View File

@ -0,0 +1,22 @@
# 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=-Xmx2048m -Dfile.encoding=UTF-8
# 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
# Enables namespacing of each library's R class so that its R class includes only the
# resources declared in the library itself and none from the library's dependencies,
# thereby reducing the size of the R class for that library
android.nonTransitiveRClass=true
android.enableJetifier=true

BIN
gradle/wrapper/gradle-wrapper.jar vendored Normal file

Binary file not shown.

View File

@ -0,0 +1,6 @@
#Sun Jun 25 11:21:59 CST 2023
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

185
gradlew vendored Normal file
View File

@ -0,0 +1,185 @@
#!/usr/bin/env sh
#
# Copyright 2015 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
##
## 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='"-Xmx64m" "-Xms64m"'
# 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 or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; 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=`expr $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"
exec "$JAVACMD" "$@"

89
gradlew.bat vendored Normal file
View File

@ -0,0 +1,89 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@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 Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@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="-Xmx64m" "-Xms64m"
@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 execute
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 execute
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
: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 %*
: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

21
settings.gradle Normal file
View File

@ -0,0 +1,21 @@
pluginManagement {
repositories {
gradlePluginPortal()
google()
jcenter()
mavenCentral()
}
}
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
jcenter()
mavenCentral()
maven { url "https://jitpack.io" }
maven { url "https://www.jitpack.io" }
}
}
rootProject.name = "Hydrology"
include ':app'