diff --git a/Code/Android/.idea/Android.iml b/Code/Android/.idea/Android.iml new file mode 100644 index 0000000..d6ebd48 --- /dev/null +++ b/Code/Android/.idea/Android.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/Code/Android/.idea/modules.xml b/Code/Android/.idea/modules.xml new file mode 100644 index 0000000..4b3d351 --- /dev/null +++ b/Code/Android/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/Code/Android/.idea/runConfigurations.xml b/Code/Android/.idea/runConfigurations.xml new file mode 100644 index 0000000..797acea --- /dev/null +++ b/Code/Android/.idea/runConfigurations.xml @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/Code/Android/.idea/workspace.xml b/Code/Android/.idea/workspace.xml new file mode 100644 index 0000000..af3a34f --- /dev/null +++ b/Code/Android/.idea/workspace.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + 1641731768884 + + + + + + + + + + \ No newline at end of file diff --git a/Code/Android/projectFirst/.gitignore b/Code/Android/projectFirst/.gitignore new file mode 100644 index 0000000..aa724b7 --- /dev/null +++ b/Code/Android/projectFirst/.gitignore @@ -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 diff --git a/Code/Android/projectFirst/.idea/codeStyles b/Code/Android/projectFirst/.idea/codeStyles new file mode 100644 index 0000000..e2e415d --- /dev/null +++ b/Code/Android/projectFirst/.idea/codeStyles @@ -0,0 +1,119 @@ + + + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
+
\ No newline at end of file diff --git a/Code/Android/projectFirst/.idea/compiler.xml b/Code/Android/projectFirst/.idea/compiler.xml new file mode 100644 index 0000000..b1bda62 --- /dev/null +++ b/Code/Android/projectFirst/.idea/compiler.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/Code/Android/projectFirst/.idea/gradle.xml b/Code/Android/projectFirst/.idea/gradle.xml new file mode 100644 index 0000000..ac6b0ae --- /dev/null +++ b/Code/Android/projectFirst/.idea/gradle.xml @@ -0,0 +1,21 @@ + + + + + + + \ No newline at end of file diff --git a/Code/Android/projectFirst/.idea/jarRepositories.xml b/Code/Android/projectFirst/.idea/jarRepositories.xml new file mode 100644 index 0000000..c638ed2 --- /dev/null +++ b/Code/Android/projectFirst/.idea/jarRepositories.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Code/Android/projectFirst/.idea/misc.xml b/Code/Android/projectFirst/.idea/misc.xml new file mode 100644 index 0000000..4700283 --- /dev/null +++ b/Code/Android/projectFirst/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/Code/Android/projectFirst/.idea/runConfigurations.xml b/Code/Android/projectFirst/.idea/runConfigurations.xml new file mode 100644 index 0000000..e497da9 --- /dev/null +++ b/Code/Android/projectFirst/.idea/runConfigurations.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/Code/Android/projectFirst/app/.gitignore b/Code/Android/projectFirst/app/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/Code/Android/projectFirst/app/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/Code/Android/projectFirst/app/build.gradle b/Code/Android/projectFirst/app/build.gradle new file mode 100644 index 0000000..8708cfa --- /dev/null +++ b/Code/Android/projectFirst/app/build.gradle @@ -0,0 +1,78 @@ +apply plugin:'com.android.application' + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.2" + + defaultConfig { + applicationId "com.app.projectfirst" + minSdkVersion 16 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + multiDexEnabled true + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + ndk { + //设置支持的SO库架构(开发者可以根据需要,选择一个或多个平台的so) + abiFilters "armeabi", "armeabi-v7a", "arm64-v8a", "x86","x86_64" + } + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'androidx.constraintlayout:constraintlayout:2.0.4' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.2' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' + implementation files('libs\\commons-lang3-3.7.jar') + implementation files('libs\\AMap3DMap_7.9.1_AMapNavi_7.9.1_AMapSearch_7.9.0_AMapLocation_5.3.1_20210414.jar') + implementation 'com.android.support:design:30.0.2' + implementation 'com.android.support:recyclerview-v7:30.0.2' + + implementation 'com.android.support:multidex:1.0.3' + //网络请求 + implementation 'com.squareup.okhttp3:okhttp:3.14.2' + implementation 'com.squareup.okio:okio:1.17.4' + implementation 'cz.msebera.android:httpclient:4.4.1.1' + implementation 'com.loopj.android:android-async-http:1.4.9' + //图片加载 + implementation 'com.github.bumptech.glide:glide:4.6.1' + annotationProcessor 'com.github.bumptech.glide:glide:4.6.1' + implementation 'com.youth.banner:banner:1.4.10' //最新版本 + //依赖注入 + implementation 'com.jakewharton:butterknife:10.2.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1' + //JSON于对象转换 + implementation 'com.google.code.gson:gson:2.7' + //弹窗 + implementation 'com.github.razerdp:BasePopup:2.1.5' + //运行时权限管理 + implementation 'pub.devrel:easypermissions:2.0.1' + //时间三级选择 + implementation 'com.contrarywind:Android-PickerView:4.1.9' + //图片缩放 + implementation 'me.panpf:sketch:2.7.1' + implementation 'me.panpf:sketch-gif:2.7.1' + //悬浮菜单按钮 + implementation 'com.github.clans:fab:1.6.4' + //视频播放器 + implementation 'com.github.dueeeke.dkplayer:dkplayer-java:3.2.6' + implementation 'com.github.dueeeke.dkplayer:dkplayer-ui:3.2.6' + + implementation 'com.github.ome450901:SimpleRatingBar:1.5.1' + implementation 'me.zhanghai.android.materialratingbar:library:1.4.0' +} + diff --git a/Code/Android/projectFirst/app/debug/debug/app-debug.apk b/Code/Android/projectFirst/app/debug/debug/app-debug.apk new file mode 100644 index 0000000..10ba1bb Binary files /dev/null and b/Code/Android/projectFirst/app/debug/debug/app-debug.apk differ diff --git a/Code/Android/projectFirst/app/debug/debug/output.json b/Code/Android/projectFirst/app/debug/debug/output.json new file mode 100644 index 0000000..740915d --- /dev/null +++ b/Code/Android/projectFirst/app/debug/debug/output.json @@ -0,0 +1,33 @@ +{ + "version": 2, + "artifactType": { + "type": "APK", + "kind": "Directory" + }, + "applicationId": "com.app.projectfirst", + "variantName": "processDebugResources", + "elements": [ + { + "type": "SINGLE", + "filters": [], + "properties": [ + { + "key": "packageId", + "value": "com.app.projectfirst" + }, + { + "key": "split", + "value": "" + }, + { + "key": "minSdkVersion", + "value": "16" + } + ], + "versionCode": 1, + "versionName": "1.0", + "enabled": true, + "outputFile": "app-debug.apk" + } + ] +} \ No newline at end of file diff --git a/Code/Android/projectFirst/app/libs/AMap3DMap_7.9.1_AMapNavi_7.9.1_AMapSearch_7.9.0_AMapLocation_5.3.1_20210414.jar b/Code/Android/projectFirst/app/libs/AMap3DMap_7.9.1_AMapNavi_7.9.1_AMapSearch_7.9.0_AMapLocation_5.3.1_20210414.jar new file mode 100644 index 0000000..03859ab Binary files /dev/null and b/Code/Android/projectFirst/app/libs/AMap3DMap_7.9.1_AMapNavi_7.9.1_AMapSearch_7.9.0_AMapLocation_5.3.1_20210414.jar differ diff --git a/Code/Android/projectFirst/app/libs/Amap_2DMap_V6.0.0_20191106.jar b/Code/Android/projectFirst/app/libs/Amap_2DMap_V6.0.0_20191106.jar new file mode 100644 index 0000000..0e19a31 Binary files /dev/null and b/Code/Android/projectFirst/app/libs/Amap_2DMap_V6.0.0_20191106.jar differ diff --git a/Code/Android/projectFirst/app/libs/Android_Map3D_SDK_V7.9.1_20210414.jar b/Code/Android/projectFirst/app/libs/Android_Map3D_SDK_V7.9.1_20210414.jar new file mode 100644 index 0000000..73fda8f Binary files /dev/null and b/Code/Android/projectFirst/app/libs/Android_Map3D_SDK_V7.9.1_20210414.jar differ diff --git a/Code/Android/projectFirst/app/libs/commons-lang3-3.7.jar b/Code/Android/projectFirst/app/libs/commons-lang3-3.7.jar new file mode 100644 index 0000000..f37ded6 Binary files /dev/null and b/Code/Android/projectFirst/app/libs/commons-lang3-3.7.jar differ diff --git a/Code/Android/projectFirst/app/proguard-rules.pro b/Code/Android/projectFirst/app/proguard-rules.pro new file mode 100644 index 0000000..481bb43 --- /dev/null +++ b/Code/Android/projectFirst/app/proguard-rules.pro @@ -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 \ No newline at end of file diff --git a/Code/Android/projectFirst/app/src/androidTest/java/com/app/projectfirst/ExampleInstrumentedTest.java b/Code/Android/projectFirst/app/src/androidTest/java/com/app/projectfirst/ExampleInstrumentedTest.java new file mode 100644 index 0000000..0ee32fd --- /dev/null +++ b/Code/Android/projectFirst/app/src/androidTest/java/com/app/projectfirst/ExampleInstrumentedTest.java @@ -0,0 +1,26 @@ +package com.app.projectfirst; + +import android.content.Context; + +import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.platform.app.InstrumentationRegistry; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.assertEquals; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + assertEquals("com.app.projectfirst", appContext.getPackageName()); + } +} \ No newline at end of file diff --git a/Code/Android/projectFirst/app/src/main/AndroidManifest.xml b/Code/Android/projectFirst/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..22c27fc --- /dev/null +++ b/Code/Android/projectFirst/app/src/main/AndroidManifest.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Code/Android/projectFirst/app/src/main/java/com/app/projectfirst/App.java b/Code/Android/projectFirst/app/src/main/java/com/app/projectfirst/App.java new file mode 100644 index 0000000..9815ea8 --- /dev/null +++ b/Code/Android/projectFirst/app/src/main/java/com/app/projectfirst/App.java @@ -0,0 +1,27 @@ +package com.app.projectfirst; + +import android.app.Application; +import android.content.Context; + +import androidx.multidex.MultiDex; + +public class App extends Application { + private static final String TAG = "App"; + private static Context mContext; + @Override + public void onCreate() { + super.onCreate(); + mContext = this; +// startService(new Intent(this, RecordService.class)); + } + @Override + protected void attachBaseContext(Context base) { + super.attachBaseContext(base); +// 如果需要使用MultiDex,需要在此处调用。 + MultiDex.install(this); + } + public static Context getContext(){ + return mContext; + } +} + diff --git a/Code/Android/projectFirst/app/src/main/java/com/app/projectfirst/activity/BaseActivity.java b/Code/Android/projectFirst/app/src/main/java/com/app/projectfirst/activity/BaseActivity.java new file mode 100644 index 0000000..2b29e1f --- /dev/null +++ b/Code/Android/projectFirst/app/src/main/java/com/app/projectfirst/activity/BaseActivity.java @@ -0,0 +1,211 @@ +package com.app.projectfirst.activity; + +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.view.Gravity; +import android.widget.Button; +import android.widget.EditText; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.app.projectfirst.config.AppConfig; +import com.app.projectfirst.utils.ActivityControl; +import com.app.projectfirst.utils.GetNetData; +import com.app.projectfirst.utils.GetValueImpl; +import com.app.projectfirst.utils.LogUtils; +import com.app.projectfirst.utils.ToastUtils; +import com.bumptech.glide.Glide; +import com.bumptech.glide.util.Util; +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; + +import org.apache.commons.lang3.StringUtils; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + + +public class BaseActivity extends AppCompatActivity { + private boolean isDebug = true; + public static int userId; + public static String userToken; + public static String userStage; + public GetValueImpl getValue; + public GetNetData getNetData; + public ActivityControl activityControl; + public final static int TYPE_MIUI = 0; + public final static int TYPE_FLYME = 1; + public final static int TYPE_M = 3;//6.0 + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + activityControl = ActivityControl.getInstance(); + activityControl.addActivity(this); + userId = activityControl.returnUserId(this); + userToken = activityControl.returnUserToken(this); + userStage = activityControl.returnUserStage(this); + getNetData = GetNetData.getInstance(); + getValue = GetValueImpl.getInstance(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + ActivityControl.getInstance().removeActivity(this); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { + if (Util.isOnMainThread() && !isFinishing() && !isDestroyed()) { + Glide.with(this).pauseRequests(); + } + } else { + if (Util.isOnMainThread() && !isFinishing()) { + Glide.with(this).pauseRequests(); + } + } + } + + public JSONObject returnRequesJSON(){ + JSONObject jsonObject = new JSONObject(); + try { + jsonObject.put("token",userToken); + } catch (JSONException e) { + e.printStackTrace(); + } + return jsonObject; + } + + + + public void toastShort(String text){ + try { + Toast toast = Toast.makeText(this,text, Toast.LENGTH_SHORT); + toast.setGravity(Gravity.CENTER , 0, 0); + toast.show(); + }catch (Exception e){ + e.printStackTrace(); + } + } + public void toastLong(String text){ + try { + Toast toast = Toast.makeText(this,text, Toast.LENGTH_LONG); + toast.setGravity(Gravity.CENTER , 0, 0); + toast.show(); + }catch (Exception e){ + e.printStackTrace(); + } + } + + public void startActivity(Class clazz, boolean isFinish) { + if (isFinish) { + finish(); + } + startActivity(new Intent(this, clazz)); + } + + protected void loge(String msg) { + if (AppConfig.logShow) { + String tag = this.getClass().getName(); + String tagFinal = tag.substring(tag.lastIndexOf(".")+1,tag.length()); + LogUtils.e(tagFinal, msg); + } + } + public boolean isEmpty(String str){ + if (StringUtils.isEmpty(str) || "null".equals(str)){ + return true; + }else { + return false; + } + } + public boolean toastEmpty(String str, String msg){ + if (StringUtils.isEmpty(str)){ + ToastUtils.toastShort(this,msg); + return true; + } + return false; + } + public boolean isBlank(String str){ + return StringUtils.isBlank(str); + } + public String returnEditText(EditText editText){ + String str = ""; + if (editText!=null){ + str = editText.getText().toString().trim(); + } + return str; + } + public String returnButton(Button button){ + String str = ""; + if (button!=null){ + str = button.getText().toString().trim(); + } + return str; + } + public String returnTextViewText(TextView textView){ + String str = ""; + if (textView!=null){ + str = textView.getText().toString().trim(); + } + return str; + } + public static boolean match(String regex, String str) { + Pattern pattern = Pattern.compile(regex); + Matcher matcher = pattern.matcher(str); + return matcher.matches(); + } + public String objectToJSONString(T o){ + Gson gson = new Gson(); + String json = gson.toJson(o); + return json; + } + public String listToJSONString(List list){ + Gson gson = new Gson(); + String json = gson.toJson(list); + return json; + } + public String mapToJSONString(HashMap map){ + Gson gson = new Gson(); + String json = gson.toJson(map); + return json; + } + public String listMapToJSONString(List> list){ + Gson gson = new Gson(); + String json = gson.toJson(list); + return json; + } + public T jsonToObject(String jsonString, Class c){ + Gson gson = new Gson(); + T t = gson.fromJson(jsonString,c); + return t; + } + public List jsonToList(String jsonString){ + List list = new ArrayList(); + Gson gson = new Gson(); + list = (List) gson.fromJson(jsonString, new TypeToken>(){}.getType()); + return list; + } + public Map jsonToMap(String jsonString){ + Map map = new HashMap(); + Gson gson = new Gson(); + map = (Map) gson.fromJson(jsonString, new TypeToken>(){}.getType()); + return map; + } + public List> jsonToListMap(String jsonString){ + List> list = new ArrayList<>(); + Gson gson = new Gson(); + list = gson.fromJson(jsonString, new TypeToken>>(){}.getType()); + return list; + } + + + +} diff --git a/Code/Android/projectFirst/app/src/main/java/com/app/projectfirst/activity/CustomView.java b/Code/Android/projectFirst/app/src/main/java/com/app/projectfirst/activity/CustomView.java new file mode 100644 index 0000000..27c6a9a --- /dev/null +++ b/Code/Android/projectFirst/app/src/main/java/com/app/projectfirst/activity/CustomView.java @@ -0,0 +1,53 @@ +package com.app.projectfirst.activity; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.MotionEvent; + +import androidx.annotation.Nullable; + +public class CustomView extends androidx.appcompat.widget.AppCompatTextView { + private int lastX; + private int lastY; + public GetCoordListener mGetCoordListener; + public CustomView(Context context) { + super(context); + } + + public CustomView(Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + } + + public CustomView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + @Override + public boolean onTouchEvent(MotionEvent event) { + //此方法监听 控件滑动时 控件在父控件的坐标点 + int x = (int) event.getX(); + int y = (int) event.getY(); + switch (event.getAction()){ + case MotionEvent.ACTION_DOWN://按下时 + lastX = x; + lastY = y; + break; + case MotionEvent.ACTION_MOVE://移动时 + int offsetX = x - lastX; + int offsetY = y - lastY; + layout(getLeft()+offsetX,getTop()+offsetY,getRight()+offsetX,getBottom()+offsetY); + if (mGetCoordListener!=null){ + mGetCoordListener.getCoord(x,y); + } + break; + } + return true; + } + + public interface GetCoordListener{ + void getCoord(int x,int y); + } + public void setOnGetCoordListener(GetCoordListener getCoordListener){ + mGetCoordListener = getCoordListener; + } +} diff --git a/Code/Android/projectFirst/app/src/main/java/com/app/projectfirst/activity/MainActivity.java b/Code/Android/projectFirst/app/src/main/java/com/app/projectfirst/activity/MainActivity.java new file mode 100644 index 0000000..d3f88b6 --- /dev/null +++ b/Code/Android/projectFirst/app/src/main/java/com/app/projectfirst/activity/MainActivity.java @@ -0,0 +1,673 @@ +package com.app.projectfirst.activity; + +import android.app.AlertDialog; +import android.app.ProgressDialog; +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.provider.MediaStore; +import android.view.Gravity; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewTreeObserver; +import android.widget.AbsoluteLayout; +import android.widget.ImageView; +import android.widget.PopupMenu; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.app.projectfirst.R; +import com.app.projectfirst.adapter.MarksAdapter; +import com.app.projectfirst.config.AppConfig; +import com.app.projectfirst.entity.Marks; +import com.app.projectfirst.entity.Tasks; +import com.app.projectfirst.entity.Users; +import com.app.projectfirst.utils.GetNetData; +import com.app.projectfirst.utils.UploadFileByOkHttp; +import com.app.projectfirst.utils.Uri2PathUtil; +import com.bumptech.glide.Glide; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Random; +import java.util.Timer; +import java.util.TimerTask; + +import butterknife.BindView; +import butterknife.ButterKnife; +import butterknife.OnClick; +import okhttp3.Response; + + +public class MainActivity extends BaseActivity { + + @BindView(R.id.title) + TextView title; + @BindView(R.id.rightTextView) + TextView rightTextView; + @BindView(R.id.linearLayout) + AbsoluteLayout linearLayout; + @BindView(R.id.mapImageView) + ImageView mapImageView; + Map locationLinearLayoutMap;//用户位置 控件集合 + Map markLinearLayoutMap;//标记控件集合 + Map taskLinearLayoutMap;//任务控件集合 + private String mapImageUrl = ""; + private static final int UPLOAD_IMAGE = 104; + private static final int UPLOAD_ERROR = 107; + public Handler handler = new Handler() { + @Override + public void handleMessage(@NonNull Message msg) { + super.handleMessage(msg); + switch (msg.what) { + case UPLOAD_IMAGE: + mapImageUrl = (String) msg.obj; + try { + uploadMap(); + } catch (Exception e) { + e.printStackTrace(); + } + break; + case UPLOAD_ERROR: + toastShort((String) msg.obj); + break; + } + } + }; + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + ButterKnife.bind(this); + title.setText("首页"); + rightTextView.setText("菜单"); + locationLinearLayoutMap = new HashMap<>();//地图界面显示 + markLinearLayoutMap = new HashMap<>();//标记界面地图显示 + taskLinearLayoutMap = new HashMap<>();//任务界面地图显示 + try { + getMapImage();//获取地图 + setLocation();//设置位置 + initMark();//获取标记 + initLocation();//获取位置 + initTask();//获取任务 + + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * 设置位置 + * @throws Exception + */ + private void setLocation() throws Exception { + //此方法用于获取当前地图控件的XY轴尺寸 + ViewTreeObserver vto3 = linearLayout.getViewTreeObserver(); + vto3.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { + @Override + public void onGlobalLayout() { + linearLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this); + int x = linearLayout.getWidth(); + int y = linearLayout.getHeight(); + loge(x+"_setLocation__"+y); + //将XY轴尺寸组装请求服务器 + JSONObject jsonObject = returnRequesJSON(); + try { + jsonObject.put("x", x); + jsonObject.put("y", y); + } catch (JSONException e) { + e.printStackTrace(); + } + //请求成功后服务器更新用户位置,在initLocation方法中持续更新用户位置 + getNetData.getData(MainActivity.this, AppConfig.UrlAddress + "setLocation", jsonObject, new GetNetData.OnGetDataListener() { + @Override + public void successed(JSONObject data, String status, String msg) { + + } + }); + } + }); + + } + + Timer timer1; + //获取位置 + private void initLocation() { + //创建计时器 持续更新当前位置 对于用户A当其他用户离线后 位置图标会及时从地图中隐藏 + TimerTask timerTask = new TimerTask() { + @Override + public void run() { + runOnUiThread(new Runnable() { + @Override + public void run() { + //访问获取地址接口 + JSONObject jsonObject = returnRequesJSON(); + getNetData.getData(MainActivity.this, AppConfig.UrlAddress + "getLocations", jsonObject, new GetNetData.OnGetDataListener() { + @Override + public void successed(JSONObject data, String status, String msg) { + try { + //获取成功后 根据用户等级 用户A可以看到全部的用户位置 其他用户只能看到自己 + if ("1".equals(userStage)){ + //解析用户集合 + String usersListStr = getValue.getValue(data,"usersList"); + JSONArray usersList = new JSONArray(usersListStr); + //循环获取每个用户信息 + for (int i=0;i marksList1 = new ArrayList<>(); + //解析标记JSONArray 添加到标记对象集合中 + for (int i = 0; i < marksList.length(); i++) { + JSONObject jsonObject1 = marksList.getJSONObject(i); + Marks marks = jsonToObject(jsonObject1.toString(), Marks.class); + //添加到标记对象集合中 + marksList1.add(marks); + } + //初始化显示标记用的 View + View view = getLayoutInflater().inflate(R.layout.view_other_tags, null); + //获取View内的列表RecyclerView对象 + RecyclerView recyclerView = view.findViewById(R.id.recyclerView); + //采用纵向线性布局 + LinearLayoutManager linearLayoutManager = new LinearLayoutManager(MainActivity.this, LinearLayoutManager.VERTICAL, false); + //将布局类型添加到列表RecyclerView对象 + recyclerView.setLayoutManager(linearLayoutManager); + //初始化列表RecyclerView的适配器 + MarksAdapter marksAdapter = new MarksAdapter(MainActivity.this, marksList1); + //适配器点击事件接口监听 + marksAdapter.setOnItemClickListener(new MarksAdapter.OnItemClickListener() { + @Override + public void receive(View view, int position, Marks marks) { + try { + shareMark(marks.getMarkId());//显示标记操作 + } catch (Exception e) { + e.printStackTrace(); + } + } + }); + //将适配器添加到列表RecyclerView + recyclerView.setAdapter(marksAdapter); + //创建一个弹窗 将该View添加到弹窗 用于用户A对其进行是否共享操作 + AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this); + builder.setTitle("标记共享") + .setView(view) + .setPositiveButton("关闭", null).show(); + } catch (Exception e) { + e.printStackTrace(); + } + } + }); + } + //显示标记图标 + private void shareMark(int markId) throws Exception { + JSONObject jsonObject = returnRequesJSON(); + jsonObject.put("markId", markId); + //访问服务器接口 + getNetData.getData(this, AppConfig.UrlAddress + "shareMark", jsonObject, new GetNetData.OnGetDataListener() { + @Override + public void successed(JSONObject data, String status, String msg) { + // 服务器处理成功后 通知共享成 并且用户在initMark()方法中 会持续更新该标记 + toastShort(msg); + } + }); + } + //用户A在上传地图选择图片成功后 安卓系统返回的图片Uri地址 + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + switch (requestCode) { + case 0: + if (resultCode == RESULT_OK) { + try { + //根据Uri获取到图片在存储中的文件路径 + String mapImageUrl = Uri2PathUtil.getRealPathFromUri(MainActivity.this, data.getData()); + //处理上传图片到服务器 + displayImage(mapImageUrl, "图片处理中,请稍后...", UPLOAD_IMAGE); + } catch (Exception e) { + e.printStackTrace(); + } + } + break; + default: + break; + } + } + //上传地图 + private void uploadMap() throws Exception { + JSONObject jsonObject = returnRequesJSON(); + jsonObject.put("mapImageUrl", mapImageUrl); + getNetData.getData(this, AppConfig.UrlAddress + "uploadMapImage", jsonObject, new GetNetData.OnGetDataListener() { + @Override + public void successed(JSONObject data, String status, String msg) { + //在选择图片成功 上传到服务器并从服务器获取到访问图片的文件名后 通知上传成功 冰刷新当前页面 + toastShort(msg); + finish(); + startActivity(new Intent(MainActivity.this,MainActivity.class)); + } + }); + } + //获取地图 + private void getMapImage() { + JSONObject jsonObject = returnRequesJSON(); + getNetData.getData(this, AppConfig.UrlAddress + "getMapImage", jsonObject, new GetNetData.OnGetDataListener() { + @Override + public void successed(JSONObject data, String status, String msg) { + try { + //从服务器撑过去到地图文件名 + String mapImageUrl = getValue.getValue(data, "mapImageUrl"); + if (!isEmpty(mapImageUrl)){ + //如果文件名不为空 则组装访问地址AppConfig.defaultNetFilePath+mapImageUrl + //为防止图片过大导致内存溢出 采用Glide框架用于在背景图片控件显示出来 + Glide.with(MainActivity.this).load(AppConfig.defaultNetFilePath+mapImageUrl).into(mapImageView); + } + + } catch (Exception e) { + e.printStackTrace(); + } + } + }); + } + + //右上角菜单点击时间 + @OnClick(R.id.rightTextView) + public void onViewClicked() { + //初始化弹出菜单 + PopupMenu popupMenu = null; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { + popupMenu = new PopupMenu(this, rightTextView, Gravity.TOP); + } else { + popupMenu = new PopupMenu(this, rightTextView); + } + //根据不同用户等级 显示对应的功能 + switch (userStage) { + case "1": + // menu布局 + popupMenu.getMenuInflater().inflate(R.menu.menu1, popupMenu.getMenu()); + // menu的item点击事件 + popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { + @Override + public boolean onMenuItemClick(MenuItem item) { + switch (item.getItemId()) { + case R.id.item0://跳转到标记页 type为0时进行标记操作 + Intent intent = new Intent(MainActivity.this, MarkActivity.class); + intent.putExtra("type", "0"); + startActivity(intent); + break; + case R.id.item1://获取其他用户未被共享的标记 + getOtherTags(); + break; + case R.id.item2://打开相册选取图片 + Intent intent2 = new Intent(Intent.ACTION_PICK, null); + intent2.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*"); + startActivityForResult(intent2, 0); + break; + case R.id.item3:////跳转到标记页 type为1时进行用户A的下达任务操作 + Intent intent3 = new Intent(MainActivity.this, MarkActivity.class); + intent3.putExtra("type", "1"); + startActivity(intent3); + break; + } + return false; + } + }); + // PopupMenu关闭事件 + popupMenu.setOnDismissListener(new PopupMenu.OnDismissListener() { + @Override + public void onDismiss(PopupMenu menu) { + + } + }); + popupMenu.show(); + break; + case "0": + // menu布局 + popupMenu.getMenuInflater().inflate(R.menu.menu0, popupMenu.getMenu()); + // menu的item点击事件 + popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { + @Override + public boolean onMenuItemClick(MenuItem item) { + switch (item.getItemId()) { + case R.id.item0://其他用户 只能进行标记 跳转到标记页 + Intent intent = new Intent(MainActivity.this, MarkActivity.class); + intent.putExtra("type", "0"); + startActivity(intent); + break; + + } + return false; + } + }); + // PopupMenu关闭事件 + popupMenu.setOnDismissListener(new PopupMenu.OnDismissListener() { + @Override + public void onDismiss(PopupMenu menu) { + + } + }); + popupMenu.show(); + break; + } + + } + //上传图片方法 + private void displayImage(String filePath, String message, int type) throws Exception { + //初始化进度弹窗 并显示 + ProgressDialog progressDialog = new ProgressDialog(this); + progressDialog.setMessage(message + filePath); + progressDialog.show(); + //拆解图片文件地址 获取到文件名 此方法没什么意义 只是看看图片对不对 + String[] strArray = filePath.split("\\."); + int suffixIndex = strArray.length - 1; + loge(filePath + "______________displayImage: strArray length is:" + strArray.length + "______" + strArray[suffixIndex]); + //在子线程中 上传图片到服务器 + new Thread(new Runnable() { + @Override + public void run() { + try { + //用okhttp框架上传图片 + Response response = UploadFileByOkHttp.getInstance().upload(AppConfig.UrlAddress + "uploadFile", filePath, System.currentTimeMillis() + new Random().nextInt(10000) + "." + strArray[suffixIndex]); + progressDialog.dismiss();//隐藏进度弹窗 + if (response.code() == 200) { + //200状态为上传成功 + if (response.body() != null) { + String responseStr = response.body().string(); + loge("____" + responseStr); + JSONObject outputJson = new JSONObject(responseStr); + String status = getValue.getValue(outputJson, "status");//上传是否成功的状态 + String msg = getValue.getValue(outputJson, "msg"); + JSONObject data = getValue.getJSONObjecValue(outputJson, "data");//服务器返回的data + if ("0".equals(status)) { + //上传成功 获取到服务器图片访问文件名 在子线程中通过handler发送到主线程 + String fileUrl = getValue.getValue(data, "filePath"); + Message message = Message.obtain(); + message.what = type; + message.obj = fileUrl; + handler.sendMessage(message); + } else { + //上传失败 在子线程中通过handler发送到主线程 + Message message = Message.obtain(); + message.what = UPLOAD_ERROR; + message.obj = msg; + handler.sendMessage(message); + } + } else { + Message message = Message.obtain(); + message.what = UPLOAD_ERROR; + message.obj = "数据解析错误"; + handler.sendMessage(message); + } + } else { + Message message = Message.obtain(); + message.what = UPLOAD_ERROR; + message.obj = "服务器连接异常:" + response.code(); + handler.sendMessage(message); + } + } catch (Exception e) { + e.printStackTrace(); + } + + } + }).start(); + } + //当前页面被销毁时进行的操作 关闭所有计时器 用户进行离线操作 + @Override + protected void onDestroy() { + super.onDestroy(); + if (timer != null) { + timer.cancel(); + } + if (timer1 != null) { + timer1.cancel(); + } + if (timer2 != null) { + timer2.cancel(); + } + outLine(); + } + //离线操作 用户访问服务器离线接口 将XY轴坐标重置为0 + private void outLine(){ + JSONObject jsonObject = returnRequesJSON(); + getNetData.getData(this, AppConfig.UrlAddress + "outLine", jsonObject, new GetNetData.OnGetDataListener() { + @Override + public void successed(JSONObject data, String status, String msg) { + + } + }); + } +} \ No newline at end of file diff --git a/Code/Android/projectFirst/app/src/main/java/com/app/projectfirst/activity/MarkActivity.java b/Code/Android/projectFirst/app/src/main/java/com/app/projectfirst/activity/MarkActivity.java new file mode 100644 index 0000000..fcc28d8 --- /dev/null +++ b/Code/Android/projectFirst/app/src/main/java/com/app/projectfirst/activity/MarkActivity.java @@ -0,0 +1,254 @@ +package com.app.projectfirst.activity; + +import android.app.AlertDialog; +import android.content.DialogInterface; +import android.content.Intent; +import android.graphics.drawable.Drawable; +import android.os.Bundle; +import android.view.View; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.EditText; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.Spinner; +import android.widget.TextView; + +import androidx.annotation.Nullable; + +import com.app.projectfirst.R; +import com.app.projectfirst.config.AppConfig; +import com.app.projectfirst.entity.Users; +import com.app.projectfirst.utils.GetNetData; +import com.bumptech.glide.Glide; +import com.bumptech.glide.load.DataSource; +import com.bumptech.glide.load.engine.GlideException; +import com.bumptech.glide.request.RequestListener; +import com.bumptech.glide.request.target.Target; + +import org.json.JSONArray; +import org.json.JSONObject; + +import butterknife.BindView; +import butterknife.ButterKnife; +import butterknife.OnClick; + +public class MarkActivity extends BaseActivity { + + @BindView(R.id.btnBack) + ImageView btnBack; + @BindView(R.id.title) + TextView title; + @BindView(R.id.rightTextView) + TextView rightTextView; + // @BindView(R.id.markView) +// CustomView markView; + @BindView(R.id.linearLayout) + LinearLayout linearLayout; + View customView; + String type = ""; + @BindView(R.id.mapImageView) + ImageView mapImageView; + @BindView(R.id.yLinearLayout) + LinearLayout yLinearLayout; + @BindView(R.id.xLinearLayout) + LinearLayout xLinearLayout; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_mark); + ButterKnife.bind(this); + title.setText("标记地图"); + rightTextView.setText("提交"); + getMapImage(); + //获取到主页跳转时 的操作类型type + Intent intent = getIntent(); + type = intent.getStringExtra("type");//1下达任务 0标记地图 + + } + //获取地图图片 + private void getMapImage() { + JSONObject jsonObject = returnRequesJSON(); + getNetData.getData(this, AppConfig.UrlAddress + "getMapImage", jsonObject, new GetNetData.OnGetDataListener() { + @Override + public void successed(JSONObject data, String status, String msg) { + try { + //成功获取到地图图片文件名 + String mapImageUrl = getValue.getValue(data, "mapImageUrl"); + if (!isEmpty(mapImageUrl)) { + //文件名不为空时 用Glide框架加载图片到ImageView控件 由于加载需要时间 为防止图片覆盖掉标记和坐标 等图片加载完毕后 再显示标记图标和XY坐标系 + Glide.with(MarkActivity.this).load(AppConfig.defaultNetFilePath + mapImageUrl).listener(new RequestListener() { + @Override + public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) { + return false; + } + + @Override + public boolean onResourceReady(Drawable resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) { + loge("图片加载完成"); + //地图图片加载完成 + //初始化自定义标记控件 为控件赋值为▼ 中文字符 + customView = getLayoutInflater().inflate(R.layout.view_mark, null); + CustomView customView1 = customView.findViewById(R.id.markView); + customView1.setText("▼"); + customView1.setTextColor(getResources().getColor(R.color.green)); + //为该标记设置位置 左上角为父控件的坐标0点 + LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT); + params.setMargins(0, 0, 0, 0); + customView1.setLayoutParams(params); + //将控件添加到父布局中 + linearLayout.addView(customView1); + return false; + } + }).into(mapImageView); + } + + } catch (Exception e) { + e.printStackTrace(); + } + } + }); + } + //上传标记 + private void uploadMark() throws Exception { + //自定义控件获取到当前相对于父布局 左侧和顶部的距离 + int x = (int) customView.getX(); + int y = (int) customView.getY(); + JSONObject jsonObject = returnRequesJSON(); + jsonObject.put("xCoord", x); + jsonObject.put("yCoord", y); + loge("uploadMark:" + jsonObject.toString()); + //将坐标距离上传到服务器 等待用户A审核 + getNetData.getData(this, AppConfig.UrlAddress + "uploadMark", jsonObject, new GetNetData.OnGetDataListener() { + @Override + public void successed(JSONObject data, String status, String msg) { + //上传成功 通知成功 并结束页面 返回到首页 + toastShort(msg); + finish(); + } + }); + } + //用于A在下达任务时 获取到其他用户 + private void getOtherUsers() { + JSONObject jsonObject = returnRequesJSON(); + getNetData.getData(this, AppConfig.UrlAddress + "getOtherUsers", jsonObject, new GetNetData.OnGetDataListener() { + @Override + public void successed(JSONObject data, String status, String msg) { + try { + //成功获取到其他用户后 解析用户集合 + String usersListStr = getValue.getValue(data, "usersList"); + JSONArray usersList = new JSONArray(usersListStr); + //创建2个数组 1个为用户ID数组 一个为用户昵称数组 + int[] uids = new int[usersList.length()]; + String[] nickNames = new String[usersList.length()]; + final int[] uid = {0}; + //为2个数组赋值 + for (int i = 0; i < usersList.length(); i++) { + JSONObject jsonObject1 = usersList.getJSONObject(i); + Users users = jsonToObject(jsonObject1.toString(), Users.class); + uids[i] = users.getUid(); + nickNames[i] = users.getNickName(); + if (i == 0) { + uid[0] = users.getUid(); + } + } + //初始化弹窗用View + View view1 = getLayoutInflater().inflate(R.layout.view_release_task, null); + //获取到View中的Spinner控件 + Spinner spinner = view1.findViewById(R.id.spinner); + EditText taskContent = view1.findViewById(R.id.taskContent); + // 建立Adapter并且绑定数据源 + ArrayAdapter adapter = new ArrayAdapter(MarkActivity.this, android.R.layout.simple_spinner_item, nickNames); + adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + //绑定 Adapter到控件 + spinner.setAdapter(adapter); + spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + @Override + public void onItemSelected(AdapterView parent, View view, + int pos, long id) { + //监听 Spinner选取事件监听 选择要下达任务的用户ID + uid[0] = uids[pos]; + } + + @Override + public void onNothingSelected(AdapterView parent) { + // Another interface callback + } + }); + //初始哈弹窗控件,并添加上面创建的spinner控件 + AlertDialog.Builder builder = new AlertDialog.Builder(MarkActivity.this); + builder.setTitle("选择用户") + .setView(view1) + .setPositiveButton("确定", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + //确定点击事件 + //获取到输入框中 输入的任务内容字符串 + String content = taskContent.getText().toString().trim(); + //判断是否选择了用户 + if (uid[0] <= 0) { + toastShort("请选择用户"); + return; + } + //判断任务内容是否为空 + if (isEmpty(content)) { + toastShort("请输入任务内容"); + return; + } + //最终发送任务数据到服务器 + try { + releaseTask(uid[0], content); + } catch (Exception e) { + e.printStackTrace(); + } + } + }).setNegativeButton("取消", null).show(); + } catch (Exception e) { + e.printStackTrace(); + } + } + }); + } + //发布任务 发布成功后 对应接收任务的用户 将会在地图上显示任务 + private void releaseTask(int uid, String content) throws Exception { + //获取到自定义控件在父布局中的位置 + int x = (int) customView.getX(); + int y = (int) customView.getY(); + //组装任务数据 上传到服务器 + JSONObject jsonObject = returnRequesJSON(); + jsonObject.put("xCoord", x); + jsonObject.put("yCoord", y); + jsonObject.put("uid", uid); + jsonObject.put("content", content); + getNetData.getData(this, AppConfig.UrlAddress + "releaseTask", jsonObject, new GetNetData.OnGetDataListener() { + @Override + public void successed(JSONObject data, String status, String msg) { + //上传成功 返回到主页 + toastShort(msg); + finish(); + } + }); + } + //点击时间 + @OnClick({R.id.btnBack, R.id.rightTextView}) + public void onViewClicked(View view) { + switch (view.getId()) { + case R.id.btnBack: + finish(); + break; + case R.id.rightTextView: + try { + //根据跳转过来时 携带的操作类型参数type进行标记或下达任务操作 + if ("1".equals(type)) { + getOtherUsers(); + } else { + uploadMark(); + } + } catch (Exception e) { + e.printStackTrace(); + } + break; + } + } +} \ No newline at end of file diff --git a/Code/Android/projectFirst/app/src/main/java/com/app/projectfirst/activity/loginAndRegist/LoginActivity.java b/Code/Android/projectFirst/app/src/main/java/com/app/projectfirst/activity/loginAndRegist/LoginActivity.java new file mode 100644 index 0000000..b33bb4b --- /dev/null +++ b/Code/Android/projectFirst/app/src/main/java/com/app/projectfirst/activity/loginAndRegist/LoginActivity.java @@ -0,0 +1,125 @@ +package com.app.projectfirst.activity.loginAndRegist; + +import android.Manifest; +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.view.View; +import android.widget.Button; +import android.widget.EditText; + +import com.app.projectfirst.R; +import com.app.projectfirst.activity.BaseActivity; +import com.app.projectfirst.activity.MainActivity; +import com.app.projectfirst.config.AppConfig; +import com.app.projectfirst.utils.GetNetData; + +import org.json.JSONObject; + +import butterknife.BindView; +import butterknife.ButterKnife; +import butterknife.OnClick; +import pub.devrel.easypermissions.EasyPermissions; + +import static com.app.projectfirst.config.AppConfig.ShareKey; + +public class LoginActivity extends BaseActivity { + + private static final String TAG = "LoginActivity"; + String PERMISSION_STORAGE_MSG = "Please grant permission. Otherwise, some functions will be affected"; + int PERMISSION_STORAGE_CODE = 10001; + String[] PERMS = {Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA, Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION}; + @BindView(R.id.userNameInput) + EditText userNameInput; + @BindView(R.id.passwordInput) + EditText passwordInput; + + @BindView(R.id.loginBtn) + Button loginBtn; + @BindView(R.id.registBtn) + Button registBtn; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_login); + ButterKnife.bind(this); + initPermission(); + + } + + /** + * 获取权限 + * WRITE_EXTERNAL_STORAGE存储权限 + * CAMERA 照相权限 + * ACCESS_COARSE_LOCATION 定位权限 + */ + private void initPermission() { + if (!EasyPermissions.hasPermissions(this, PERMS)) { + EasyPermissions.requestPermissions(this, PERMISSION_STORAGE_MSG, PERMISSION_STORAGE_CODE, PERMS); + } else { + } + } + + /** + * 登录方法 + * @throws Exception + */ + private void loginNow() throws Exception { + //获取输入框中的文本字符串 + String userName = userNameInput.getText().toString().trim(); + String password = passwordInput.getText().toString().trim(); + //判空处理 + if (isEmpty(userName)) { + toastShort("请输入用户名"); + return; + } + if (isEmpty(password)) { + toastShort("请输入密码"); + return; + } + //组装成JSONObject + JSONObject jsonObject = new JSONObject(); + jsonObject.put("userName", userName); + jsonObject.put("password", password); + //访问服务器接口 + getNetData.getData(this, AppConfig.UrlAddress + "login", jsonObject, new GetNetData.OnGetDataListener() { + @Override + public void successed(JSONObject data, String status, String msg) { + //服务器访问成功后返回数据 data + //解析data + int userId = getValue.getIntValue(data, "uid"); + String userToken = getValue.getValue(data, "token"); + String userStage = getValue.getValue(data, "userStage"); + //将用户ID token 等级存储到本地 + SharedPreferences.Editor editor = getSharedPreferences(ShareKey, MODE_PRIVATE).edit(); + editor.putInt("userId", userId); + editor.putString("userToken", userToken); + editor.putString("userStage", userStage); + editor.apply(); + //删除所有Activity + activityControl.finishAll(); + //跳转到主页 + startActivity(new Intent(LoginActivity.this, MainActivity.class)); + + } + }); + } + + //点击事件 + @OnClick({R.id.loginBtn, R.id.registBtn}) + public void onViewClicked(View view) { + switch (view.getId()) { + case R.id.loginBtn: + try { + loginNow(); + } catch (Exception e) { + e.printStackTrace(); + } + break; + case R.id.registBtn: + startActivity(RegistActivity.class,false); + break; + } + } +} \ No newline at end of file diff --git a/Code/Android/projectFirst/app/src/main/java/com/app/projectfirst/activity/loginAndRegist/RegistActivity.java b/Code/Android/projectFirst/app/src/main/java/com/app/projectfirst/activity/loginAndRegist/RegistActivity.java new file mode 100644 index 0000000..6e88998 --- /dev/null +++ b/Code/Android/projectFirst/app/src/main/java/com/app/projectfirst/activity/loginAndRegist/RegistActivity.java @@ -0,0 +1,122 @@ +package com.app.projectfirst.activity.loginAndRegist; + +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.view.View; +import android.widget.Button; +import android.widget.EditText; +import android.widget.ImageView; +import android.widget.TextView; + +import com.app.projectfirst.R; +import com.app.projectfirst.activity.BaseActivity; +import com.app.projectfirst.activity.MainActivity; +import com.app.projectfirst.config.AppConfig; +import com.app.projectfirst.utils.GetNetData; + +import org.json.JSONObject; + +import butterknife.BindView; +import butterknife.ButterKnife; +import butterknife.OnClick; + +import static com.app.projectfirst.config.AppConfig.ShareKey; + +public class RegistActivity extends BaseActivity { + + @BindView(R.id.btnBack) + ImageView btnBack; + @BindView(R.id.title) + TextView title; + @BindView(R.id.userNameInput) + EditText userNameInput; + @BindView(R.id.passwordInput) + EditText passwordInput; + @BindView(R.id.passwordConfirmInput) + EditText passwordConfirmInput; + @BindView(R.id.registBtn) + Button registBtn; + @BindView(R.id.rightTextView) + TextView rightTextView; + @BindView(R.id.nickNameInput) + EditText nickNameInput; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_regist); + ButterKnife.bind(this); + title.setText("注册"); + } + + private void registNow() throws Exception { + //获取输入框中的文本字符串 + String userName = userNameInput.getText().toString().trim(); + String password = passwordInput.getText().toString().trim(); + String passwordConfirm = passwordConfirmInput.getText().toString().trim(); + String nickName = nickNameInput.getText().toString().trim(); + //判空处理 + if (isEmpty(userName)) { + toastShort("请输入用户名"); + return; + } + if (isEmpty(password)) { + toastShort("请输入密码"); + return; + } + if (isEmpty(passwordConfirm)) { + toastShort("请确定密码"); + return; + } + if (!password.equals(passwordConfirm)) { + toastShort("密码输入不一致"); + return; + } + if (isEmpty(nickName)) { + toastShort("请输入昵称"); + return; + } + //组装成JSONObject + JSONObject jsonObject = new JSONObject(); + jsonObject.put("userName", userName); + jsonObject.put("password", password); + jsonObject.put("nickName", nickName); + getNetData.getData(this, AppConfig.UrlAddress + "regist", jsonObject, new GetNetData.OnGetDataListener() { + @Override + public void successed(JSONObject data, String status, String msg) { + //服务器访问成功后返回数据 data + //解析data + int userId = getValue.getIntValue(data, "uid"); + String userToken = getValue.getValue(data, "token"); + String userStage = getValue.getValue(data, "userStage"); + SharedPreferences.Editor editor = getSharedPreferences(ShareKey, MODE_PRIVATE).edit(); + editor.putInt("userId", userId); + editor.putString("userToken", userToken); + editor.putString("userStage", userStage); + editor.apply(); + //删除所有Activity + activityControl.finishAll(); + //跳转到主页 + startActivity(new Intent(RegistActivity.this, MainActivity.class)); + + } + }); + } + + @OnClick({R.id.btnBack, R.id.registBtn}) + public void onViewClicked(View view) { + switch (view.getId()) { + case R.id.btnBack: + finish(); + break; + case R.id.registBtn: + try { + registNow(); + } catch (Exception e) { + e.printStackTrace(); + } + break; + } + } +} \ No newline at end of file diff --git a/Code/Android/projectFirst/app/src/main/java/com/app/projectfirst/adapter/MarksAdapter.java b/Code/Android/projectFirst/app/src/main/java/com/app/projectfirst/adapter/MarksAdapter.java new file mode 100644 index 0000000..1614372 --- /dev/null +++ b/Code/Android/projectFirst/app/src/main/java/com/app/projectfirst/adapter/MarksAdapter.java @@ -0,0 +1,83 @@ +package com.app.projectfirst.adapter; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.app.projectfirst.R; +import com.app.projectfirst.entity.Marks; + +import java.util.List; + +//RecyclerView控件适配器 +public class MarksAdapter extends RecyclerView.Adapter { + private List list; + private Context context; + private OnItemClickListener mOnItemClickListener; + + /** + * 有参构造方法 传入上下文和标记集合 + * @param context + * @param list + */ + public MarksAdapter(Context context, List list) { + this.context = context; + this.list = list; + + } + + @NonNull + @Override + public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + ViewHolder holder = new ViewHolder(LayoutInflater.from(context).inflate(R.layout.adapter_marks,parent,false)); + return holder; + } + + @Override + public void onBindViewHolder(@NonNull ViewHolder holder, int position) { + Marks marks = list.get(position); + holder.nickName.setText(marks.getNickName()); + holder.xCoord.setText(marks.getMarkXCoord()+""); + holder.yCoord.setText(marks.getMarkYCoord()+""); + if(mOnItemClickListener!=null){ + holder.shareBtn.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + int pos = holder.getLayoutPosition(); + mOnItemClickListener.receive(holder.shareBtn,pos,marks); + } + }); + } + } + + @Override + public int getItemCount() { + return list.size(); + } + + + static class ViewHolder extends RecyclerView.ViewHolder{ + TextView nickName; + TextView shareBtn; + TextView xCoord; + TextView yCoord; + public ViewHolder(@NonNull View itemView) { + super(itemView); + nickName = (TextView)itemView.findViewById(R.id.nickName); + shareBtn = (TextView)itemView.findViewById(R.id.shareBtn); + xCoord = (TextView)itemView.findViewById(R.id.xCoord); + yCoord = (TextView)itemView.findViewById(R.id.yCoord); + } + } + public interface OnItemClickListener{ + void receive(View view, int position, Marks marks); + } + public void setOnItemClickListener(OnItemClickListener onItemClickListener){ + mOnItemClickListener = onItemClickListener; + } +} diff --git a/Code/Android/projectFirst/app/src/main/java/com/app/projectfirst/config/AppConfig.java b/Code/Android/projectFirst/app/src/main/java/com/app/projectfirst/config/AppConfig.java new file mode 100644 index 0000000..8c48ead --- /dev/null +++ b/Code/Android/projectFirst/app/src/main/java/com/app/projectfirst/config/AppConfig.java @@ -0,0 +1,11 @@ +package com.app.projectfirst.config; + +public class AppConfig { + public static final String UrlAddress = "http://192.168.150.1:8080/"; + public static final String defaultNetFilePath = UrlAddress+"files/"; + public static final String ShareKey = "userInfo";// + public static final boolean show = true; + public static final boolean logShow = true; + public static final int y = 10; + public static final int x = 10; +} diff --git a/Code/Android/projectFirst/app/src/main/java/com/app/projectfirst/entity/Marks.java b/Code/Android/projectFirst/app/src/main/java/com/app/projectfirst/entity/Marks.java new file mode 100644 index 0000000..3b2449e --- /dev/null +++ b/Code/Android/projectFirst/app/src/main/java/com/app/projectfirst/entity/Marks.java @@ -0,0 +1,81 @@ +package com.app.projectfirst.entity; + +public class Marks { + private int markId; + private int uid; + private String nickName; + private int markXCoord; + private int markYCoord; + private String isShare; + public Marks() { + } + + public Marks(int markId, int uid, String nickName, int markXCoord, int markYCoord, String isShare) { + this.markId = markId; + this.uid = uid; + this.nickName = nickName; + this.markXCoord = markXCoord; + this.markYCoord = markYCoord; + this.isShare = isShare; + } + + public int getMarkId() { + return markId; + } + + public void setMarkId(int markId) { + this.markId = markId; + } + + public int getUid() { + return uid; + } + + public void setUid(int uid) { + this.uid = uid; + } + + public String getNickName() { + return nickName; + } + + public void setNickName(String nickName) { + this.nickName = nickName; + } + + public int getMarkXCoord() { + return markXCoord; + } + + public void setMarkXCoord(int markXCoord) { + this.markXCoord = markXCoord; + } + + public int getMarkYCoord() { + return markYCoord; + } + + public void setMarkYCoord(int markYCoord) { + this.markYCoord = markYCoord; + } + + public String getIsShare() { + return isShare; + } + + public void setIsShare(String isShare) { + this.isShare = isShare; + } + + @Override + public String toString() { + return "Marks{" + + "markId=" + markId + + ", uid=" + uid + + ", nickName='" + nickName + '\'' + + ", markXCoord=" + markXCoord + + ", markYCoord=" + markYCoord + + ", isShare='" + isShare + '\'' + + '}'; + } +} diff --git a/Code/Android/projectFirst/app/src/main/java/com/app/projectfirst/entity/Tasks.java b/Code/Android/projectFirst/app/src/main/java/com/app/projectfirst/entity/Tasks.java new file mode 100644 index 0000000..e5037ab --- /dev/null +++ b/Code/Android/projectFirst/app/src/main/java/com/app/projectfirst/entity/Tasks.java @@ -0,0 +1,70 @@ +package com.app.projectfirst.entity; + +public class Tasks { + private int taskId; + private int uid; + private String content; + private int taskXCoord; + private int taskYCoord; + public Tasks() { + } + + public Tasks(int taskId, int uid, String content, int taskXCoord, int taskYCoord) { + this.taskId = taskId; + this.uid = uid; + this.content = content; + this.taskXCoord = taskXCoord; + this.taskYCoord = taskYCoord; + } + + public int getTaskId() { + return taskId; + } + + public void setTaskId(int taskId) { + this.taskId = taskId; + } + + public int getUid() { + return uid; + } + + public void setUid(int uid) { + this.uid = uid; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + public int getTaskXCoord() { + return taskXCoord; + } + + public void setTaskXCoord(int taskXCoord) { + this.taskXCoord = taskXCoord; + } + + public int getTaskYCoord() { + return taskYCoord; + } + + public void setTaskYCoord(int taskYCoord) { + this.taskYCoord = taskYCoord; + } + + @Override + public String toString() { + return "Tasks{" + + "taskId=" + taskId + + ", uid=" + uid + + ", content='" + content + '\'' + + ", taskXCoord=" + taskXCoord + + ", taskYCoord=" + taskYCoord + + '}'; + } +} diff --git a/Code/Android/projectFirst/app/src/main/java/com/app/projectfirst/entity/Users.java b/Code/Android/projectFirst/app/src/main/java/com/app/projectfirst/entity/Users.java new file mode 100644 index 0000000..da4014d --- /dev/null +++ b/Code/Android/projectFirst/app/src/main/java/com/app/projectfirst/entity/Users.java @@ -0,0 +1,106 @@ +package com.app.projectfirst.entity; + +import java.io.Serializable; + +public class Users implements Serializable { + private int uid; + private String token; + private String userName; + private String password; + private String nickName; + private int xCoord; + private int yCoord; + private String userStage; + public Users() { + } + + + public Users(int uid, String token, String userName, String password, String nickName, int xCoord, int yCoord, String userStage) { + this.uid = uid; + this.token = token; + this.userName = userName; + this.password = password; + this.nickName = nickName; + this.xCoord = xCoord; + this.yCoord = yCoord; + this.userStage = userStage; + } + + public int getUid() { + return uid; + } + + public void setUid(int uid) { + this.uid = uid; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + + 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; + } + + public String getNickName() { + return nickName; + } + + public void setNickName(String nickName) { + this.nickName = nickName; + } + + public int getxCoord() { + return xCoord; + } + + public void setxCoord(int xCoord) { + this.xCoord = xCoord; + } + + public int getyCoord() { + return yCoord; + } + + public void setyCoord(int yCoord) { + this.yCoord = yCoord; + } + + public String getUserStage() { + return userStage; + } + + public void setUserStage(String userStage) { + this.userStage = userStage; + } + + @Override + public String toString() { + return "Users{" + + "uid=" + uid + + ", token='" + token + '\'' + + ", userName='" + userName + '\'' + + ", password='" + password + '\'' + + ", nickName='" + nickName + '\'' + + ", xCoord='" + xCoord + '\'' + + ", yCoord='" + yCoord + '\'' + + ", userStage='" + userStage + '\'' + + '}'; + } +} diff --git a/Code/Android/projectFirst/app/src/main/java/com/app/projectfirst/utils/ActivityControl.java b/Code/Android/projectFirst/app/src/main/java/com/app/projectfirst/utils/ActivityControl.java new file mode 100644 index 0000000..d31ea4f --- /dev/null +++ b/Code/Android/projectFirst/app/src/main/java/com/app/projectfirst/utils/ActivityControl.java @@ -0,0 +1,64 @@ +package com.app.projectfirst.utils; + +import android.app.Activity; +import android.content.Context; +import android.content.SharedPreferences; + +import java.lang.ref.WeakReference; +import java.util.ArrayList; +import java.util.List; + +import static com.app.projectfirst.config.AppConfig.ShareKey; + +public class ActivityControl { + private static final String TAG = "ActivityControl"; + + private WeakReference sCurrentActivityWeakRef; + private static String token; + public static List activities = new ArrayList<>(); + private static class ActivityControlHolder{ + private static ActivityControl activityControl = new ActivityControl(); + } + public ActivityControl() { + } + public static ActivityControl getInstance(){ + return ActivityControlHolder.activityControl; + } + + public void resetToken(){ + token = ""; + } + + public void addActivity(Activity activity){ + activities.add(activity); + } + public void removeActivity(Activity activity){ + activities.remove(activity); + } + public void finishAll(){ + for (Activity activity:activities) { + if(!activity.isFinishing()){ + activity.finish(); + + } + } + activities.clear(); + } + + + public int returnUserId(Context context){ + SharedPreferences sharedPreferences = context.getSharedPreferences(ShareKey, Context.MODE_PRIVATE); + + return sharedPreferences.getInt("userId",-1); + } + + public String returnUserToken(Context context){ + SharedPreferences sharedPreferences = context.getSharedPreferences(ShareKey, Context.MODE_PRIVATE); + return sharedPreferences.getString("userToken",""); + } + public String returnUserStage(Context context){ + SharedPreferences sharedPreferences = context.getSharedPreferences(ShareKey, Context.MODE_PRIVATE); + return sharedPreferences.getString("userStage",""); + + } +} diff --git a/Code/Android/projectFirst/app/src/main/java/com/app/projectfirst/utils/GetNetData.java b/Code/Android/projectFirst/app/src/main/java/com/app/projectfirst/utils/GetNetData.java new file mode 100644 index 0000000..3bf955b --- /dev/null +++ b/Code/Android/projectFirst/app/src/main/java/com/app/projectfirst/utils/GetNetData.java @@ -0,0 +1,93 @@ +package com.app.projectfirst.utils; + +import android.app.Activity; +import android.content.Context; +import android.content.ContextWrapper; + +import com.app.projectfirst.config.AppConfig; +import com.loopj.android.http.JsonHttpResponseHandler; + +import org.json.JSONException; +import org.json.JSONObject; + +import cz.msebera.android.httpclient.Header; + + +public class GetNetData { + private static GetValueImpl getValue; + private static final String TAG = "getNetData"; + private static class GetNetworkDataHolder{ + private static GetNetData getNetworkData = new GetNetData(); + } + public GetNetData() { + } + public static GetNetData getInstance(){ + getValue = GetValueImpl.getInstance(); + return GetNetworkDataHolder.getNetworkData; + } + + public void getData(final Context context, final String url, JSONObject jsonObject, final OnGetDataListener onGetDataListener){ + HttpClientManager.post(context,url,jsonObject,new JsonHttpResponseHandler(){ + @Override + public void onSuccess(int statusCode, Header[] headers, JSONObject outputJson) { + if (outputJson!=null){ + //statusCode == 200 + String status = getValue.getValue(outputJson,"status"); + String msg = getValue.getValue(outputJson,"msg"); + JSONObject data = null; + try { + data = new JSONObject(getValue.getValue(outputJson,"data")); + } catch (JSONException e) { + e.printStackTrace(); + } + Activity activity = findActivity(context); + // LogUtils.e(activity != null ? activity.getLocalClassName(): context.getPackageName(),"___"+data.toString()+"___"); + if ("0".equals(status)){ + onGetDataListener.successed(data,status,msg); + }else { + LogUtils.e(TAG,"getDataFromServiceFive failed url is:"+url); + ToastUtils.toastShort(context,msg); +// onGetDataListener.failed(data,status,msg); + } + } + } + + @Override + public void onFailure(int statusCode, Header[] headers, String responseBody, Throwable throwable) { + LogUtils.e(TAG,"getDataFromServiceFive onFailure1 url is:"+url); + String str = "服务器连接错误-"+statusCode; + if (AppConfig.show) { + str += ("___" + url); + } + ToastUtils.toastShort(context,str); +// onGetDataListener.netError(str); + } + + @Override + public void onFailure(int statusCode, Header[] headers, Throwable throwable, JSONObject errorResponse) { + LogUtils.e(TAG,"getDataFromServiceFive onFailure2 url is:"+url); + String str = "服务器连接错误-"+statusCode; + if (AppConfig.show){ + str+=("___"+url); + } + ToastUtils.toastShort(context,str); + } + }); + } + + public interface OnGetDataListener{ + void successed(JSONObject data, String status, String msg); + } + + public static Activity findActivity(Context context) { + if (context instanceof Activity) { + return (Activity) context; + } + if (context instanceof ContextWrapper) { + ContextWrapper wrapper = (ContextWrapper) context; + return findActivity(wrapper.getBaseContext()); + } else { + return null; + } + } +} diff --git a/Code/Android/projectFirst/app/src/main/java/com/app/projectfirst/utils/GetValueImpl.java b/Code/Android/projectFirst/app/src/main/java/com/app/projectfirst/utils/GetValueImpl.java new file mode 100644 index 0000000..8e949c2 --- /dev/null +++ b/Code/Android/projectFirst/app/src/main/java/com/app/projectfirst/utils/GetValueImpl.java @@ -0,0 +1,145 @@ +package com.app.projectfirst.utils; + + + +import org.json.JSONArray; +import org.json.JSONObject; + +import java.io.File; + + +public class GetValueImpl { + private static class GetValueImplHolder { + private static GetValueImpl getValue = new GetValueImpl(); + } + public GetValueImpl() { + } + public static GetValueImpl getInstance(){ + return GetValueImplHolder.getValue; + } + + public String getValue(JSONObject jsonObject, String key) { + String value = ""; + try { + if(jsonObject!=null) { + if (jsonObject.has(key)) { + value = jsonObject.getString(key); + } + } + }catch (Exception e){ + e.printStackTrace(); + } + return value; + } + public float getFloatValue(JSONObject jsonObject, String key) { + float value = 0; + try { + if (jsonObject!=null) { + if (jsonObject.has(key)) { + String valueStr = jsonObject.getString(key); + value = Float.valueOf(valueStr); + } + } + }catch (Exception e){ + e.printStackTrace(); + } + return value; + } + public double getDoubleValue(JSONObject jsonObject, String key) { + double value = 0; + try { + if (jsonObject!=null) { + if (jsonObject.has(key)) { + String valueStr = jsonObject.getString(key); + value = Double.valueOf(valueStr); + } + } + }catch (Exception e){ + e.printStackTrace(); + } + return value; + } + public int getIntValue(JSONObject jsonObject, String key) { + int value = 0; + try { + if (jsonObject!=null) { + if (jsonObject.has(key)) { + value = jsonObject.getInt(key); + } + } + }catch (Exception e){ + e.printStackTrace(); + } + return value; + } + public boolean getBooleanValue(JSONObject jsonObject, String key) { + boolean value = false; + try { + if (jsonObject!=null) { + if (jsonObject.has(key)) { + value = jsonObject.getBoolean(key); + } + } + }catch (Exception e){ + e.printStackTrace(); + } + return value; + } + + public JSONObject getJSONObjecValue(JSONObject jsonObject, String key) { + JSONObject value = new JSONObject(); + try { + if (jsonObject!=null) { + if (jsonObject.has(key)) { + value = jsonObject.getJSONObject(key); + } + } + }catch (Exception e){ + e.printStackTrace(); + } + return value; + } + + + public JSONArray getJSONArrayValue(JSONObject jsonObject, String key) { + JSONArray value = new JSONArray(); + try { + if (jsonObject!=null) { + if (jsonObject.has(key)) { + value = jsonObject.getJSONArray(key); + } + } + }catch (Exception e){ + e.printStackTrace(); + } + return value; + } + public File getFileValue(JSONObject jsonObject, String key){ + File file = null; + try{ + if (jsonObject!=null){ + if (jsonObject.has(key)){ + file = (File) jsonObject.get(key); + } + } + }catch (Exception e){ + e.printStackTrace(); + } + return file; + } + public Object getObjectValue(JSONObject jsonObject, String key){ + Object object = null; + try { + if (jsonObject!=null){ + if (jsonObject.has(key)){ + object = jsonObject.get(key); + } + } + }catch (Exception e){ + e.printStackTrace(); + } + return object; + } + + +} diff --git a/Code/Android/projectFirst/app/src/main/java/com/app/projectfirst/utils/HttpClientManager.java b/Code/Android/projectFirst/app/src/main/java/com/app/projectfirst/utils/HttpClientManager.java new file mode 100644 index 0000000..d25b773 --- /dev/null +++ b/Code/Android/projectFirst/app/src/main/java/com/app/projectfirst/utils/HttpClientManager.java @@ -0,0 +1,59 @@ +package com.app.projectfirst.utils; + +import android.content.Context; + +import com.loopj.android.http.AsyncHttpClient; +import com.loopj.android.http.AsyncHttpResponseHandler; +import com.loopj.android.http.BinaryHttpResponseHandler; +import com.loopj.android.http.JsonHttpResponseHandler; +import com.loopj.android.http.RequestHandle; +import com.loopj.android.http.RequestParams; + +import org.json.JSONObject; + +import cz.msebera.android.httpclient.entity.StringEntity; + +public class HttpClientManager { + + public static AsyncHttpClient client = new AsyncHttpClient(); // 实例话对象 + + static { + client.setTimeout(30*1000); // 设置链接超时,如果不设置,默认为10s + } + + public static RequestHandle post(Context context, final String url, RequestParams params, + AsyncHttpResponseHandler handler) { + RequestHandle requestHandle=client.post(context,url, params,handler); + return requestHandle; + } + public static RequestHandle post(Context context, final String url, JSONObject jsonParam, + AsyncHttpResponseHandler handler) { + + StringEntity entity = new StringEntity(jsonParam.toString(),"utf-8");//解决中文乱码问题 + RequestHandle requestHandle=client.post(context,url, entity,"application/json",handler); + return requestHandle; + } + + public static RequestHandle get(String urlString, JsonHttpResponseHandler res) // 不带参数,获取json对象或者数组 + { + RequestHandle requestHandle=client.get(urlString, res); + return requestHandle; + } + + public static RequestHandle get(String urlString, RequestParams params, + JsonHttpResponseHandler res) // 带参数,获取json对象或者数组 + { + RequestHandle requestHandle=client.get(urlString, params, res); + return requestHandle; + } + + public static RequestHandle get(String uString, BinaryHttpResponseHandler bHandler) // 下载数据使用,会返回byte数据 + { + RequestHandle requestHandle=client.get(uString, bHandler); + return requestHandle; + } + + public static AsyncHttpClient getClient() { + return client; + } +} diff --git a/Code/Android/projectFirst/app/src/main/java/com/app/projectfirst/utils/HttpClientManagerSync.java b/Code/Android/projectFirst/app/src/main/java/com/app/projectfirst/utils/HttpClientManagerSync.java new file mode 100644 index 0000000..15e6bf9 --- /dev/null +++ b/Code/Android/projectFirst/app/src/main/java/com/app/projectfirst/utils/HttpClientManagerSync.java @@ -0,0 +1,60 @@ +package com.app.projectfirst.utils; + +import android.content.Context; + +import com.loopj.android.http.AsyncHttpClient; +import com.loopj.android.http.AsyncHttpResponseHandler; +import com.loopj.android.http.BinaryHttpResponseHandler; +import com.loopj.android.http.JsonHttpResponseHandler; +import com.loopj.android.http.RequestHandle; +import com.loopj.android.http.RequestParams; +import com.loopj.android.http.SyncHttpClient; + +import org.json.JSONObject; + +import cz.msebera.android.httpclient.entity.StringEntity; + +public class HttpClientManagerSync { + + public static SyncHttpClient client = new SyncHttpClient(); // 实例话对象 + + static { + client.setTimeout(30*1000); // 设置链接超时,如果不设置,默认为10s + } + + public static RequestHandle post(Context context, final String url, RequestParams params, + AsyncHttpResponseHandler handler) { + RequestHandle requestHandle=client.post(context,url, params,handler); + return requestHandle; + } + public static RequestHandle post(Context context, final String url, JSONObject jsonParam, + AsyncHttpResponseHandler handler) { + + StringEntity entity = new StringEntity(jsonParam.toString(),"utf-8");//解决中文乱码问题 + RequestHandle requestHandle=client.post(context,url, entity,"application/json",handler); + return requestHandle; + } + + public static RequestHandle get(String urlString, JsonHttpResponseHandler res) // 不带参数,获取json对象或者数组 + { + RequestHandle requestHandle=client.get(urlString, res); + return requestHandle; + } + + public static RequestHandle get(String urlString, RequestParams params, + JsonHttpResponseHandler res) // 带参数,获取json对象或者数组 + { + RequestHandle requestHandle=client.get(urlString, params, res); + return requestHandle; + } + + public static RequestHandle get(String uString, BinaryHttpResponseHandler bHandler) // 下载数据使用,会返回byte数据 + { + RequestHandle requestHandle=client.get(uString, bHandler); + return requestHandle; + } + + public static AsyncHttpClient getClient() { + return client; + } +} diff --git a/Code/Android/projectFirst/app/src/main/java/com/app/projectfirst/utils/LogUtils.java b/Code/Android/projectFirst/app/src/main/java/com/app/projectfirst/utils/LogUtils.java new file mode 100644 index 0000000..ac07bce --- /dev/null +++ b/Code/Android/projectFirst/app/src/main/java/com/app/projectfirst/utils/LogUtils.java @@ -0,0 +1,40 @@ +package com.app.projectfirst.utils; + +import android.util.Log; + +import com.app.projectfirst.config.AppConfig; + +public class LogUtils { + public static final int VERBOSE = 1; + public static final int DEBUG = 2; + public static final int INFO = 3; + public static final int WARN = 4; + public static final int ERROR = 5; + public static final int NOTHING = 6; + public static final int level = VERBOSE; + public static void v(String tag, String msg){ + if (AppConfig.logShow) { + Log.v(tag, msg); + } + } + public static void d(String tag, String msg){ + if (AppConfig.logShow) { + Log.d(tag, msg); + } + } + public static void i(String tag, String msg){ + if (AppConfig.logShow) { + Log.i(tag, msg); + } + } + public static void w(String tag, String msg){ + if (AppConfig.logShow) { + Log.w(tag, msg); + } + } + public static void e(String tag, String msg){ + if (AppConfig.logShow) { + Log.e(tag, msg); + } + } +} diff --git a/Code/Android/projectFirst/app/src/main/java/com/app/projectfirst/utils/OSUtils.java b/Code/Android/projectFirst/app/src/main/java/com/app/projectfirst/utils/OSUtils.java new file mode 100644 index 0000000..b4f9c49 --- /dev/null +++ b/Code/Android/projectFirst/app/src/main/java/com/app/projectfirst/utils/OSUtils.java @@ -0,0 +1,121 @@ +package com.app.projectfirst.utils; + + +import android.os.Build; +import android.text.TextUtils; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; + +public class OSUtils { + + public static final String ROM_MIUI = "MIUI"; + public static final String ROM_EMUI = "EMUI"; + public static final String ROM_FLYME = "FLYME"; + public static final String ROM_OPPO = "OPPO"; + public static final String ROM_SMARTISAN = "SMARTISAN"; + public static final String ROM_VIVO = "VIVO"; + public static final String ROM_QIKU = "QIKU"; + + private static final String KEY_VERSION_MIUI = "ro.miui.ui.version.name"; + private static final String KEY_VERSION_EMUI = "ro.build.version.emui"; + private static final String KEY_VERSION_OPPO = "ro.build.version.opporom"; + private static final String KEY_VERSION_SMARTISAN = "ro.smartisan.version"; + private static final String KEY_VERSION_VIVO = "ro.vivo.os.version"; + + private static String sName; + private static String sVersion; + + public static boolean isEmui() { + return check(ROM_EMUI); + } + + public static boolean isMiui() { + return check(ROM_MIUI); + } + + public static boolean isVivo() { + return check(ROM_VIVO); + } + + public static boolean isOppo() { + return check(ROM_OPPO); + } + + public static boolean isFlyme() { + return check(ROM_FLYME); + } + + public static boolean is360() { + return check(ROM_QIKU) || check("360"); + } + + public static boolean isSmartisan() { + return check(ROM_SMARTISAN); + } + + public static String getName() { + if (sName == null) { + check(""); + } + return sName; + } + + public static String getVersion() { + if (sVersion == null) { + check(""); + } + return sVersion; + } + + public static boolean check(String rom) { + if (sName != null) { + return sName.equals(rom); + } + + if (!TextUtils.isEmpty(sVersion = getProp(KEY_VERSION_MIUI))) { + sName = ROM_MIUI; + } else if (!TextUtils.isEmpty(sVersion = getProp(KEY_VERSION_EMUI))) { + sName = ROM_EMUI; + } else if (!TextUtils.isEmpty(sVersion = getProp(KEY_VERSION_OPPO))) { + sName = ROM_OPPO; + } else if (!TextUtils.isEmpty(sVersion = getProp(KEY_VERSION_VIVO))) { + sName = ROM_VIVO; + } else if (!TextUtils.isEmpty(sVersion = getProp(KEY_VERSION_SMARTISAN))) { + sName = ROM_SMARTISAN; + } else { + sVersion = Build.DISPLAY; + if (sVersion.toUpperCase().contains(ROM_FLYME)) { + sName = ROM_FLYME; + } else { + sVersion = Build.UNKNOWN; + sName = Build.MANUFACTURER.toUpperCase(); + } + } + return sName.equals(rom); + } + + public static String getProp(String name) { + String line = null; + BufferedReader input = null; + try { + Process p = Runtime.getRuntime().exec("getprop " + name); + input = new BufferedReader(new InputStreamReader(p.getInputStream()), 1024); + line = input.readLine(); + input.close(); + } catch (IOException ex) { + return null; + } finally { + if (input != null) { + try { + input.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return line; + } +} + diff --git a/Code/Android/projectFirst/app/src/main/java/com/app/projectfirst/utils/ToastUtils.java b/Code/Android/projectFirst/app/src/main/java/com/app/projectfirst/utils/ToastUtils.java new file mode 100644 index 0000000..8595584 --- /dev/null +++ b/Code/Android/projectFirst/app/src/main/java/com/app/projectfirst/utils/ToastUtils.java @@ -0,0 +1,55 @@ +package com.app.projectfirst.utils; + +import android.content.Context; +import android.view.Gravity; +import android.widget.Toast; + +import com.app.projectfirst.config.AppConfig; + + +public class ToastUtils { + + public static void toastShort(Context context, String msg){ + try { + Toast toast = Toast.makeText(context,msg, Toast.LENGTH_SHORT); + toast.setGravity(Gravity.CENTER , 0, 0); + toast.show(); + }catch (Exception e){ + e.printStackTrace(); + } + + } + public static void toastLong(Context context, String msg){ + try { + Toast toast = Toast.makeText(context,msg, Toast.LENGTH_LONG); + toast.setGravity(Gravity.CENTER , 0, 0); + toast.show(); + }catch (Exception e){ + e.printStackTrace(); + } + + } + + public static void toastShortTest(Context context, String msg){ + try { + if (AppConfig.show){ + Toast toast = Toast.makeText(context,msg, Toast.LENGTH_SHORT); + toast.setGravity(Gravity.CENTER , 0, 0); + toast.show(); + } + }catch (Exception e){ + e.printStackTrace(); + } + } + public static void toastLongTest(Context context, String msg){ + try { + if (AppConfig.show){ + Toast toast = Toast.makeText(context,msg, Toast.LENGTH_LONG); + toast.setGravity(Gravity.CENTER , 0, 0); + toast.show(); + } + }catch (Exception e){ + e.printStackTrace(); + } + } +} diff --git a/Code/Android/projectFirst/app/src/main/java/com/app/projectfirst/utils/UploadFileByOkHttp.java b/Code/Android/projectFirst/app/src/main/java/com/app/projectfirst/utils/UploadFileByOkHttp.java new file mode 100644 index 0000000..d5dcff3 --- /dev/null +++ b/Code/Android/projectFirst/app/src/main/java/com/app/projectfirst/utils/UploadFileByOkHttp.java @@ -0,0 +1,42 @@ +package com.app.projectfirst.utils; + +import java.io.File; +import java.util.UUID; + +import okhttp3.MediaType; +import okhttp3.MultipartBody; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.RequestBody; +import okhttp3.Response; + +public class UploadFileByOkHttp { + + public UploadFileByOkHttp() { + } + private static class UploadFileByOkHttpHolder{ + private static UploadFileByOkHttp getUploadFileByOkHttp = new UploadFileByOkHttp(); + } + public static UploadFileByOkHttp getInstance(){ + return UploadFileByOkHttp.UploadFileByOkHttpHolder.getUploadFileByOkHttp; + } + public Response upload(String url, String filePath, String fileName) throws Exception { + OkHttpClient client = new OkHttpClient(); + RequestBody requestBody = new MultipartBody.Builder() + .setType(MultipartBody.FORM) + .addFormDataPart("file", fileName, + RequestBody.create(MediaType.parse("multipart/form-data"), new File(filePath))) + .build(); + + Request request = new Request.Builder() + .header("Authorization", "Client-ID " + UUID.randomUUID()) + .url(url) + .post(requestBody) + .build(); + + Response response = client.newCall(request).execute(); +// if (!response.isSuccessful()) throw new IOException("Unexpected code " + response); + + return response; + } +} diff --git a/Code/Android/projectFirst/app/src/main/java/com/app/projectfirst/utils/Uri2PathUtil.java b/Code/Android/projectFirst/app/src/main/java/com/app/projectfirst/utils/Uri2PathUtil.java new file mode 100644 index 0000000..1aebb4f --- /dev/null +++ b/Code/Android/projectFirst/app/src/main/java/com/app/projectfirst/utils/Uri2PathUtil.java @@ -0,0 +1,193 @@ +package com.app.projectfirst.utils; + +import android.annotation.TargetApi; +import android.content.ContentResolver; +import android.content.ContentUris; +import android.content.Context; +import android.database.Cursor; +import android.net.Uri; +import android.os.Build; +import android.os.Environment; +import android.provider.DocumentsContract; +import android.provider.MediaStore; + +import androidx.loader.content.CursorLoader; + +public class Uri2PathUtil { + private static final String TAG = "Uri2PathUtil"; + //复杂版处理 (适配多种API) + public static String getRealPathFromUri(Context context, Uri uri) { + int sdkVersion = Build.VERSION.SDK_INT; + if (sdkVersion < 11) return getRealPathFromUri_BelowApi11(context, uri); + if (sdkVersion < 19) return getRealPathFromUri_Api11To18(context, uri); + else return getRealPathFromUri_AboveApi19(context, uri); + } + + /** + * 适配api19以上,根据uri获取图片的绝对路径 + */ + @TargetApi(Build.VERSION_CODES.KITKAT) + private static String getRealPathFromUri_AboveApi19(Context context, Uri uri) { + if (DocumentsContract.isDocumentUri(context, uri)) { + if (isExternalStorageDocument(uri)) { + final String docId = DocumentsContract.getDocumentId(uri); + final String[] split = docId.split(":"); + final String type = split[0]; + if ("primary".equalsIgnoreCase(type)) { + return Environment.getExternalStorageDirectory() + "/" + split[1]; + } + } else if (isDownloadsDocument(uri)) { + final String id = DocumentsContract.getDocumentId(uri); + final Uri contentUri = ContentUris.withAppendedId( + Uri.parse("content://downloads/public_downloads"), Long.valueOf(id)); + + return getDataColumn(context, contentUri, null, null); + } else if (isMediaDocument(uri)) { + final String docId = DocumentsContract.getDocumentId(uri); + final String[] split = docId.split(":"); + final String type = split[0]; + + Uri contentUri; + if ("image".equals(type)) { + contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; + } else if ("video".equals(type)) { + contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; + } else if ("audio".equals(type)) { + contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; + } else { + contentUri = MediaStore.Files.getContentUri("external"); + } + + final String selection = "_id=?"; + final String[] selectionArgs = new String[]{split[1]}; + return getDataColumn(context, contentUri, selection, selectionArgs); + } + + + } else if ("content".equalsIgnoreCase(uri.getScheme())) { + return getDataColumn(context, uri, null, null); + } else if ("file".equalsIgnoreCase(uri.getScheme())) { + return uri.getPath(); + } + + return null; + } + + /** + * 适配api11-api18,根据uri获取图片的绝对路径 + */ + private static String getRealPathFromUri_Api11To18(Context context, Uri uri) { + String filePath = null; + String[] projection = {MediaStore.Images.Media.DATA}; + //这个有两个包不知道是哪个。。。。不过这个复杂版一般用不到 + CursorLoader loader = new CursorLoader(context, uri, projection, null, null, null); + Cursor cursor = loader.loadInBackground(); + + if (cursor != null) { + cursor.moveToFirst(); + filePath = cursor.getString(cursor.getColumnIndex(projection[0])); + cursor.close(); + } + return filePath; + } + + /** + * 适配api11以下(不包括api11),根据uri获取图片的绝对路径 + */ + private static String getRealPathFromUri_BelowApi11(Context context, Uri uri) { + String filePath = null; + String[] projection = {MediaStore.Images.Media.DATA}; + Cursor cursor = context.getContentResolver().query(uri, projection, null, null, null); + if (cursor != null && cursor.moveToFirst()) { + filePath = cursor.getString(cursor.getColumnIndex(projection[0])); + cursor.close(); + } + return filePath; + } + + /** + * Get the value of the data column for this Uri. This is useful for + * MediaStore Uris, and other file-based ContentProviders. + * + * @param context The context. + * @param uri The Uri to query. + * @param selection (Optional) Filter used in the query. + * @param selectionArgs (Optional) Selection arguments used in the query. + * @return The value of the _data column, which is typically a file path. + */ + public static String getDataColumn(Context context, Uri uri, String selection, + String[] selectionArgs) { + Cursor cursor = null; + String column = MediaStore.MediaColumns.DATA; + String[] projection = {column}; + LogUtils.e(TAG,uri.toString()); + try { + cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, + null); + if (cursor != null && cursor.moveToFirst()) { + int column_index = cursor.getColumnIndexOrThrow(column); + return cursor.getString(column_index); + } + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (cursor != null) + cursor.close(); + } + return null; + } + + /** + * @param uri The Uri to check. + * @return Whether the Uri authority is ExternalStorageProvider. + */ + public static boolean isExternalStorageDocument(Uri uri) { + return "com.android.externalstorage.documents".equals(uri.getAuthority()); + } + + /** + * @param uri The Uri to check. + * @return Whether the Uri authority is DownloadsProvider. + */ + public static boolean isDownloadsDocument(Uri uri) { + return "com.android.providers.downloads.documents".equals(uri.getAuthority()); + } + + /** + * @param uri The Uri to check. + * @return Whether the Uri authority is MediaProvider. + */ + public static boolean isMediaDocument(Uri uri) { + return "com.android.providers.media.documents".equals(uri.getAuthority()); + } + public static String getRealFilePath(final Context context, final Uri uri ) { + if ( null == uri ) return null; + final String scheme = uri.getScheme(); + String data = null; + LogUtils.e(TAG,"scheme is:"+scheme); + if ( scheme == null ) + data = uri.getPath(); + else if ( ContentResolver.SCHEME_FILE.equals( scheme ) ) { + data = uri.getPath(); + } else if ( ContentResolver.SCHEME_CONTENT.equals( scheme ) ) { + LogUtils.e(TAG,"测试锚点1"); + Cursor cursor = context.getContentResolver().query( uri, new String[] { MediaStore.Images.ImageColumns.DATA }, null, null, null ); + if ( null != cursor ) { + LogUtils.e(TAG,"测试锚点2"); + if ( cursor.moveToFirst() ) { + + int index = cursor.getColumnIndex( MediaStore.Images.ImageColumns.DATA ); + LogUtils.e(TAG,"测试锚点3___"+index); + if ( index > -1 ) { + LogUtils.e(TAG,"测试锚点4"); + data = cursor.getString( index ); + } + } + cursor.close(); + } + } + LogUtils.e(TAG,"测试锚点5"+data); + return data; + } + +} diff --git a/Code/Android/projectFirst/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/Code/Android/projectFirst/app/src/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 0000000..2b068d1 --- /dev/null +++ b/Code/Android/projectFirst/app/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/Code/Android/projectFirst/app/src/main/res/drawable/a_round_view_four_1296db_bg.xml b/Code/Android/projectFirst/app/src/main/res/drawable/a_round_view_four_1296db_bg.xml new file mode 100644 index 0000000..7d9b4fe --- /dev/null +++ b/Code/Android/projectFirst/app/src/main/res/drawable/a_round_view_four_1296db_bg.xml @@ -0,0 +1,12 @@ + + + + + + + + + \ No newline at end of file diff --git a/Code/Android/projectFirst/app/src/main/res/drawable/a_round_view_four_border_c1296db.xml b/Code/Android/projectFirst/app/src/main/res/drawable/a_round_view_four_border_c1296db.xml new file mode 100644 index 0000000..4640e70 --- /dev/null +++ b/Code/Android/projectFirst/app/src/main/res/drawable/a_round_view_four_border_c1296db.xml @@ -0,0 +1,12 @@ + + + + + + + + + \ No newline at end of file diff --git a/Code/Android/projectFirst/app/src/main/res/drawable/back_white_icon.png b/Code/Android/projectFirst/app/src/main/res/drawable/back_white_icon.png new file mode 100644 index 0000000..ee2e1ec Binary files /dev/null and b/Code/Android/projectFirst/app/src/main/res/drawable/back_white_icon.png differ diff --git a/Code/Android/projectFirst/app/src/main/res/drawable/blue.png b/Code/Android/projectFirst/app/src/main/res/drawable/blue.png new file mode 100644 index 0000000..0a6aeac Binary files /dev/null and b/Code/Android/projectFirst/app/src/main/res/drawable/blue.png differ diff --git a/Code/Android/projectFirst/app/src/main/res/drawable/green.png b/Code/Android/projectFirst/app/src/main/res/drawable/green.png new file mode 100644 index 0000000..87c37ba Binary files /dev/null and b/Code/Android/projectFirst/app/src/main/res/drawable/green.png differ diff --git a/Code/Android/projectFirst/app/src/main/res/drawable/ic_launcher_background.xml b/Code/Android/projectFirst/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..07d5da9 --- /dev/null +++ b/Code/Android/projectFirst/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Code/Android/projectFirst/app/src/main/res/drawable/password_icon.png b/Code/Android/projectFirst/app/src/main/res/drawable/password_icon.png new file mode 100644 index 0000000..a8888e3 Binary files /dev/null and b/Code/Android/projectFirst/app/src/main/res/drawable/password_icon.png differ diff --git a/Code/Android/projectFirst/app/src/main/res/drawable/red.png b/Code/Android/projectFirst/app/src/main/res/drawable/red.png new file mode 100644 index 0000000..d5acc32 Binary files /dev/null and b/Code/Android/projectFirst/app/src/main/res/drawable/red.png differ diff --git a/Code/Android/projectFirst/app/src/main/res/drawable/user_name_icon.png b/Code/Android/projectFirst/app/src/main/res/drawable/user_name_icon.png new file mode 100644 index 0000000..e8f9ce6 Binary files /dev/null and b/Code/Android/projectFirst/app/src/main/res/drawable/user_name_icon.png differ diff --git a/Code/Android/projectFirst/app/src/main/res/layout/activity_login.xml b/Code/Android/projectFirst/app/src/main/res/layout/activity_login.xml new file mode 100644 index 0000000..4a4e987 --- /dev/null +++ b/Code/Android/projectFirst/app/src/main/res/layout/activity_login.xml @@ -0,0 +1,100 @@ + + + + + + + + + + + + + + + + + +