diff --git a/app/.gitignore b/app/.gitignore
new file mode 100644
index 0000000..aa724b7
--- /dev/null
+++ b/app/.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/app/.idea/.gitignore b/app/.idea/.gitignore
new file mode 100644
index 0000000..359bb53
--- /dev/null
+++ b/app/.idea/.gitignore
@@ -0,0 +1,3 @@
+# 默认忽略的文件
+/shelf/
+/workspace.xml
diff --git a/app/.idea/.name b/app/.idea/.name
new file mode 100644
index 0000000..0469830
--- /dev/null
+++ b/app/.idea/.name
@@ -0,0 +1 @@
+code
\ No newline at end of file
diff --git a/app/.idea/codeStyles/Project.xml b/app/.idea/codeStyles/Project.xml
new file mode 100644
index 0000000..681f41a
--- /dev/null
+++ b/app/.idea/codeStyles/Project.xml
@@ -0,0 +1,116 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ 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/app/.idea/compiler.xml b/app/.idea/compiler.xml
new file mode 100644
index 0000000..b589d56
--- /dev/null
+++ b/app/.idea/compiler.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/.idea/deploymentTargetDropDown.xml b/app/.idea/deploymentTargetDropDown.xml
new file mode 100644
index 0000000..0c0c338
--- /dev/null
+++ b/app/.idea/deploymentTargetDropDown.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/.idea/gradle.xml b/app/.idea/gradle.xml
new file mode 100644
index 0000000..0897082
--- /dev/null
+++ b/app/.idea/gradle.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/.idea/migrations.xml b/app/.idea/migrations.xml
new file mode 100644
index 0000000..f8051a6
--- /dev/null
+++ b/app/.idea/migrations.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/.idea/misc.xml b/app/.idea/misc.xml
new file mode 100644
index 0000000..0f86676
--- /dev/null
+++ b/app/.idea/misc.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/.idea/sonarlint/issuestore/0/5/05efc8b1657769a27696d478ded1e95f38737233 b/app/.idea/sonarlint/issuestore/0/5/05efc8b1657769a27696d478ded1e95f38737233
new file mode 100644
index 0000000..e69de29
diff --git a/app/.idea/sonarlint/issuestore/0/7/0712df971a99ac4d2fccb8e0fb19f377f3374cca b/app/.idea/sonarlint/issuestore/0/7/0712df971a99ac4d2fccb8e0fb19f377f3374cca
new file mode 100644
index 0000000..e69de29
diff --git a/app/.idea/sonarlint/issuestore/1/d/1dd5236d42b189b5ada41088c8eb5e454a5c6ea3 b/app/.idea/sonarlint/issuestore/1/d/1dd5236d42b189b5ada41088c8eb5e454a5c6ea3
new file mode 100644
index 0000000..40eead5
--- /dev/null
+++ b/app/.idea/sonarlint/issuestore/1/d/1dd5236d42b189b5ada41088c8eb5e454a5c6ea3
@@ -0,0 +1,15 @@
+
+
+java:S1192h"FDefine a constant instead of duplicating this literal "ansen" 3 times.(J$3766fed1-d9d0-45ba-9ff8-b5cae697bff5
+i
+java:S1604A"(Make this anonymous inner class a lambda(ډJ$9b2d07a2-23d5-4a02-b138-ad7f5a30cd84
+
+java:S1450 "VRemove the "webView" field and declare it as a local variable in the relevant methods.( J$ff53e3c4-67ba-4014-863c-7ce0f217b3c9
+{
+java:S1161*":Add the "@Override" annotation above this method signature(J$faad1e2c-65c8-42ff-b0c9-10ce70ecf5ee
+v java:S1258"""TMake rootView a static final constant or non-public and provide accessors if needed.(ʥJ$4369ed43-185f-4de4-9b27-71e0e6dd86f3
+
+java:S1104?"PMake user a static final constant or non-public and provide accessors if needed.(J$4b3cc300-d869-467c-ba7c-c8abacd9e7f1
+
+java:S1104@"PMake exit a static final constant or non-public and provide accessors if needed.(oJ$3e1d0bbe-cc18-41cd-964f-3aa19f610207
+
+java:S1450"VRemove the "inflate" field and declare it as a local variable in the relevant methods.(J$cb049d3b-5b2d-4d1a-b3a6-bc23e1366597
+
+java:S1450"YRemove the "viewHolder" field and declare it as a local variable in the relevant methods.(J$e6b1d344-3c08-4c8c-b180-4260309d48a7
+w java:S125("
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/app/src/main/java/com/example/code/App.java b/app/app/src/main/java/com/example/code/App.java
new file mode 100644
index 0000000..929ba0d
--- /dev/null
+++ b/app/app/src/main/java/com/example/code/App.java
@@ -0,0 +1,35 @@
+package com.example.code;
+
+import android.app.Application;
+import android.content.SharedPreferences;
+
+import com.example.code.bien.User;
+import com.google.gson.Gson;
+
+import java.util.List;
+
+public class App extends Application {
+
+// public static String URL = "http://192.168.1.4:8026/"; //这个是要修改ip
+ // public static String URL = "http://10.11.181.239:8026/"; //这个是要修改ip
+ public static String URL = "http://10.8.39.108:8026/";
+ public static String HOST = URL + "myproject/app";
+ public static boolean isLogin = false;
+ public static SharedPreferences sp;
+ public static Gson gson;
+ public static SharedPreferences.Editor sp_edit;
+ public static List userList;
+ public static User user;
+
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ gson = new Gson();
+ sp = getSharedPreferences("sd", MODE_PRIVATE);
+ sp_edit = sp.edit();
+ sp_edit.putInt("voitId", 0).commit();
+ }
+
+
+}
diff --git a/app/app/src/main/java/com/example/code/LoginActivity.java b/app/app/src/main/java/com/example/code/LoginActivity.java
new file mode 100644
index 0000000..a82a19e
--- /dev/null
+++ b/app/app/src/main/java/com/example/code/LoginActivity.java
@@ -0,0 +1,148 @@
+package com.example.code;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Looper;
+import android.text.TextUtils;
+import android.view.View;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.Toast;
+
+import androidx.annotation.Nullable;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.example.code.bien.User;
+import com.example.code.http.HttpUtlis;
+import com.example.code.http.OnResponseListner;
+import com.example.vote.R;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 登陆界面
+ */
+public class LoginActivity extends Activity implements View.OnClickListener {
+
+ private EditText username; //用户名输入框
+ private EditText password; //密码输入框
+ private Button login; //登陆按钮
+ private Button register; //注册按钮
+
+ //页面创建
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_login);
+ initView();
+
+ }
+
+ //页面内容初始化方法
+ private void initView() {
+ username = (EditText) findViewById(R.id.username);
+ password = (EditText) findViewById(R.id.password);
+ login = (Button) findViewById(R.id.login);
+ register = (Button) findViewById(R.id.register);
+
+ login.setOnClickListener(this);
+ register.setOnClickListener(this);
+ }
+
+ //按钮点击事件绑定
+ @Override
+ public void onClick(View v) {
+ if (v.getId() == R.id.login){
+ submit();
+ }
+ if (v.getId() == R.id.register){
+ startActivity(new Intent(getApplicationContext(), RegisterActivity.class));
+ }
+// switch (v.getId()) {
+// case R.id.login:
+//
+// break;
+// case R.id.register:
+// //跳转注册页面
+//
+// break;
+// }
+ }
+
+ //登陆请求提交
+ private void submit() {
+ // validate
+ String usernameString = username.getText().toString().trim();
+ //判断用户名是否为空 为空则进行提示 并终止操作
+ if (TextUtils.isEmpty(usernameString)) {
+ Toast.makeText(this, "用户名错误", Toast.LENGTH_SHORT).show();
+ return;
+ }
+ //判断密码是否为空
+ String passwordString = password.getText().toString().trim();
+ if (TextUtils.isEmpty(passwordString)) {
+ Toast.makeText(this, "密码错误", Toast.LENGTH_SHORT).show();
+ return;
+ }
+
+ //使用多线程执行提交操作
+ Thread thread = new Thread(new Runnable() {
+ @Override
+ public void run() {
+ //在这填上您原来的代码即可
+ loginSubmit();
+ finish();
+ }
+ });
+ thread.start();
+
+ }
+
+
+ public void loginSubmit() {
+ //登陆请求地址
+ String url = App.HOST + "/loginSubmit";
+ Map map = new HashMap<>();
+ map.put("username", username.getText().toString());
+ map.put("password", password.getText().toString());
+ //执行http远程登陆请求
+ HttpUtlis.postRequest(url, map, new OnResponseListner() {
+ //http请求成功执行
+ @Override
+ public void onSucess(String response) {
+ //执行登陆请求成功 解析返回json内容
+ System.out.println("response = " + response);
+ JSONObject object = JSON.parseObject(response);
+ Integer status = object.getInteger("status");
+ String msg = object.getString("msg");
+ String data = object.getString("data");
+ if (status == 200) {
+ /*Looper.prepare();
+ Toast.makeText(getApplicationContext(), "登录成功", Toast.LENGTH_SHORT).show();
+ Looper.loop();*/
+ System.out.println("登录成功");
+ //更新界面
+ User user = JSON.parseObject(data, User.class);
+ App.user = user;
+ startActivity(new Intent(getApplicationContext(), MainActivity.class));
+ finish();
+ } else {
+ Looper.prepare();
+ Toast.makeText(getApplicationContext(), "登录失败", Toast.LENGTH_SHORT).show();
+ Looper.loop();
+ System.out.println("登录失败");
+ }
+ }
+
+ //http请求出错执行方法
+ @Override
+ public void onError(String error) {
+ System.out.println("error = " + error);
+ }
+ });
+ }
+
+
+}
diff --git a/app/app/src/main/java/com/example/code/MainActivity.java b/app/app/src/main/java/com/example/code/MainActivity.java
new file mode 100644
index 0000000..845be56
--- /dev/null
+++ b/app/app/src/main/java/com/example/code/MainActivity.java
@@ -0,0 +1,34 @@
+package com.example.code;
+
+import android.annotation.SuppressLint;
+import android.os.Bundle;
+import com.example.vote.R;
+import com.google.android.material.bottomnavigation.BottomNavigationView;
+
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.navigation.NavController;
+import androidx.navigation.Navigation;
+import androidx.navigation.ui.AppBarConfiguration;
+import androidx.navigation.ui.NavigationUI;
+
+public class MainActivity extends AppCompatActivity {
+
+ @SuppressLint("WrongConstant")
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+ BottomNavigationView navView = findViewById(R.id.nav_view);
+ // Passing each menu ID as a set of Ids because each
+ // menu should be considered as top level destinations.
+ navView.setLabelVisibilityMode(BottomNavigationView.LAYOUT_MODE_OPTICAL_BOUNDS);
+ AppBarConfiguration appBarConfiguration = new AppBarConfiguration.Builder(
+ R.id.navigation_home, R.id.navigation_sc, R.id.navigation_wd)
+ .build();
+ NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
+ NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);
+ NavigationUI.setupWithNavController(navView, navController);
+
+ }
+
+}
\ No newline at end of file
diff --git a/app/app/src/main/java/com/example/code/RegisterActivity.java b/app/app/src/main/java/com/example/code/RegisterActivity.java
new file mode 100644
index 0000000..82eb49c
--- /dev/null
+++ b/app/app/src/main/java/com/example/code/RegisterActivity.java
@@ -0,0 +1,162 @@
+package com.example.code;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Looper;
+import android.text.TextUtils;
+import android.view.View;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.Toast;
+
+import androidx.annotation.Nullable;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.example.code.http.HttpUtlis;
+import com.example.code.http.OnResponseListner;
+
+import java.util.HashMap;
+import java.util.Map;
+import com.example.vote.R;
+/**
+ * 注册界面
+ */
+public class RegisterActivity extends Activity implements View.OnClickListener {
+
+ private EditText username; //注册用户名框
+ private EditText password;//注册密码框
+ private EditText tlep; //注册电话框
+ private EditText intro; //简介
+ private EditText idcard; //身份证
+ private Button login;//登陆按钮
+ private Button register;//注册按钮
+
+
+ //执行注册提交方法
+ public void registerSubmit() {
+ //注册请求地址
+ String url = App.HOST + "/registerSubmit";
+ //使用map集合传递参数
+ Map map = new HashMap<>();
+ map.put("username", username.getText().toString());
+ map.put("password", password.getText().toString());
+ map.put("tlep", tlep.getText().toString());
+ map.put("intro", intro.getText().toString());
+ map.put("idcard", idcard.getText().toString());
+ //执行http注册请求
+ HttpUtlis.postRequest(url, map, new OnResponseListner() {
+ //http请求成功
+ @Override
+ public void onSucess(String response) {
+ System.out.println("response = " + response);
+ //解析返回的json内容
+ JSONObject object = JSON.parseObject(response);
+ Integer status = object.getInteger("status");
+ String msg = object.getString("msg");
+ //状态为200代表注册成功
+ if (status == 200) {
+ Looper.prepare();
+ Toast.makeText(getApplicationContext(), "注册成功", Toast.LENGTH_SHORT).show();
+ Looper.loop();
+ System.out.println("注册成功");
+ //更新界面
+ finish();
+
+ } else {
+ Looper.prepare();
+ Toast.makeText(getApplicationContext(), "注册失败", Toast.LENGTH_SHORT).show();
+ Looper.loop();
+ System.out.println("注册失败");
+ }
+ }
+
+ //http请求失败
+ @Override
+ public void onError(String error) {
+ System.out.println("error = " + error);
+ }
+ });
+ }
+
+ //界面创建
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_register);
+ initView();
+
+
+ }
+
+ //界面初始化
+ private void initView() {
+ username = (EditText) findViewById(R.id.username);
+ password = (EditText) findViewById(R.id.password);
+ tlep = (EditText) findViewById(R.id.tlep);
+ intro = (EditText) findViewById(R.id.intro);
+ idcard = (EditText) findViewById(R.id.idcard);
+ login = (Button) findViewById(R.id.login);
+ register = (Button) findViewById(R.id.register);
+
+ login.setOnClickListener(this);
+ register.setOnClickListener(this);
+ }
+
+ //按钮点击事件绑定
+ @Override
+ public void onClick(View v) {
+
+ if (v.getId() == R.id.login){
+ submit();
+ }
+ if (v.getId() == R.id.register){
+ finish();
+ }
+
+// switch (v.getId()) {
+// case R.id.login:
+// submit();
+// break;
+// case R.id.register:
+// finish();
+// break;
+// }
+ }
+
+ //点击注册按钮提交执行方法
+ private void submit() {
+ // validate
+ String usernameString = username.getText().toString().trim();
+ if (TextUtils.isEmpty(usernameString)) {
+ Toast.makeText(this, "用户名", Toast.LENGTH_SHORT).show();
+ return;
+ }
+
+ String passwordString = password.getText().toString().trim();
+ if (TextUtils.isEmpty(passwordString)) {
+ Toast.makeText(this, "密码", Toast.LENGTH_SHORT).show();
+ return;
+ }
+
+ String tlepString = tlep.getText().toString().trim();
+ if (TextUtils.isEmpty(tlepString)) {
+ Toast.makeText(this, "手机号", Toast.LENGTH_SHORT).show();
+ return;
+ }
+
+
+ //使用多线程进行http请求 防止界面卡死
+ Thread thread = new Thread(new Runnable() {
+ @Override
+ public void run() {
+ //调用注册提交http请求
+ registerSubmit();
+ }
+ });
+ thread.start();
+
+
+ }
+}
diff --git a/app/app/src/main/java/com/example/code/bien/GlobalResult.java b/app/app/src/main/java/com/example/code/bien/GlobalResult.java
new file mode 100644
index 0000000..b1f1870
--- /dev/null
+++ b/app/app/src/main/java/com/example/code/bien/GlobalResult.java
@@ -0,0 +1,107 @@
+package com.example.code.bien;
+
+/**
+ * @Description: 自定义响应数据结构
+ * 这个类是提供给门户,ios,安卓,微信商城用的
+ * 门户接受此类数据后需要使用本类的方法转换成对于的数据类型格式(类,或者list)
+ * 其他自行处理
+ * 200:表示成功
+ * 500:表示错误,错误信息在msg字段中
+ * 501:bean验证错误,不管多少个错误都以map形式返回
+ * 502:拦截器拦截到用户token出错
+ * 555:异常抛出信息
+ */
+public class GlobalResult {
+
+ // 响应业务状态
+ private Integer status;
+
+ // 响应消息
+ private String msg;
+
+ // 响应中的数据
+ private Object data;
+
+ private String ok; // 不使用
+
+ public static GlobalResult build(Integer status, String msg, Object data) {
+ return new GlobalResult(status, msg, data);
+ }
+
+ public static GlobalResult ok(Object data) {
+ return new GlobalResult(data);
+ }
+
+ public static GlobalResult ok() {
+ return new GlobalResult(null);
+ }
+
+ public static GlobalResult errorMsg(String msg) {
+ return new GlobalResult(500, msg, null);
+ }
+
+ public static GlobalResult errorMap(Object data) {
+ return new GlobalResult(501, "error", data);
+ }
+
+ public static GlobalResult errorTokenMsg(String msg) {
+ return new GlobalResult(502, msg, null);
+ }
+
+ public static GlobalResult errorException(String msg) {
+ return new GlobalResult(555, msg, null);
+ }
+
+ public GlobalResult() {
+
+ }
+
+ public GlobalResult(Integer status, String msg, Object data) {
+ this.status = status;
+ this.msg = msg;
+ this.data = data;
+ }
+
+ public GlobalResult(Object data) {
+ this.status = 200;
+ this.msg = "OK";
+ this.data = data;
+ }
+
+ public Boolean isOK() {
+ return this.status == 200;
+ }
+
+ public Integer getStatus() {
+ return status;
+ }
+
+ public void setStatus(Integer status) {
+ this.status = status;
+ }
+
+ public String getMsg() {
+ return msg;
+ }
+
+ public void setMsg(String msg) {
+ this.msg = msg;
+ }
+
+ public Object getData() {
+ return data;
+ }
+
+ public void setData(Object data) {
+ this.data = data;
+ }
+
+ public String getOk() {
+ return ok;
+ }
+
+ public void setOk(String ok) {
+ this.ok = ok;
+ }
+
+}
\ No newline at end of file
diff --git a/app/app/src/main/java/com/example/code/bien/User.java b/app/app/src/main/java/com/example/code/bien/User.java
new file mode 100644
index 0000000..e0285cf
--- /dev/null
+++ b/app/app/src/main/java/com/example/code/bien/User.java
@@ -0,0 +1,128 @@
+package com.example.code.bien;
+
+import java.io.Serializable;
+
+public class User implements Serializable {
+ /**
+ * ID
+ */
+ private Integer id;
+ /**
+ * 姓名
+ */
+ private String name;
+ /**
+ * 电话
+ */
+ private String phone;
+ /**
+ * 头像
+ */
+ private String picurl;
+ /**
+ * 邮箱
+ */
+ private String email;
+ /**
+ * 角色
+ */
+ private String role;
+ /**
+ * 性别
+ */
+ private String sex;
+ /**
+ * 密码
+ */
+ private String password;
+ /**
+ * 备注
+ */
+ private String intro;
+ /**
+ * 金额
+ */
+ private Integer money;
+
+ public Integer getMoney() {
+ return money;
+ }
+
+ public void setMoney(Integer money) {
+ this.money = money;
+ }
+
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getPhone() {
+ return phone;
+ }
+
+ public void setPhone(String phone) {
+ this.phone = phone;
+ }
+
+ public String getPicurl() {
+ return picurl;
+ }
+
+ public void setPicurl(String picurl) {
+ this.picurl = picurl;
+ }
+
+ public String getEmail() {
+ return email;
+ }
+
+ public void setEmail(String email) {
+ this.email = email;
+ }
+
+ public String getRole() {
+ return role;
+ }
+
+ public void setRole(String role) {
+ this.role = role;
+ }
+
+ public String getSex() {
+ return sex;
+ }
+
+ public void setSex(String sex) {
+ this.sex = sex;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ public String getIntro() {
+ return intro;
+ }
+
+ public void setIntro(String intro) {
+ this.intro = intro;
+ }
+
+
+}
diff --git a/app/app/src/main/java/com/example/code/http/HttpUtlis.java b/app/app/src/main/java/com/example/code/http/HttpUtlis.java
new file mode 100644
index 0000000..851217f
--- /dev/null
+++ b/app/app/src/main/java/com/example/code/http/HttpUtlis.java
@@ -0,0 +1,107 @@
+package com.example.code.http;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.Map;
+
+public class HttpUtlis {
+ /**
+ *get请求封装
+ */
+ public static void getRequest(String url, Map params, OnResponseListner listner) {
+ String encode = "utf-8";
+ System.out.println( "请求地址 url = " + url);
+ System.out.println(" 发送参数 params = " + params);
+ StringBuffer sb = new StringBuffer(url);
+ sb.append("?");
+ if (params!=null && !params.isEmpty()){
+ for (Map.Entry entry:params.entrySet()) { //增强for遍历循环添加拼接请求内容
+ sb.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
+ }
+ sb.deleteCharAt(sb.length()-1);
+ if (listner!=null) {
+ try {
+ System.out.println(" 请求地址 = " + sb.toString());
+ URL path = new URL(sb.toString());
+ if (path!=null) {
+ HttpURLConnection con = (HttpURLConnection) path.openConnection();
+ con.setRequestMethod("GET"); //设置请求方式
+ con.setConnectTimeout(3000); //链接超时3秒
+ con.setDoOutput(true);
+ con.setDoInput(true);
+ OutputStream os = con.getOutputStream();
+ os.write(sb.toString().getBytes(encode));
+ os.close();
+ if (con.getResponseCode() == 200) { //应答码200表示请求成功
+ onSucessResopond(encode, listner, con);
+ }
+ }
+ } catch (Exception error) {
+ error.printStackTrace();
+ onError(listner, error);
+ }
+ }
+ }
+ }
+
+ /**
+ * POST请求
+ */
+ public static void postRequest(String url,Map params,OnResponseListner listner){
+ System.out.println( "请求地址 url = " + url);
+ System.out.println(" 发送参数 params = " + params);
+ String encode = "utf-8";
+ StringBuffer sb = new StringBuffer();
+ if (params!=null && !params.isEmpty()){
+ for (Map.Entry entry: params.entrySet()) {
+ sb.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
+ }
+ sb.deleteCharAt(sb.length()-1);
+ }
+ if (listner!=null) {
+ try {
+ URL path = new URL(url);
+ if (path!=null){
+ HttpURLConnection con = (HttpURLConnection) path.openConnection();
+ con.setRequestMethod("POST"); //设置请求方法POST
+ con.setConnectTimeout(3000);
+ con.setDoOutput(true);
+ con.setDoInput(true);
+ byte[] bytes = sb.toString().getBytes();
+ OutputStream outputStream = con.getOutputStream();
+ outputStream.write(bytes);
+ outputStream.close();
+ if (con.getResponseCode()==200){
+ onSucessResopond(encode, listner, con);
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ onError(listner, e);
+ }
+ }
+ }
+
+ private static void onError(OnResponseListner listner,Exception onError) {
+ listner.onError(onError.toString());
+ }
+
+ private static void onSucessResopond(String encode, OnResponseListner listner, HttpURLConnection con) throws IOException {
+ InputStream inputStream = con.getInputStream();
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();//创建内存输出流
+ int len = 0;
+ byte[] bytes = new byte[1024];
+ if (inputStream != null) {
+ while ((len = inputStream.read(bytes)) != -1) {
+ baos.write(bytes, 0, len);
+ }
+ String str = new String(baos.toByteArray(), encode);
+ listner.onSucess(str);
+ }
+ }
+
+}
diff --git a/app/app/src/main/java/com/example/code/http/OnResponseListner.java b/app/app/src/main/java/com/example/code/http/OnResponseListner.java
new file mode 100644
index 0000000..73bf7fc
--- /dev/null
+++ b/app/app/src/main/java/com/example/code/http/OnResponseListner.java
@@ -0,0 +1,6 @@
+package com.example.code.http;
+
+public interface OnResponseListner {
+ void onSucess(String response);
+ void onError(String error);
+}
diff --git a/app/app/src/main/java/com/example/code/ui/home/HomeFragment.java b/app/app/src/main/java/com/example/code/ui/home/HomeFragment.java
new file mode 100644
index 0000000..92ffeff
--- /dev/null
+++ b/app/app/src/main/java/com/example/code/ui/home/HomeFragment.java
@@ -0,0 +1,163 @@
+package com.example.code.ui.home;
+
+import android.app.AlertDialog;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.net.Uri;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.webkit.DownloadListener;
+import android.webkit.JavascriptInterface;
+import android.webkit.JsResult;
+import android.webkit.WebChromeClient;
+import android.webkit.WebSettings;
+import android.webkit.WebView;
+import android.webkit.WebViewClient;
+import android.widget.Button;
+import android.widget.ProgressBar;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.fragment.app.Fragment;
+import androidx.lifecycle.ViewModelProvider;
+
+import com.example.code.App;
+import com.example.code.LoginActivity;
+
+import com.example.code.ui.wd.WdFragment;
+import com.example.vote.R;
+
+
+public class HomeFragment extends Fragment {
+ private WebView webView;
+ private ProgressBar progressBar;
+
+ private void downloadByBrowser(String url) {
+ Intent intent = new Intent(Intent.ACTION_VIEW);
+ intent.addCategory(Intent.CATEGORY_BROWSABLE);
+ intent.setData(Uri.parse(url));
+ startActivity(intent);
+ }
+
+ public View onCreateView(@NonNull LayoutInflater inflater,
+ ViewGroup container, Bundle savedInstanceState) {
+ View view = View.inflate(getContext(), R.layout.wd_fragment, null);
+
+ progressBar = (ProgressBar) view.findViewById(R.id.progressbar);//进度条
+
+ webView = (WebView) view.findViewById(R.id.webview);
+// webView.loadUrl("file:///android_asset/test.html");//加载asset文件夹下html
+
+ //String url = App.URL + "/myproject/AppIndex?uid=" + App.user.getId() + "&page=productList";
+ String url = App.URL + "/myproject/AppIndex?uid=" + App.user.getId() + "&page=phone";
+ webView.loadUrl(url);//加载url
+
+ //使用webview显示html代码
+// webView.loadDataWithBaseURL(null," 欢迎您 " +
+// "使用webview显示 html代码
", "text/html" , "utf-8", null);
+
+ webView.addJavascriptInterface(this, "android");//添加js监听 这样html就能调用客户端
+ webView.setWebChromeClient(webChromeClient);
+ webView.setWebViewClient(webViewClient);
+
+ WebSettings webSettings = webView.getSettings();
+ webSettings.setJavaScriptEnabled(true);//允许使用js
+
+ webView.setDownloadListener(new DownloadListener() {
+ @Override
+ public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimeType, long contentLength) {
+ downloadByBrowser(url);
+ }
+
+ });
+
+ /**
+ * LOAD_CACHE_ONLY: 不使用网络,只读取本地缓存数据
+ * LOAD_DEFAULT: (默认)根据cache-control决定是否从网络上取数据。
+ * LOAD_NO_CACHE: 不使用缓存,只从网络获取数据.
+ * LOAD_CACHE_ELSE_NETWORK,只要本地有,无论是否过期,或者no-cache,都使用缓存中的数据。
+ */
+ webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);//不使用缓存,只从网络获取数据.
+
+ //支持屏幕缩放
+ webSettings.setSupportZoom(true);
+ webSettings.setBuiltInZoomControls(true);
+
+ //不显示webview缩放按钮
+// webSettings.setDisplayZoomControls(false);
+ return view;
+ }
+
+ //WebViewClient主要帮助WebView处理各种通知、请求事件
+ private WebViewClient webViewClient = new WebViewClient() {
+ @Override
+ public void onPageFinished(WebView view, String url) {//页面加载完成
+ progressBar.setVisibility(View.GONE);
+ }
+
+ @Override
+ public void onPageStarted(WebView view, String url, Bitmap favicon) {//页面开始加载
+ progressBar.setVisibility(View.VISIBLE);
+ }
+
+ @Override
+ public boolean shouldOverrideUrlLoading(WebView view, String url) {
+ Log.i("ansen", "拦截url:" + url);
+ if (url.equals("http://www.google.com/")) {
+ Toast.makeText(getContext(), "国内不能访问google,拦截该url", Toast.LENGTH_LONG).show();
+ return true;//表示我已经处理过了
+ }
+ return super.shouldOverrideUrlLoading(view, url);
+ }
+
+ };
+
+ //WebChromeClient主要辅助WebView处理Javascript的对话框、网站图标、网站title、加载进度等
+ private WebChromeClient webChromeClient = new WebChromeClient() {
+ //不支持js的alert弹窗,需要自己监听然后通过dialog弹窗
+ @Override
+ public boolean onJsAlert(WebView webView, String url, String message, JsResult result) {
+ AlertDialog.Builder localBuilder = new AlertDialog.Builder(webView.getContext());
+ localBuilder.setMessage(message).setPositiveButton("确定", null);
+ localBuilder.setCancelable(false);
+ localBuilder.create().show();
+
+ //注意:
+ //必须要这一句代码:result.confirm()表示:
+ //处理结果为确定状态同时唤醒WebCore线程
+ //否则不能继续点击按钮
+ result.confirm();
+ return true;
+ }
+
+ //获取网页标题
+ @Override
+ public void onReceivedTitle(WebView view, String title) {
+ super.onReceivedTitle(view, title);
+ Log.i("ansen", "网页标题:" + title);
+ }
+
+ //加载进度回调
+ @Override
+ public void onProgressChanged(WebView view, int newProgress) {
+ progressBar.setProgress(newProgress);
+ }
+ };
+
+
+ /**
+ * JS调用android的方法
+ *
+ * @param str
+ * @return
+ */
+ @JavascriptInterface //仍然必不可少
+ public void getClient(String str) {
+ Log.i("ansen", "html调用客户端:" + str);
+ }
+}
\ No newline at end of file
diff --git a/app/app/src/main/java/com/example/code/ui/out/OutFragment.java b/app/app/src/main/java/com/example/code/ui/out/OutFragment.java
new file mode 100644
index 0000000..bd5d875
--- /dev/null
+++ b/app/app/src/main/java/com/example/code/ui/out/OutFragment.java
@@ -0,0 +1,73 @@
+package com.example.code.ui.out;
+
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.fragment.app.Fragment;
+
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.TextView;
+
+import com.example.code.App;
+import com.example.code.LoginActivity;
+
+import com.example.code.ui.wd.WdFragment;
+import com.example.vote.R;
+
+
+public class OutFragment extends Fragment {
+ private View inflate;
+ private ViewHolder viewHolder;
+
+ public static OutFragment newInstance() {
+ return new OutFragment();
+ }
+
+ @Override
+ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
+ @Nullable Bundle savedInstanceState) {
+
+ inflate = inflater.inflate(R.layout.out_fragment, container, false);
+ viewHolder = new ViewHolder(inflate);
+
+ //viewHolder.user.setText("用户名:");
+ viewHolder.exit.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ App.isLogin = false;
+ App.user = null;
+ startActivity(new Intent(getContext(), LoginActivity.class));
+ getActivity().finish();
+ }
+ });
+
+
+ return inflate;
+ }
+
+ @Override
+ public void onActivityCreated(@Nullable Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+ // TODO: Use the ViewModel
+ }
+
+ class ViewHolder {
+ public View rootView;
+ public TextView user;
+ public Button exit;
+
+ public ViewHolder(View rootView) {
+ this.rootView = rootView;
+ this.user = (TextView) rootView.findViewById(R.id.user);
+ this.exit = (Button) rootView.findViewById(R.id.exit);
+ }
+
+ }
+}
diff --git a/app/app/src/main/java/com/example/code/ui/sc/ScFragment.java b/app/app/src/main/java/com/example/code/ui/sc/ScFragment.java
new file mode 100644
index 0000000..2577262
--- /dev/null
+++ b/app/app/src/main/java/com/example/code/ui/sc/ScFragment.java
@@ -0,0 +1,167 @@
+package com.example.code.ui.sc;
+
+import android.app.AlertDialog;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Looper;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.webkit.DownloadListener;
+import android.webkit.JavascriptInterface;
+import android.webkit.JsResult;
+import android.webkit.WebChromeClient;
+import android.webkit.WebSettings;
+import android.webkit.WebView;
+import android.webkit.WebViewClient;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.ProgressBar;
+import android.widget.Toast;
+
+import androidx.annotation.NonNull;
+import androidx.fragment.app.Fragment;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.example.code.App;
+
+import com.example.code.bien.User;
+import com.example.code.http.HttpUtlis;
+import com.example.code.http.OnResponseListner;
+import com.example.vote.R;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class ScFragment extends Fragment {
+ private WebView webView;
+ private ProgressBar progressBar;
+
+ private void downloadByBrowser(String url) {
+ Intent intent = new Intent(Intent.ACTION_VIEW);
+ intent.addCategory(Intent.CATEGORY_BROWSABLE);
+ intent.setData(Uri.parse(url));
+ startActivity(intent);
+ }
+
+ public View onCreateView(@NonNull LayoutInflater inflater,
+ ViewGroup container, Bundle savedInstanceState) {
+ View view = View.inflate(getContext(), R.layout.wd_fragment, null);
+
+ progressBar = (ProgressBar) view.findViewById(R.id.progressbar);//进度条
+
+ webView = (WebView) view.findViewById(R.id.webview);
+// webView.loadUrl("file:///android_asset/test.html");//加载asset文件夹下html
+
+ String url = App.URL + "/myproject/AppIndex?uid=" + App.user.getId() + "&page=infoList";
+ webView.loadUrl(url);//加载url
+
+ //使用webview显示html代码
+// webView.loadDataWithBaseURL(null," 欢迎您 " +
+// "使用webview显示 html代码
", "text/html" , "utf-8", null);
+
+ webView.addJavascriptInterface(this, "android");//添加js监听 这样html就能调用客户端
+ webView.setWebChromeClient(webChromeClient);
+ webView.setWebViewClient(webViewClient);
+
+ WebSettings webSettings = webView.getSettings();
+ webSettings.setJavaScriptEnabled(true);//允许使用js
+
+ webView.setDownloadListener(new DownloadListener() {
+ @Override
+ public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimeType, long contentLength) {
+ downloadByBrowser(url);
+ }
+
+ });
+
+ /**
+ * LOAD_CACHE_ONLY: 不使用网络,只读取本地缓存数据
+ * LOAD_DEFAULT: (默认)根据cache-control决定是否从网络上取数据。
+ * LOAD_NO_CACHE: 不使用缓存,只从网络获取数据.
+ * LOAD_CACHE_ELSE_NETWORK,只要本地有,无论是否过期,或者no-cache,都使用缓存中的数据。
+ */
+ webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);//不使用缓存,只从网络获取数据.
+
+ //支持屏幕缩放
+ webSettings.setSupportZoom(true);
+ webSettings.setBuiltInZoomControls(true);
+
+ //不显示webview缩放按钮
+// webSettings.setDisplayZoomControls(false);
+ return view;
+ }
+
+ //WebViewClient主要帮助WebView处理各种通知、请求事件
+ private WebViewClient webViewClient = new WebViewClient() {
+ @Override
+ public void onPageFinished(WebView view, String url) {//页面加载完成
+ progressBar.setVisibility(View.GONE);
+ }
+
+ @Override
+ public void onPageStarted(WebView view, String url, Bitmap favicon) {//页面开始加载
+ progressBar.setVisibility(View.VISIBLE);
+ }
+
+ @Override
+ public boolean shouldOverrideUrlLoading(WebView view, String url) {
+ Log.i("ansen", "拦截url:" + url);
+ if (url.equals("http://www.google.com/")) {
+ Toast.makeText(getContext(), "国内不能访问google,拦截该url", Toast.LENGTH_LONG).show();
+ return true;//表示我已经处理过了
+ }
+ return super.shouldOverrideUrlLoading(view, url);
+ }
+
+ };
+
+ //WebChromeClient主要辅助WebView处理Javascript的对话框、网站图标、网站title、加载进度等
+ private WebChromeClient webChromeClient = new WebChromeClient() {
+ //不支持js的alert弹窗,需要自己监听然后通过dialog弹窗
+ @Override
+ public boolean onJsAlert(WebView webView, String url, String message, JsResult result) {
+ AlertDialog.Builder localBuilder = new AlertDialog.Builder(webView.getContext());
+ localBuilder.setMessage(message).setPositiveButton("确定", null);
+ localBuilder.setCancelable(false);
+ localBuilder.create().show();
+
+ //注意:
+ //必须要这一句代码:result.confirm()表示:
+ //处理结果为确定状态同时唤醒WebCore线程
+ //否则不能继续点击按钮
+ result.confirm();
+ return true;
+ }
+
+ //获取网页标题
+ @Override
+ public void onReceivedTitle(WebView view, String title) {
+ super.onReceivedTitle(view, title);
+ Log.i("ansen", "网页标题:" + title);
+ }
+
+ //加载进度回调
+ @Override
+ public void onProgressChanged(WebView view, int newProgress) {
+ progressBar.setProgress(newProgress);
+ }
+ };
+
+
+ /**
+ * JS调用android的方法
+ *
+ * @param str
+ * @return
+ */
+ @JavascriptInterface //仍然必不可少
+ public void getClient(String str) {
+ Log.i("ansen", "html调用客户端:" + str);
+ }
+}
diff --git a/app/app/src/main/java/com/example/code/ui/wd/WdFragment.java b/app/app/src/main/java/com/example/code/ui/wd/WdFragment.java
new file mode 100644
index 0000000..09400d2
--- /dev/null
+++ b/app/app/src/main/java/com/example/code/ui/wd/WdFragment.java
@@ -0,0 +1,158 @@
+package com.example.code.ui.wd;
+
+import android.app.AlertDialog;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.net.Uri;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.webkit.DownloadListener;
+import android.webkit.JavascriptInterface;
+import android.webkit.JsResult;
+import android.webkit.WebChromeClient;
+import android.webkit.WebSettings;
+import android.webkit.WebView;
+import android.webkit.WebViewClient;
+import android.widget.ProgressBar;
+import android.widget.Toast;
+
+import androidx.annotation.NonNull;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.fragment.app.Fragment;
+
+import com.example.code.App;
+import com.example.code.MainActivity;
+import com.example.vote.R;
+
+public class WdFragment extends Fragment {
+ private WebView webView;
+ private ProgressBar progressBar;
+
+ private void downloadByBrowser(String url) {
+ Intent intent = new Intent(Intent.ACTION_VIEW);
+ intent.addCategory(Intent.CATEGORY_BROWSABLE);
+ intent.setData(Uri.parse(url));
+ startActivity(intent);
+ }
+
+ public View onCreateView(@NonNull LayoutInflater inflater,
+ ViewGroup container, Bundle savedInstanceState) {
+ View view = View.inflate(getContext(), R.layout.wd_fragment, null);
+
+ progressBar = (ProgressBar) view.findViewById(R.id.progressbar);//进度条
+
+ webView = (WebView) view.findViewById(R.id.webview);
+// webView.loadUrl("file:///android_asset/test.html");//加载asset文件夹下html
+
+ String url = App.URL + "/myproject/AppIndex?uid=" + App.user.getId() + "&page=index";
+ webView.loadUrl(url);//加载url
+
+ //使用webview显示html代码
+// webView.loadDataWithBaseURL(null," 欢迎您 " +
+// "使用webview显示 html代码
", "text/html" , "utf-8", null);
+
+ webView.addJavascriptInterface(this, "android");//添加js监听 这样html就能调用客户端
+ webView.setWebChromeClient(webChromeClient);
+ webView.setWebViewClient(webViewClient);
+
+ WebSettings webSettings = webView.getSettings();
+ webSettings.setJavaScriptEnabled(true);//允许使用js
+
+ webView.setDownloadListener(new DownloadListener() {
+ @Override
+ public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimeType, long contentLength) {
+ downloadByBrowser(url);
+ }
+
+ });
+
+ /**
+ * LOAD_CACHE_ONLY: 不使用网络,只读取本地缓存数据
+ * LOAD_DEFAULT: (默认)根据cache-control决定是否从网络上取数据。
+ * LOAD_NO_CACHE: 不使用缓存,只从网络获取数据.
+ * LOAD_CACHE_ELSE_NETWORK,只要本地有,无论是否过期,或者no-cache,都使用缓存中的数据。
+ */
+ webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);//不使用缓存,只从网络获取数据.
+
+ //支持屏幕缩放
+ webSettings.setSupportZoom(true);
+ webSettings.setBuiltInZoomControls(true);
+
+ //不显示webview缩放按钮
+// webSettings.setDisplayZoomControls(false);
+ return view;
+ }
+
+ //WebViewClient主要帮助WebView处理各种通知、请求事件
+ private WebViewClient webViewClient = new WebViewClient() {
+ @Override
+ public void onPageFinished(WebView view, String url) {//页面加载完成
+ progressBar.setVisibility(View.GONE);
+ }
+
+ @Override
+ public void onPageStarted(WebView view, String url, Bitmap favicon) {//页面开始加载
+ progressBar.setVisibility(View.VISIBLE);
+ }
+
+ @Override
+ public boolean shouldOverrideUrlLoading(WebView view, String url) {
+ Log.i("ansen", "拦截url:" + url);
+ if (url.equals("http://www.google.com/")) {
+ Toast.makeText(getContext(), "国内不能访问google,拦截该url", Toast.LENGTH_LONG).show();
+ return true;//表示我已经处理过了
+ }
+ return super.shouldOverrideUrlLoading(view, url);
+ }
+
+ };
+
+ //WebChromeClient主要辅助WebView处理Javascript的对话框、网站图标、网站title、加载进度等
+ private WebChromeClient webChromeClient = new WebChromeClient() {
+ //不支持js的alert弹窗,需要自己监听然后通过dialog弹窗
+ @Override
+ public boolean onJsAlert(WebView webView, String url, String message, JsResult result) {
+ AlertDialog.Builder localBuilder = new AlertDialog.Builder(webView.getContext());
+ localBuilder.setMessage(message).setPositiveButton("确定", null);
+ localBuilder.setCancelable(false);
+ localBuilder.create().show();
+
+ //注意:
+ //必须要这一句代码:result.confirm()表示:
+ //处理结果为确定状态同时唤醒WebCore线程
+ //否则不能继续点击按钮
+ result.confirm();
+ return true;
+ }
+
+ //获取网页标题
+ @Override
+ public void onReceivedTitle(WebView view, String title) {
+ super.onReceivedTitle(view, title);
+ Log.i("ansen", "网页标题:" + title);
+ }
+
+ //加载进度回调
+ @Override
+ public void onProgressChanged(WebView view, int newProgress) {
+ progressBar.setProgress(newProgress);
+ }
+ };
+
+
+ /**
+ * JS调用android的方法
+ *
+ * @param str
+ * @return
+ */
+ @JavascriptInterface //仍然必不可少
+ public void getClient(String str) {
+ Log.i("ansen", "html调用客户端:" + str);
+ }
+
+}
\ No newline at end of file
diff --git a/app/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/app/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
new file mode 100644
index 0000000..2b068d1
--- /dev/null
+++ b/app/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/app/src/main/res/drawable/bg_20dp_r.xml b/app/app/src/main/res/drawable/bg_20dp_r.xml
new file mode 100644
index 0000000..e221ce5
--- /dev/null
+++ b/app/app/src/main/res/drawable/bg_20dp_r.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/app/src/main/res/drawable/ic_baseline_fiber_manual_record_24.xml b/app/app/src/main/res/drawable/ic_baseline_fiber_manual_record_24.xml
new file mode 100644
index 0000000..feb56de
--- /dev/null
+++ b/app/app/src/main/res/drawable/ic_baseline_fiber_manual_record_24.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/app/app/src/main/res/drawable/ic_baseline_keyboard_arrow_left_24.xml b/app/app/src/main/res/drawable/ic_baseline_keyboard_arrow_left_24.xml
new file mode 100644
index 0000000..0f232d6
--- /dev/null
+++ b/app/app/src/main/res/drawable/ic_baseline_keyboard_arrow_left_24.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/app/app/src/main/res/drawable/ic_baseline_language_24.xml b/app/app/src/main/res/drawable/ic_baseline_language_24.xml
new file mode 100644
index 0000000..f9c7bfa
--- /dev/null
+++ b/app/app/src/main/res/drawable/ic_baseline_language_24.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/app/app/src/main/res/drawable/ic_baseline_mood_24.xml b/app/app/src/main/res/drawable/ic_baseline_mood_24.xml
new file mode 100644
index 0000000..0cee23f
--- /dev/null
+++ b/app/app/src/main/res/drawable/ic_baseline_mood_24.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/app/app/src/main/res/drawable/ic_baseline_mood_bad_24.xml b/app/app/src/main/res/drawable/ic_baseline_mood_bad_24.xml
new file mode 100644
index 0000000..0a9013c
--- /dev/null
+++ b/app/app/src/main/res/drawable/ic_baseline_mood_bad_24.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/app/app/src/main/res/drawable/ic_baseline_person_24.xml b/app/app/src/main/res/drawable/ic_baseline_person_24.xml
new file mode 100644
index 0000000..0fa2c3e
--- /dev/null
+++ b/app/app/src/main/res/drawable/ic_baseline_person_24.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/app/app/src/main/res/drawable/ic_dashboard_black_24dp.xml b/app/app/src/main/res/drawable/ic_dashboard_black_24dp.xml
new file mode 100644
index 0000000..46fc8de
--- /dev/null
+++ b/app/app/src/main/res/drawable/ic_dashboard_black_24dp.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/app/src/main/res/drawable/ic_fiber_manual_record_24.xml b/app/app/src/main/res/drawable/ic_fiber_manual_record_24.xml
new file mode 100644
index 0000000..feb56de
--- /dev/null
+++ b/app/app/src/main/res/drawable/ic_fiber_manual_record_24.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/app/app/src/main/res/drawable/ic_home_black_24dp.xml b/app/app/src/main/res/drawable/ic_home_black_24dp.xml
new file mode 100644
index 0000000..f8bb0b5
--- /dev/null
+++ b/app/app/src/main/res/drawable/ic_home_black_24dp.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/app/src/main/res/drawable/ic_launcher_background.xml b/app/app/src/main/res/drawable/ic_launcher_background.xml
new file mode 100644
index 0000000..07d5da9
--- /dev/null
+++ b/app/app/src/main/res/drawable/ic_launcher_background.xml
@@ -0,0 +1,170 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/app/src/main/res/drawable/ic_notifications_black_24dp.xml b/app/app/src/main/res/drawable/ic_notifications_black_24dp.xml
new file mode 100644
index 0000000..78b75c3
--- /dev/null
+++ b/app/app/src/main/res/drawable/ic_notifications_black_24dp.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/app/src/main/res/drawable/open_1.png b/app/app/src/main/res/drawable/open_1.png
new file mode 100644
index 0000000..2b5f8aa
Binary files /dev/null and b/app/app/src/main/res/drawable/open_1.png differ
diff --git a/app/app/src/main/res/drawable/open_2.png b/app/app/src/main/res/drawable/open_2.png
new file mode 100644
index 0000000..21ba770
Binary files /dev/null and b/app/app/src/main/res/drawable/open_2.png differ
diff --git a/app/app/src/main/res/drawable/test_image.xml b/app/app/src/main/res/drawable/test_image.xml
new file mode 100644
index 0000000..8e72b50
--- /dev/null
+++ b/app/app/src/main/res/drawable/test_image.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/app/src/main/res/layout/activity_login.xml b/app/app/src/main/res/layout/activity_login.xml
new file mode 100644
index 0000000..b2b2402
--- /dev/null
+++ b/app/app/src/main/res/layout/activity_login.xml
@@ -0,0 +1,90 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/app/src/main/res/layout/activity_main.xml b/app/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..89b895b
--- /dev/null
+++ b/app/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/app/src/main/res/layout/activity_register.xml b/app/app/src/main/res/layout/activity_register.xml
new file mode 100644
index 0000000..728934f
--- /dev/null
+++ b/app/app/src/main/res/layout/activity_register.xml
@@ -0,0 +1,201 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/app/src/main/res/layout/fragment_home.xml b/app/app/src/main/res/layout/fragment_home.xml
new file mode 100644
index 0000000..8fdd43a
--- /dev/null
+++ b/app/app/src/main/res/layout/fragment_home.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/app/src/main/res/layout/item.xml b/app/app/src/main/res/layout/item.xml
new file mode 100644
index 0000000..3ede243
--- /dev/null
+++ b/app/app/src/main/res/layout/item.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/app/src/main/res/layout/item_cl.xml b/app/app/src/main/res/layout/item_cl.xml
new file mode 100644
index 0000000..02adfb3
--- /dev/null
+++ b/app/app/src/main/res/layout/item_cl.xml
@@ -0,0 +1,82 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/app/src/main/res/layout/item_fbu.xml b/app/app/src/main/res/layout/item_fbu.xml
new file mode 100644
index 0000000..d7fbe33
--- /dev/null
+++ b/app/app/src/main/res/layout/item_fbu.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/app/src/main/res/layout/main.xml b/app/app/src/main/res/layout/main.xml
new file mode 100644
index 0000000..8447547
--- /dev/null
+++ b/app/app/src/main/res/layout/main.xml
@@ -0,0 +1,91 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/app/src/main/res/layout/out_fragment.xml b/app/app/src/main/res/layout/out_fragment.xml
new file mode 100644
index 0000000..73217c8
--- /dev/null
+++ b/app/app/src/main/res/layout/out_fragment.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/app/src/main/res/layout/sc_fragment.xml b/app/app/src/main/res/layout/sc_fragment.xml
new file mode 100644
index 0000000..8fdd43a
--- /dev/null
+++ b/app/app/src/main/res/layout/sc_fragment.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/app/src/main/res/layout/wd_fragment.xml b/app/app/src/main/res/layout/wd_fragment.xml
new file mode 100644
index 0000000..8fdd43a
--- /dev/null
+++ b/app/app/src/main/res/layout/wd_fragment.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/app/src/main/res/menu/bottom_nav_menu.xml b/app/app/src/main/res/menu/bottom_nav_menu.xml
new file mode 100644
index 0000000..ceb203d
--- /dev/null
+++ b/app/app/src/main/res/menu/bottom_nav_menu.xml
@@ -0,0 +1,25 @@
+
+
\ No newline at end of file
diff --git a/app/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 0000000..eca70cf
--- /dev/null
+++ b/app/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 0000000..eca70cf
--- /dev/null
+++ b/app/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/app/src/main/res/mipmap-hdpi/aaa.png b/app/app/src/main/res/mipmap-hdpi/aaa.png
new file mode 100644
index 0000000..f967a16
Binary files /dev/null and b/app/app/src/main/res/mipmap-hdpi/aaa.png differ
diff --git a/app/app/src/main/res/mipmap-hdpi/add.png b/app/app/src/main/res/mipmap-hdpi/add.png
new file mode 100644
index 0000000..c00349d
Binary files /dev/null and b/app/app/src/main/res/mipmap-hdpi/add.png differ
diff --git a/app/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/app/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000..a571e60
Binary files /dev/null and b/app/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/app/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/app/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
new file mode 100644
index 0000000..61da551
Binary files /dev/null and b/app/app/src/main/res/mipmap-hdpi/ic_launcher_round.png differ
diff --git a/app/app/src/main/res/mipmap-hdpi/login.jpg b/app/app/src/main/res/mipmap-hdpi/login.jpg
new file mode 100644
index 0000000..5376b0e
Binary files /dev/null and b/app/app/src/main/res/mipmap-hdpi/login.jpg differ
diff --git a/app/app/src/main/res/mipmap-hdpi/sc0.png b/app/app/src/main/res/mipmap-hdpi/sc0.png
new file mode 100644
index 0000000..28c3adc
Binary files /dev/null and b/app/app/src/main/res/mipmap-hdpi/sc0.png differ
diff --git a/app/app/src/main/res/mipmap-hdpi/sc1.png b/app/app/src/main/res/mipmap-hdpi/sc1.png
new file mode 100644
index 0000000..0ff1cbf
Binary files /dev/null and b/app/app/src/main/res/mipmap-hdpi/sc1.png differ
diff --git a/app/app/src/main/res/mipmap-hdpi/xz0.png b/app/app/src/main/res/mipmap-hdpi/xz0.png
new file mode 100644
index 0000000..eff1710
Binary files /dev/null and b/app/app/src/main/res/mipmap-hdpi/xz0.png differ
diff --git a/app/app/src/main/res/mipmap-hdpi/xz1.png b/app/app/src/main/res/mipmap-hdpi/xz1.png
new file mode 100644
index 0000000..f25574a
Binary files /dev/null and b/app/app/src/main/res/mipmap-hdpi/xz1.png differ
diff --git a/app/app/src/main/res/mipmap-mdpi/ic_launcher.png b/app/app/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000..c41dd28
Binary files /dev/null and b/app/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/app/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/app/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
new file mode 100644
index 0000000..db5080a
Binary files /dev/null and b/app/app/src/main/res/mipmap-mdpi/ic_launcher_round.png differ
diff --git a/app/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/app/app/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..6dba46d
Binary files /dev/null and b/app/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/app/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/app/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..da31a87
Binary files /dev/null and b/app/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ
diff --git a/app/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..15ac681
Binary files /dev/null and b/app/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/app/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/app/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..b216f2d
Binary files /dev/null and b/app/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ
diff --git a/app/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/app/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 0000000..f25a419
Binary files /dev/null and b/app/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/app/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/app/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..e96783c
Binary files /dev/null and b/app/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ
diff --git a/app/app/src/main/res/navigation/mobile_navigation.xml b/app/app/src/main/res/navigation/mobile_navigation.xml
new file mode 100644
index 0000000..bc77cdb
--- /dev/null
+++ b/app/app/src/main/res/navigation/mobile_navigation.xml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/app/src/main/res/values-night/themes.xml b/app/app/src/main/res/values-night/themes.xml
new file mode 100644
index 0000000..8d5a5dc
--- /dev/null
+++ b/app/app/src/main/res/values-night/themes.xml
@@ -0,0 +1,16 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/app/src/main/res/values/colors.xml b/app/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000..f8c6127
--- /dev/null
+++ b/app/app/src/main/res/values/colors.xml
@@ -0,0 +1,10 @@
+
+
+ #FFBB86FC
+ #FF6200EE
+ #FF3700B3
+ #FF03DAC5
+ #FF018786
+ #FF000000
+ #FFFFFFFF
+
\ No newline at end of file
diff --git a/app/app/src/main/res/values/dimens.xml b/app/app/src/main/res/values/dimens.xml
new file mode 100644
index 0000000..e00c2dd
--- /dev/null
+++ b/app/app/src/main/res/values/dimens.xml
@@ -0,0 +1,5 @@
+
+
+ 16dp
+ 16dp
+
\ No newline at end of file
diff --git a/app/app/src/main/res/values/strings.xml b/app/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..3b91631
--- /dev/null
+++ b/app/app/src/main/res/values/strings.xml
@@ -0,0 +1,11 @@
+
+ 个性定制公寓
+ 退出登陆
+ 个人中心
+ 参与
+ 发起
+ 房源推荐
+ 问卷调查
+
+ Hello blank fragment
+
\ No newline at end of file
diff --git a/app/app/src/main/res/values/themes.xml b/app/app/src/main/res/values/themes.xml
new file mode 100644
index 0000000..769f046
--- /dev/null
+++ b/app/app/src/main/res/values/themes.xml
@@ -0,0 +1,19 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/app/src/main/res/xml/network_security_config.xml b/app/app/src/main/res/xml/network_security_config.xml
new file mode 100644
index 0000000..2439f15
--- /dev/null
+++ b/app/app/src/main/res/xml/network_security_config.xml
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/app/build.gradle b/app/build.gradle
new file mode 100644
index 0000000..fa53fdf
--- /dev/null
+++ b/app/build.gradle
@@ -0,0 +1,25 @@
+plugins {
+ alias(libs.plugins.androidApplication) apply false
+}
+//buildscript {
+// repositories {
+// google()
+// jcenter()
+// }
+// dependencies {
+// classpath 'com.android.tools.build:gradle:3.5.3'
+// // NOTE: Do not place your application dependencies here; they belong
+// // in the individual module build.gradle files
+// }
+//}
+//
+//allprojects {
+// repositories {
+// google()
+// jcenter()
+// }
+//}
+//
+//task clean(type: Delete) {
+// delete rootProject.buildDir
+//}
\ No newline at end of file
diff --git a/app/gradle.properties b/app/gradle.properties
new file mode 100644
index 0000000..52f5917
--- /dev/null
+++ b/app/gradle.properties
@@ -0,0 +1,19 @@
+# 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
+# Automatically convert third-party libraries to use AndroidX
+android.enableJetifier=true
\ No newline at end of file
diff --git a/app/gradle/libs.versions.toml b/app/gradle/libs.versions.toml
new file mode 100644
index 0000000..111057a
--- /dev/null
+++ b/app/gradle/libs.versions.toml
@@ -0,0 +1,22 @@
+[versions]
+agp = "8.3.0"
+junit = "4.13.2"
+junitVersion = "1.1.5"
+espressoCore = "3.5.1"
+appcompat = "1.6.1"
+material = "1.10.0"
+activity = "1.8.0"
+constraintlayout = "2.1.4"
+
+[libraries]
+junit = { group = "junit", name = "junit", version.ref = "junit" }
+ext-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
+espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
+appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" }
+material = { group = "com.google.android.material", name = "material", version.ref = "material" }
+activity = { group = "androidx.activity", name = "activity", version.ref = "activity" }
+constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "constraintlayout" }
+
+[plugins]
+androidApplication = { id = "com.android.application", version.ref = "agp" }
+
diff --git a/app/gradle/wrapper/gradle-wrapper.jar b/app/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..7454180
Binary files /dev/null and b/app/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/app/gradle/wrapper/gradle-wrapper.properties b/app/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..e411586
--- /dev/null
+++ b/app/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,5 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/app/gradlew b/app/gradlew
new file mode 100644
index 0000000..1b6c787
--- /dev/null
+++ b/app/gradlew
@@ -0,0 +1,234 @@
+#!/bin/sh
+
+#
+# Copyright © 2015-2021 the original 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 POSIX generated by Gradle.
+#
+# Important for running:
+#
+# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
+# noncompliant, but you have some other compliant shell such as ksh or
+# bash, then to run this script, type that shell name before the whole
+# command line, like:
+#
+# ksh Gradle
+#
+# Busybox and similar reduced shells will NOT work, because this script
+# requires all of these POSIX shell features:
+# * functions;
+# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
+# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
+# * compound commands having a testable exit status, especially «case»;
+# * various built-in commands including «command», «set», and «ulimit».
+#
+# Important for patching:
+#
+# (2) This script targets any POSIX shell, so it avoids extensions provided
+# by Bash, Ksh, etc; in particular arrays are avoided.
+#
+# The "traditional" practice of packing multiple parameters into a
+# space-separated string is a well documented source of bugs and security
+# problems, so this is (mostly) avoided, by progressively accumulating
+# options in "$@", and eventually passing that to Java.
+#
+# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
+# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
+# see the in-line comments for details.
+#
+# There are tweaks for specific operating systems such as AIX, CygWin,
+# Darwin, MinGW, and NonStop.
+#
+# (3) This script is generated from the Groovy template
+# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
+# within the Gradle project.
+#
+# You can find Gradle at https://github.com/gradle/gradle/.
+#
+##############################################################################
+
+# Attempt to set APP_HOME
+
+# Resolve links: $0 may be a link
+app_path=$0
+
+# Need this for daisy-chained symlinks.
+while
+ APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
+ [ -h "$app_path" ]
+do
+ ls=$( ls -ld "$app_path" )
+ link=${ls#*' -> '}
+ case $link in #(
+ /*) app_path=$link ;; #(
+ *) app_path=$APP_HOME$link ;;
+ esac
+done
+
+APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
+
+APP_NAME="Gradle"
+APP_BASE_NAME=${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 "$*"
+} >&2
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+} >&2
+
+# 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 ;; #(
+ MSYS* | 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" && ! "$darwin" && ! "$nonstop" ; then
+ case $MAX_FD in #(
+ max*)
+ MAX_FD=$( ulimit -H -n ) ||
+ warn "Could not query maximum file descriptor limit"
+ esac
+ case $MAX_FD in #(
+ '' | soft) :;; #(
+ *)
+ ulimit -n "$MAX_FD" ||
+ warn "Could not set maximum file descriptor limit to $MAX_FD"
+ esac
+fi
+
+# Collect all arguments for the java command, stacking in reverse order:
+# * args from the command line
+# * the main class name
+# * -classpath
+# * -D...appname settings
+# * --module-path (only if needed)
+# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if "$cygwin" || "$msys" ; then
+ APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
+ CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
+
+ JAVACMD=$( cygpath --unix "$JAVACMD" )
+
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ for arg do
+ if
+ case $arg in #(
+ -*) false ;; # don't mess with options #(
+ /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
+ [ -e "$t" ] ;; #(
+ *) false ;;
+ esac
+ then
+ arg=$( cygpath --path --ignore --mixed "$arg" )
+ fi
+ # Roll the args list around exactly as many times as the number of
+ # args, so each arg winds up back in the position where it started, but
+ # possibly modified.
+ #
+ # NB: a `for` loop captures its iteration list before it begins, so
+ # changing the positional parameters here affects neither the number of
+ # iterations, nor the values presented in `arg`.
+ shift # remove old arg
+ set -- "$@" "$arg" # push replacement arg
+ done
+fi
+
+# Collect all arguments for the java command;
+# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
+# shell script including quotes and variable substitutions, so put them in
+# double quotes to make sure that they get re-expanded; and
+# * put everything else in single quotes, so that it's not re-expanded.
+
+set -- \
+ "-Dorg.gradle.appname=$APP_BASE_NAME" \
+ -classpath "$CLASSPATH" \
+ org.gradle.wrapper.GradleWrapperMain \
+ "$@"
+
+# Use "xargs" to parse quoted args.
+#
+# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
+#
+# In Bash we could simply go:
+#
+# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
+# set -- "${ARGS[@]}" "$@"
+#
+# but POSIX shell has neither arrays nor command substitution, so instead we
+# post-process each arg (as a line of input to sed) to backslash-escape any
+# character that might be a shell metacharacter, then use eval to reverse
+# that process (while maintaining the separation between arguments), and wrap
+# the whole thing up as a single "set" statement.
+#
+# This will of course break if any of these variables contains a newline or
+# an unmatched quote.
+#
+
+eval "set -- $(
+ printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
+ xargs -n1 |
+ sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
+ tr '\n' ' '
+ )" '"$@"'
+
+exec "$JAVACMD" "$@"
diff --git a/app/gradlew.bat b/app/gradlew.bat
new file mode 100644
index 0000000..107acd3
--- /dev/null
+++ b/app/gradlew.bat
@@ -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
diff --git a/app/settings.gradle b/app/settings.gradle
new file mode 100644
index 0000000..a1e3f9e
--- /dev/null
+++ b/app/settings.gradle
@@ -0,0 +1,25 @@
+pluginManagement {
+ repositories {
+ google {
+ content {
+ includeGroupByRegex("com\\.android.*")
+ includeGroupByRegex("com\\.google.*")
+ includeGroupByRegex("androidx.*")
+ }
+ }
+ mavenCentral()
+ gradlePluginPortal()
+ google()
+ jcenter()
+ }
+}
+dependencyResolutionManagement {
+ repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
+ repositories {
+ google()
+ mavenCentral()
+ jcenter()
+ }
+}
+include ':app'
+rootProject.name = "code"
\ No newline at end of file