sunnnl

pull remote/master to local/sumin

Showing 32 changed files with 399 additions and 53 deletions
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
7 /.idea/workspace.xml 7 /.idea/workspace.xml
8 /.idea/navEditor.xml 8 /.idea/navEditor.xml
9 /.idea/assetWizardSettings.xml 9 /.idea/assetWizardSettings.xml
10 +/.idea/.name
10 .DS_Store 11 .DS_Store
11 /build 12 /build
12 /captures 13 /captures
......
...@@ -11,21 +11,26 @@ ...@@ -11,21 +11,26 @@
11 android:label="@string/app_name" 11 android:label="@string/app_name"
12 android:roundIcon="@mipmap/ic_launcher_round" 12 android:roundIcon="@mipmap/ic_launcher_round"
13 android:supportsRtl="true" 13 android:supportsRtl="true"
14 - android:theme="@style/AppTheme"> 14 + android:networkSecurityConfig="@xml/network_security_config"
15 + android:theme="@style/Theme.AppCompat.NoActionBar">
15 <activity android:name=".ui.VideoCheckActivity"></activity> 16 <activity android:name=".ui.VideoCheckActivity"></activity>
16 <activity android:name=".ui.DeviceManagerActivity" /> 17 <activity android:name=".ui.DeviceManagerActivity" />
17 <activity android:name=".ui.RemoteControlRecordActivity" /> 18 <activity android:name=".ui.RemoteControlRecordActivity" />
18 <activity 19 <activity
19 android:name=".ui.SplashActivity" 20 android:name=".ui.SplashActivity"
20 android:noHistory="true" 21 android:noHistory="true"
21 - android:screenOrientation="fullSensor" /> 22 + android:screenOrientation="fullSensor" >
22 - <activity android:name=".ui.MainActivity"> 23 +
23 <intent-filter> 24 <intent-filter>
24 <action android:name="android.intent.action.MAIN" /> 25 <action android:name="android.intent.action.MAIN" />
25 26
26 <category android:name="android.intent.category.LAUNCHER" /> 27 <category android:name="android.intent.category.LAUNCHER" />
27 </intent-filter> 28 </intent-filter>
28 </activity> 29 </activity>
30 + <activity android:name=".ui.MainActivity">
31 +
32 + </activity>
33 + <activity android:name=".ui.SettingActivity" />
29 </application> 34 </application>
30 35
31 </manifest> 36 </manifest>
...\ No newline at end of file ...\ No newline at end of file
......
1 +package com.sunnni.smartdoorlock.api;
2 +
3 +import android.os.Handler;
4 +import android.util.Log;
5 +
6 +import com.google.gson.JsonArray;
7 +import com.google.gson.JsonElement;
8 +import com.google.gson.JsonObject;
9 +import com.google.gson.JsonParser;
10 +
11 +import org.json.JSONObject;
12 +
13 +import java.io.BufferedInputStream;
14 +import java.io.BufferedReader;
15 +import java.io.InputStream;
16 +import java.io.InputStreamReader;
17 +import java.io.OutputStream;
18 +import java.net.HttpURLConnection;
19 +import java.net.URL;
20 +import java.util.Iterator;
21 +import java.util.Set;
22 +
23 +public class Api {
24 + public interface Callback {
25 + void callbackMethod(Object obj);
26 + }
27 +
28 + static private final String DOMAIN = "gateway.bu.to";
29 + static private String accessToken = null;
30 +
31 + static private void callApi(final String method, final String endpoint, final JsonObject params, final Callback callback) {
32 + final Handler handler = new Handler();
33 + new Thread() {
34 + public void run() {
35 + ApiResult apiResult;
36 + try {
37 + String queryString = "";
38 + if(("GET".equals(method) || "DELETE".equals(method)) && params != null) {
39 + Set<String> keys = params.keySet();
40 + Iterator<String> iter = keys.iterator();
41 + while(iter.hasNext()) {
42 + String key = iter.next();
43 + queryString += "&" + key + "=" + params.get(key).getAsString();
44 + }
45 + queryString = "?" + queryString.substring(1);
46 + }
47 +
48 + URL url = new URL("http://" + Api.DOMAIN + endpoint + queryString);
49 + HttpURLConnection conn = (HttpURLConnection) url.openConnection();
50 + conn.setRequestMethod(method);
51 +
52 + if(accessToken != null) {
53 + conn.setRequestProperty("access_token", accessToken);
54 + }
55 +
56 + if("POST".equals(method) || "PUT".equals(method)) {
57 + if(params == null) {
58 + throw new Exception("params is null");
59 + }
60 + OutputStream os = conn.getOutputStream();
61 + os.write(params.toString().getBytes());
62 + os.flush();
63 + os.close();
64 + }
65 +
66 + int status = conn.getResponseCode();
67 + Log.d("status", String.valueOf(status));
68 + InputStream is = conn.getErrorStream();
69 + if(is == null)
70 + is = conn.getInputStream();
71 +
72 + StringBuilder builder = new StringBuilder();
73 + BufferedReader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
74 + String line;
75 + while((line = reader.readLine()) != null) {
76 + builder.append(line);
77 + }
78 +
79 + Log.d("http result", builder.toString());
80 + JsonElement jsonElement = JsonParser.parseString(builder.toString());
81 +
82 + apiResult = new ApiResult(status < 300, status, jsonElement);
83 + } catch (Exception e) {
84 + e.printStackTrace();
85 + apiResult = new ApiResult(false);
86 + }
87 +
88 + final ApiResult finalApiResult = apiResult;
89 + handler.post(new Runnable() {
90 + @Override
91 + public void run() {
92 + callback.callbackMethod(finalApiResult);
93 + }
94 + });
95 + }
96 + }.start();
97 + }
98 +
99 + static public void setAccessToken(String accessToken) {
100 + Api.accessToken = accessToken;
101 + }
102 +
103 + static public void auth(String doorId, final Callback callback) {
104 + if("123123123".equals(doorId)) {
105 + // 테스트를 위한 super pass
106 + callback.callbackMethod(new Auth(true, "superpass"));
107 + return;
108 + }
109 +
110 + JsonObject params = new JsonObject();
111 + params.addProperty("door_id", doorId);
112 + callApi("GET", "/api/auth", params, new Callback() {
113 + @Override
114 + public void callbackMethod(Object obj) {
115 + ApiResult apiResult = (ApiResult) obj;
116 + if(apiResult.isSuccess()) {
117 + JsonObject resp = (JsonObject) apiResult.getData();
118 + if(resp.get("is_available").getAsBoolean()) {
119 + callback.callbackMethod(new Auth(true, resp.get("access_token").getAsString()));
120 + } else {
121 + callback.callbackMethod(new Auth(false));
122 + }
123 + } else {
124 + callback.callbackMethod(null);
125 + }
126 + }
127 + });
128 + }
129 +
130 + static public void getSetting(final Callback callback) {
131 + callApi("GET", "/api/setting", null, new Callback() {
132 + @Override
133 + public void callbackMethod(Object obj) {
134 + ApiResult apiResult = (ApiResult) obj;
135 + if(apiResult.isSuccess()) {
136 + JsonObject resp = (JsonObject) apiResult.getData();
137 + callback.callbackMethod(new Setting(resp.get("recording").getAsBoolean()));
138 + } else {
139 + callback.callbackMethod(null);
140 + }
141 + }
142 + });
143 + }
144 +
145 + static public void setSetting(Setting setting, final Callback callback) {
146 + JsonObject params = new JsonObject();
147 + params.addProperty("recording", setting.getRecording());
148 +
149 + callApi("PUT", "/api/setting", params, new Callback() {
150 + @Override
151 + public void callbackMethod(Object obj) {
152 + ApiResult apiResult = (ApiResult) obj;
153 + if(apiResult.isSuccess()) {
154 + callback.callbackMethod(true);
155 + } else {
156 + callback.callbackMethod(null);
157 + }
158 + }
159 + });
160 + }
161 +}
1 +package com.sunnni.smartdoorlock.api;
2 +
3 +import com.google.gson.JsonElement;
4 +import com.google.gson.JsonObject;
5 +
6 +public class ApiResult {
7 + public boolean isSuccess() {
8 + return this.success;
9 + }
10 +
11 + public Object getData() {
12 + return this.data;
13 + }
14 +
15 + public int getStatus() {
16 + return this.status;
17 + }
18 +
19 + public ApiResult(boolean success, int status, JsonElement obj) {
20 + this.success = success;
21 + this.data = obj;
22 + this.status = status;
23 + }
24 +
25 + public ApiResult(boolean success) {
26 + this.success = success;
27 + this.data = null;
28 + this.status = 999;
29 + }
30 +
31 + private boolean success;
32 + private JsonElement data;
33 + private int status;
34 +}
1 +package com.sunnni.smartdoorlock.api;
2 +
3 +public class Auth {
4 + private boolean isAvailable;
5 + private String accessToken = null;
6 +
7 + public Auth(boolean isAvailable, String accessToken) {
8 + this.isAvailable = isAvailable;
9 + this.accessToken = accessToken;
10 + }
11 +
12 + public Auth(boolean isAvailable) {
13 + this.isAvailable = isAvailable;
14 + }
15 +
16 + public boolean getIsAvailable() {
17 + return this.isAvailable;
18 + }
19 +
20 + public String getAccessToken() {
21 + return this.accessToken;
22 + }
23 +}
1 +package com.sunnni.smartdoorlock.api;
2 +
3 +public class Setting {
4 + private boolean recording;
5 +
6 + public Setting(boolean recording) {
7 + this.recording = recording;
8 + }
9 +
10 + public boolean getRecording() {
11 + return recording;
12 + }
13 +}
1 +package com.sunnni.smartdoorlock.ui;
2 +
3 +import android.content.Intent;
4 +import android.content.SharedPreferences;
5 +import android.os.Bundle;
6 +import android.view.View;
7 +import android.widget.Button;
8 +import android.widget.CompoundButton;
9 +import android.widget.Switch;
10 +import android.widget.Toast;
11 +
12 +import com.sunnni.smartdoorlock.R;
13 +import com.sunnni.smartdoorlock.api.Api;
14 +import com.sunnni.smartdoorlock.api.Setting;
15 +
16 +import androidx.appcompat.app.AppCompatActivity;
17 +
18 +public class SettingActivity extends AppCompatActivity {
19 + private Switch swcRecording;
20 + private Button btnLogout;
21 +
22 + @Override
23 + protected void onCreate(Bundle savedInstanceState) {
24 + super.onCreate(savedInstanceState);
25 + setContentView(R.layout.activity_setting);
26 + btnLogout = (Button) findViewById(R.id.btn_logout);
27 + btnLogout.setOnClickListener(new View.OnClickListener() {
28 + @Override
29 + public void onClick(View view) {
30 + SharedPreferences pref = getSharedPreferences("gateway", MODE_PRIVATE);
31 + SharedPreferences.Editor editor = pref.edit();
32 + editor.remove("accessToken");
33 + editor.commit();
34 + startActivity(new Intent(SettingActivity.this, SplashActivity.class));
35 + }
36 + });
37 +
38 + swcRecording = (Switch) findViewById(R.id.swc_recording);
39 + swcRecording.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
40 + @Override
41 + public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
42 + Api.setSetting(new Setting(true), new Api.Callback() {
43 + @Override
44 + public void callbackMethod(Object obj) {
45 + if(obj == null) {
46 + Toast.makeText(getApplicationContext(),"연결 상태가 불안정합니다.",Toast.LENGTH_SHORT).show();
47 + }
48 + }
49 + });
50 + }
51 + });
52 +
53 + Api.getSetting(new Api.Callback() {
54 + @Override
55 + public void callbackMethod(Object obj) {
56 + Setting setting = (Setting) obj;
57 + if(setting == null) {
58 + Toast.makeText(getApplicationContext(),"연결 상태가 불안정합니다.",Toast.LENGTH_SHORT).show();
59 + return;
60 + }
61 +
62 + swcRecording.setChecked(setting.getRecording());
63 + }
64 + });
65 + }
66 +}
...@@ -5,6 +5,7 @@ import androidx.constraintlayout.widget.ConstraintLayout; ...@@ -5,6 +5,7 @@ import androidx.constraintlayout.widget.ConstraintLayout;
5 5
6 import android.annotation.SuppressLint; 6 import android.annotation.SuppressLint;
7 import android.content.Intent; 7 import android.content.Intent;
8 +import android.content.SharedPreferences;
8 import android.os.Bundle; 9 import android.os.Bundle;
9 import android.os.Handler; 10 import android.os.Handler;
10 import android.util.Log; 11 import android.util.Log;
...@@ -20,6 +21,8 @@ import android.widget.Toast; ...@@ -20,6 +21,8 @@ import android.widget.Toast;
20 import com.google.android.material.textfield.TextInputEditText; 21 import com.google.android.material.textfield.TextInputEditText;
21 import com.google.android.material.textfield.TextInputLayout; 22 import com.google.android.material.textfield.TextInputLayout;
22 import com.sunnni.smartdoorlock.R; 23 import com.sunnni.smartdoorlock.R;
24 +import com.sunnni.smartdoorlock.api.Api;
25 +import com.sunnni.smartdoorlock.api.Auth;
23 26
24 public class SplashActivity extends AppCompatActivity { 27 public class SplashActivity extends AppCompatActivity {
25 28
...@@ -27,6 +30,7 @@ public class SplashActivity extends AppCompatActivity { ...@@ -27,6 +30,7 @@ public class SplashActivity extends AppCompatActivity {
27 private TextInputLayout textInputLayout; 30 private TextInputLayout textInputLayout;
28 private TextInputEditText edtSuperKey; 31 private TextInputEditText edtSuperKey;
29 private ConstraintLayout btnEnter; 32 private ConstraintLayout btnEnter;
33 + private ImageView imgEnter;
30 34
31 private Animation logoAnimation; 35 private Animation logoAnimation;
32 36
...@@ -38,17 +42,23 @@ public class SplashActivity extends AppCompatActivity { ...@@ -38,17 +42,23 @@ public class SplashActivity extends AppCompatActivity {
38 super.onCreate(savedInstanceState); 42 super.onCreate(savedInstanceState);
39 setContentView(R.layout.activity_splash); 43 setContentView(R.layout.activity_splash);
40 44
41 - logoContainer = findViewById(R.id.ll_logo); 45 + SharedPreferences pref = getSharedPreferences("gateway", MODE_PRIVATE);
42 - textInputLayout = findViewById(R.id.til_super_key); 46 + String accessToken = pref.getString("accessToken", "");
43 - btnEnter = findViewById(R.id.cl_enter); 47 + if(!"".equals(accessToken)) {
44 - edtSuperKey = findViewById(R.id.edt_super_key); 48 + Api.setAccessToken(accessToken);
45 - 49 + startActivity(new Intent(SplashActivity.this, MainActivity.class));
46 - logoAnimation = AnimationUtils.loadAnimation(this, R.anim.anim_bottom_up); 50 + } else {
47 - 51 + logoContainer = findViewById(R.id.ll_logo);
48 - test = findViewById(R.id.img_test); 52 + textInputLayout = findViewById(R.id.til_super_key);
49 - 53 + btnEnter = findViewById(R.id.cl_enter);
50 - splashLoading(); 54 + edtSuperKey = findViewById(R.id.edt_super_key);
51 - init(); 55 + imgEnter = findViewById((R.id.img_enter));
56 +
57 + logoAnimation = AnimationUtils.loadAnimation(this, R.anim.anim_bottom_up);
58 +
59 + splashLoading();
60 + init();
61 + }
52 } 62 }
53 63
54 private void splashLoading() { 64 private void splashLoading() {
...@@ -60,49 +70,41 @@ public class SplashActivity extends AppCompatActivity { ...@@ -60,49 +70,41 @@ public class SplashActivity extends AppCompatActivity {
60 70
61 textInputLayout.setVisibility(View.VISIBLE); 71 textInputLayout.setVisibility(View.VISIBLE);
62 btnEnter.setVisibility(View.VISIBLE); 72 btnEnter.setVisibility(View.VISIBLE);
63 - btnEnter.bringToFront();
64 -
65 - test.setVisibility(View.VISIBLE);
66 -
67 -
68 - test.setOnClickListener(new View.OnClickListener() {
69 - @Override
70 - public void onClick(View v) {
71 - Log.d("스플래시", "테스트 버튼");
72 - }
73 - });
74 -
75 - btnEnter.setOnClickListener(new View.OnClickListener(){
76 - @Override
77 - public void onClick(View v) {
78 - Log.d("스플래시", "버튼");
79 - }
80 - });
81 -
82 } 73 }
83 - }, 2000); 74 + }, 3000);
84 } 75 }
85 76
86 private void init() { 77 private void init() {
87 - btnEnter.setOnClickListener(new View.OnClickListener() { 78 + imgEnter.setOnClickListener(new View.OnClickListener() {
88 @Override 79 @Override
89 public void onClick(View v) { 80 public void onClick(View v) {
90 - Log.d("스플래시", "edtSuperKey.toString()"); 81 + String text = edtSuperKey.getText().toString();
91 - if(edtSuperKey.toString().isEmpty()){ 82 + if("".equals(text)){
92 - Log.d("스플래시", "true"); 83 + Toast.makeText(getApplicationContext(),"고유번호를 입력해주세요.",Toast.LENGTH_SHORT).show();
93 } else { 84 } else {
94 - Intent intent = new Intent(SplashActivity.this, MainActivity.class); 85 + Api.auth(text, new Api.Callback() {
95 - startActivity(intent); 86 + @Override
96 - finish(); 87 + public void callbackMethod(Object obj) {
88 + Auth auth = (Auth) obj;
89 + if(auth == null) {
90 + Toast.makeText(getApplicationContext(),"연결 상태가 불안정합니다.",Toast.LENGTH_SHORT).show();
91 + return;
92 + }
93 +
94 + if(auth.getIsAvailable()) {
95 + SharedPreferences pref = getSharedPreferences("gateway", MODE_PRIVATE);
96 + SharedPreferences.Editor editor = pref.edit();
97 + editor.putString("accessToken", auth.getAccessToken());
98 + Api.setAccessToken(auth.getAccessToken());
99 + editor.commit();
100 + startActivity(new Intent(SplashActivity.this, MainActivity.class));
101 + } else {
102 + Toast.makeText(getApplicationContext(),"고유번호를 확인해주세요.",Toast.LENGTH_SHORT).show();
103 + }
104 + }
105 + });
97 } 106 }
98 } 107 }
99 }); 108 });
100 -
101 - logoContainer.setOnClickListener(new View.OnClickListener() {
102 - @Override
103 - public void onClick(View v) {
104 - Log.d("스플래시", "edtSuperKey.toString()");
105 - }
106 - });
107 } 109 }
108 } 110 }
......
...@@ -313,4 +313,12 @@ ...@@ -313,4 +313,12 @@
313 313
314 </androidx.constraintlayout.widget.ConstraintLayout> 314 </androidx.constraintlayout.widget.ConstraintLayout>
315 315
316 + <Button
317 + android:id="@+id/btn_setting"
318 + android:layout_width="wrap_content"
319 + android:layout_height="wrap_content"
320 + android:text="btn_setting"
321 + tools:layout_editor_absoluteX="166dp"
322 + tools:layout_editor_absoluteY="399dp" />
323 +
316 </androidx.constraintlayout.widget.ConstraintLayout> 324 </androidx.constraintlayout.widget.ConstraintLayout>
...\ No newline at end of file ...\ No newline at end of file
......
1 +<?xml version="1.0" encoding="utf-8"?>
2 +<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
3 + xmlns:app="http://schemas.android.com/apk/res-auto"
4 + xmlns:tools="http://schemas.android.com/tools"
5 + android:layout_width="match_parent"
6 + android:layout_height="match_parent">
7 +
8 + <Button
9 + android:id="@+id/btn_logout"
10 + android:layout_width="wrap_content"
11 + android:layout_height="wrap_content"
12 + android:layout_marginStart="22dp"
13 + android:layout_marginTop="9dp"
14 + android:text="btn_logout"
15 + app:layout_constraintStart_toStartOf="@+id/swc_recording"
16 + app:layout_constraintTop_toBottomOf="@+id/swc_recording" />
17 +
18 + <Switch
19 + android:id="@+id/swc_recording"
20 + android:layout_width="wrap_content"
21 + android:layout_height="wrap_content"
22 + android:layout_marginEnd="117dp"
23 + android:layout_marginTop="151dp"
24 + android:text="swc_recording"
25 + app:layout_constraintEnd_toEndOf="parent"
26 + app:layout_constraintTop_toTopOf="parent" />
27 +</androidx.constraintlayout.widget.ConstraintLayout>
...\ No newline at end of file ...\ No newline at end of file
...@@ -94,6 +94,7 @@ ...@@ -94,6 +94,7 @@
94 app:layout_constraintTop_toTopOf="parent" /> 94 app:layout_constraintTop_toTopOf="parent" />
95 95
96 <ImageView 96 <ImageView
97 + android:id="@+id/img_enter"
97 android:layout_width="wrap_content" 98 android:layout_width="wrap_content"
98 android:layout_height="wrap_content" 99 android:layout_height="wrap_content"
99 android:src="@drawable/baseline_send_white_24" 100 android:src="@drawable/baseline_send_white_24"
......
1 <?xml version="1.0" encoding="utf-8"?> 1 <?xml version="1.0" encoding="utf-8"?>
2 <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> 2 <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
3 - <background android:drawable="@drawable/ic_launcher_background" /> 3 + <background android:drawable="@drawable/ic_launcher_background"/>
4 - <foreground android:drawable="@drawable/ic_launcher_foreground" /> 4 + <foreground android:drawable="@mipmap/ic_launcher_foreground"/>
5 </adaptive-icon> 5 </adaptive-icon>
...\ No newline at end of file ...\ No newline at end of file
......
1 <?xml version="1.0" encoding="utf-8"?> 1 <?xml version="1.0" encoding="utf-8"?>
2 <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> 2 <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
3 - <background android:drawable="@drawable/ic_launcher_background" /> 3 + <background android:drawable="@drawable/ic_launcher_background"/>
4 - <foreground android:drawable="@drawable/ic_launcher_foreground" /> 4 + <foreground android:drawable="@mipmap/ic_launcher_foreground"/>
5 </adaptive-icon> 5 </adaptive-icon>
...\ No newline at end of file ...\ No newline at end of file
......

3.51 KB | W: | H:

1.9 KB | W: | H:

  • 2-up
  • Swipe
  • Onion skin

5.21 KB | W: | H:

3.68 KB | W: | H:

  • 2-up
  • Swipe
  • Onion skin

2.57 KB | W: | H:

1.35 KB | W: | H:

  • 2-up
  • Swipe
  • Onion skin

3.31 KB | W: | H:

2.3 KB | W: | H:

  • 2-up
  • Swipe
  • Onion skin

4.81 KB | W: | H:

2.79 KB | W: | H:

  • 2-up
  • Swipe
  • Onion skin

7.3 KB | W: | H:

5.2 KB | W: | H:

  • 2-up
  • Swipe
  • Onion skin

7.72 KB | W: | H:

4.23 KB | W: | H:

  • 2-up
  • Swipe
  • Onion skin

11.6 KB | W: | H:

8.14 KB | W: | H:

  • 2-up
  • Swipe
  • Onion skin

10.4 KB | W: | H:

6 KB | W: | H:

  • 2-up
  • Swipe
  • Onion skin

16.2 KB | W: | H:

11.7 KB | W: | H:

  • 2-up
  • Swipe
  • Onion skin
1 +<?xml version="1.0" encoding="utf-8"?>
2 +<network-security-config>
3 + <!--Set application-wide security config using base-config tag.-->
4 + <base-config cleartextTrafficPermitted="true"/>
5 +</network-security-config>
...\ No newline at end of file ...\ No newline at end of file
...@@ -8,7 +8,7 @@ buildscript { ...@@ -8,7 +8,7 @@ buildscript {
8 8
9 } 9 }
10 dependencies { 10 dependencies {
11 - classpath 'com.android.tools.build:gradle:3.6.1' 11 + classpath 'com.android.tools.build:gradle:3.6.3'
12 12
13 13
14 // NOTE: Do not place your application dependencies here; they belong 14 // NOTE: Do not place your application dependencies here; they belong
......