sunnnl

Merge branch 'master' of http://khuhub.khu.ac.kr/cse437_e/smartdoorlock-frontend into sumin

package com.sunnni.smartdoorlock.api;
import android.os.Build;
import android.os.Handler;
import android.util.Log;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.sunnni.smartdoorlock.data.Auth;
import com.sunnni.smartdoorlock.data.Device;
import com.sunnni.smartdoorlock.data.RemoteRecord;
import com.sunnni.smartdoorlock.data.Setting;
import com.sunnni.smartdoorlock.data.Video;
import org.json.JSONObject;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Set;
......@@ -54,13 +57,12 @@ public class Api {
}
if("POST".equals(method) || "PUT".equals(method)) {
if(params == null) {
throw new Exception("params is null");
if(params != null) {
OutputStream os = conn.getOutputStream();
os.write(params.toString().getBytes());
os.flush();
os.close();
}
OutputStream os = conn.getOutputStream();
os.write(params.toString().getBytes());
os.flush();
os.close();
}
int status = conn.getResponseCode();
......@@ -158,4 +160,158 @@ public class Api {
}
});
}
static public void requestRemote(final Callback callback) {
JsonObject params = new JsonObject();
params.addProperty("device_name", Build.MODEL);
callApi("POST", "/api/remote", params, new Callback() {
@Override
public void callbackMethod(Object obj) {
ApiResult apiResult = (ApiResult) obj;
if(apiResult.isSuccess()) {
callback.callbackMethod(new Boolean(true));
} else {
callback.callbackMethod(null);
}
}
});
}
static public void getRemotes(final Callback callback) {
callApi("GET", "/api/remote", null, new Callback() {
@Override
public void callbackMethod(Object obj) {
ApiResult apiResult = (ApiResult) obj;
if(apiResult.isSuccess()) {
JsonObject resp = (JsonObject) apiResult.getData();
if(resp.has("remoteHistoryList")) {
ArrayList<RemoteRecord> remoteRecords = new ArrayList<RemoteRecord>();
Iterator it = resp.getAsJsonArray("remoteHistoryList").iterator();
while(it.hasNext()) {
JsonObject jsonObject = (JsonObject) it.next();
remoteRecords.add(new RemoteRecord(jsonObject.get("device_name").getAsString(), jsonObject.get("created").getAsString()));
}
callback.callbackMethod(remoteRecords);
} else {
callback.callbackMethod(null);
}
} else {
callback.callbackMethod(null);
}
}
});
}
static public void getVideos(final Callback callback) {
callApi("GET", "/api/video", null, new Callback() {
@Override
public void callbackMethod(Object obj) {
ApiResult apiResult = (ApiResult) obj;
if(apiResult.isSuccess()) {
JsonObject resp = (JsonObject) apiResult.getData();
if(resp.has("videoList")) {
ArrayList<Video> videos = new ArrayList<Video>();
Iterator it = resp.getAsJsonArray("videoList").iterator();
while(it.hasNext()) {
JsonObject jsonObject = (JsonObject) it.next();
videos.add(new Video(jsonObject.get("vid_name").getAsString(), jsonObject.get("thumb").getAsString(), jsonObject.get("created").getAsString()));
}
callback.callbackMethod(videos);
} else {
callback.callbackMethod(null);
}
} else {
callback.callbackMethod(null);
}
}
});
}
static public void getVideo(Video video, final Callback callback) {
callApi("GET", "/api/video/" + video.getVidName(), null, new Callback() {
@Override
public void callbackMethod(Object obj) {
ApiResult apiResult = (ApiResult) obj;
if(apiResult.isSuccess()) {
JsonObject resp = (JsonObject) apiResult.getData();
if(resp.has("s3link")) {
callback.callbackMethod(resp.get("s3link").getAsString());
} else {
callback.callbackMethod(null);
}
} else {
callback.callbackMethod(null);
}
}
});
}
static public void removeVideo(Video video, final Callback callback) {
callApi("DELETE", "/api/video/" + video.getVidName(), null, new Callback() {
@Override
public void callbackMethod(Object obj) {
ApiResult apiResult = (ApiResult) obj;
if(apiResult.isSuccess()) {
callback.callbackMethod(new Boolean(true));
} else {
callback.callbackMethod(null);
}
}
});
}
static public void getDevices(final Callback callback) {
callApi("GET", "/api/device", null, new Callback() {
@Override
public void callbackMethod(Object obj) {
ApiResult apiResult = (ApiResult) obj;
if(apiResult.isSuccess()) {
JsonObject resp = (JsonObject) apiResult.getData();
if(resp.has("deviceList")) {
ArrayList<Device> videos = new ArrayList<Device>();
Iterator it = resp.getAsJsonArray("deviceList").iterator();
while(it.hasNext()) {
JsonObject jsonObject = (JsonObject) it.next();
videos.add(new Device(jsonObject.get("device_id").getAsInt(), jsonObject.get("rfid_id").getAsString(), jsonObject.get("created").getAsString()));
}
callback.callbackMethod(videos);
} else {
callback.callbackMethod(null);
}
} else {
callback.callbackMethod(null);
}
}
});
}
static public void removeDevice(Device device, final Callback callback) {
callApi("DELETE", "/api/device/" + device.getDeviceId(), null, new Callback() {
@Override
public void callbackMethod(Object obj) {
ApiResult apiResult = (ApiResult) obj;
if(apiResult.isSuccess()) {
callback.callbackMethod(new Boolean(true));
} else {
callback.callbackMethod(null);
}
}
});
}
static public void requestAddDevice(final Callback callback) {
callApi("POST", "/api/device/request", null, new Callback() {
@Override
public void callbackMethod(Object obj) {
ApiResult apiResult = (ApiResult) obj;
if(apiResult.isSuccess()) {
callback.callbackMethod(new Boolean(true));
} else {
callback.callbackMethod(null);
}
}
});
}
}
......
package com.sunnni.smartdoorlock.api;
package com.sunnni.smartdoorlock.data;
public class Auth {
private boolean isAvailable;
......
package com.sunnni.smartdoorlock.data;
public class Device {
public String deviceNumber;
public String registerDate;
private int deviceId;
private String RFIDId;
private String created;
public Device(String number, String date){
this.deviceNumber = number;
this.registerDate = date;
public Device(int deviceId, String RFIDId, String created){
this.deviceId = deviceId;
this.RFIDId = RFIDId;
this.created = created;
}
public String getCreated() {
return created;
}
public int getDeviceId() {
return deviceId;
}
public String getRFIDId() {
return RFIDId;
}
}
......
package com.sunnni.smartdoorlock.data;
public class RemoteRecord {
public String deviceName;
public String remoteDate;
private String deviceName;
private String created;
public RemoteRecord(String name, String date){
this.deviceName = name;
this.remoteDate = date;
public RemoteRecord(String deviceName, String created){
this.deviceName = deviceName;
this.created = created;
}
public String getDeviceName() {
return deviceName;
}
public String getCreated() {
return created;
}
}
......
package com.sunnni.smartdoorlock.api;
package com.sunnni.smartdoorlock.data;
public class Setting {
private boolean recording;
......
package com.sunnni.smartdoorlock.data;
public class Video {
private String vidName;
private String thumb;
private String created;
private String s3link;
public Video(String vidName, String thumb, String created) {
this.vidName = vidName;
this.thumb = thumb;
this.created = created;
}
public void setS3link(String s3link) {
this.s3link = s3link;
}
public String getCreated() {
return created;
}
public String getS3link() {
return s3link;
}
public String getThumb() {
return thumb;
}
public String getVidName() {
return vidName;
}
}
......@@ -9,17 +9,22 @@ import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.ScrollView;
import android.widget.Toast;
import com.sunnni.smartdoorlock.R;
import com.sunnni.smartdoorlock.api.Api;
import com.sunnni.smartdoorlock.data.Device;
import com.sunnni.smartdoorlock.data.RemoteRecord;
import java.util.ArrayList;
import java.util.Objects;
import static android.view.InputDevice.getDevice;
public class DeviceManagerActivity extends AppCompatActivity {
ArrayList<Device> mList = new ArrayList<Device>();
......@@ -37,7 +42,7 @@ public class DeviceManagerActivity extends AppCompatActivity {
setToolbar(mToolbar);
setRecyclerView();
setDeviceList();
getDevice();
init();
}
......@@ -78,26 +83,21 @@ public class DeviceManagerActivity extends AppCompatActivity {
mRecyclerView.setAdapter(mAdapter);
}
// 기기 목록 dummy data -> api 생성되면 수정
private void setDeviceList(){
Device temp;
mList.add(temp = new Device("0047617826460", "2020.10.08 17:21:30"));
mList.add(temp = new Device("0047617826460", "2020.10.08 17:21:30"));
mList.add(temp = new Device("0047617826460", "2020.10.08 17:21:30"));
mList.add(temp = new Device("0047617826460", "2020.10.08 17:21:30"));
mList.add(temp = new Device("0047617826460", "2020.10.08 17:21:30"));
mList.add(temp = new Device("0047617826460", "2020.10.08 17:21:30"));
mList.add(temp = new Device("0047617826460", "2020.10.08 17:21:30"));
mList.add(temp = new Device("0047617826460", "2020.10.08 17:21:30"));
mList.add(temp = new Device("0047617826460", "2020.10.08 17:21:30"));
mList.add(temp = new Device("0047617826460", "2020.10.08 17:21:30"));
mList.add(temp = new Device("0047617826460", "2020.10.08 17:21:30"));
mList.add(temp = new Device("0047617826460", "2020.10.08 17:21:30"));
mList.add(temp = new Device("0047617826460", "2020.10.08 17:21:30"));
mList.add(temp = new Device("0047617826460", "2020.10.08 17:21:30"));
mList.add(temp = new Device("0047617826460", "2020.10.08 17:21:30"));
mAdapter.notifyDataSetChanged();
public void getDevice() {
Api.getDevices(new Api.Callback() {
@Override
public void callbackMethod(Object obj) {
if(obj == null) {
Toast.makeText(getApplicationContext(), "연결 상태가 불안정합니다.", Toast.LENGTH_SHORT).show();
startActivity(new Intent(DeviceManagerActivity.this, MainActivity.class));
return;
} else {
mList.clear();
mList.addAll(0, (ArrayList<Device>) obj);
mAdapter.notifyDataSetChanged();
}
}
});
}
private void remoteControlDialog() {
......@@ -107,7 +107,18 @@ public class DeviceManagerActivity extends AppCompatActivity {
builder.setPositiveButton("추가", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(DeviceManagerActivity.this, "도어락에 기기를 태그해주세요.", Toast.LENGTH_LONG).show();
Api.requestAddDevice(new Api.Callback() {
@Override
public void callbackMethod(Object obj) {
if(obj == null) {
Toast.makeText(getApplicationContext(), "연결 상태가 불안정합니다.", Toast.LENGTH_SHORT).show();
startActivity(new Intent(DeviceManagerActivity.this, MainActivity.class));
return;
} else {
Toast.makeText(DeviceManagerActivity.this, "도어락에 기기를 태그해주세요.", Toast.LENGTH_LONG).show();
}
}
});
}
});
builder.setNegativeButton("취소", new DialogInterface.OnClickListener() {
......
package com.sunnni.smartdoorlock.ui;
import android.content.DialogInterface;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
......@@ -14,6 +15,7 @@ import androidx.core.content.res.ResourcesCompat;
import androidx.recyclerview.widget.RecyclerView;
import com.sunnni.smartdoorlock.R;
import com.sunnni.smartdoorlock.api.Api;
import com.sunnni.smartdoorlock.data.Device;
import java.util.ArrayList;
......@@ -33,9 +35,9 @@ public class DeviceRecyclerViewAdapter extends RecyclerView.Adapter<DeviceRecycl
this.mTrashcan = v.findViewById(R.id.img_trashcan);
}
void bind(Device device) {
mTvDeviceNum.setText(device.deviceNumber);
mTvRegisterDate.setText(device.registerDate);
void bind(final Device device) {
mTvDeviceNum.setText(device.getRFIDId());
mTvRegisterDate.setText(device.getCreated());
mTrashcan.setOnClickListener(new View.OnClickListener() {
@Override
......@@ -46,7 +48,19 @@ public class DeviceRecyclerViewAdapter extends RecyclerView.Adapter<DeviceRecycl
builder.setPositiveButton("삭제", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(itemView.getContext(), "삭제되었습니다.", Toast.LENGTH_SHORT).show();
Api.removeDevice(device, new Api.Callback() {
@Override
public void callbackMethod(Object obj) {
if(obj == null) {
Toast.makeText(itemView.getContext(), "연결 상태가 불안정합니다.", Toast.LENGTH_SHORT).show();
return;
} else {
Toast.makeText(itemView.getContext(), "삭제되었습니다.", Toast.LENGTH_LONG).show();
// TODO : 목록 refresh
// DeviceManagerActivity.getDevices 를 호출하거나 DeviceManagerActivity.mList에서 device 제거
}
}
});
}
});
builder.setNegativeButton("취소", new DialogInterface.OnClickListener() {
......
......@@ -22,6 +22,7 @@ import android.widget.Toast;
import com.google.android.material.navigation.NavigationView;
import com.sunnni.smartdoorlock.R;
import com.sunnni.smartdoorlock.api.Api;
import java.util.Objects;
......@@ -220,8 +221,17 @@ public class MainActivity extends AppCompatActivity {
builder.setPositiveButton("열기", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// 원격 해제 구현 부분
Toast.makeText(MainActivity.this, "도어락이 열렸습니다.", Toast.LENGTH_SHORT).show();
Api.requestRemote(new Api.Callback() {
@Override
public void callbackMethod(Object obj) {
if(obj == null) {
Toast.makeText(getApplicationContext(),"연결 상태가 불안정합니다.",Toast.LENGTH_SHORT).show();
return;
} else {
Toast.makeText(MainActivity.this, "도어락이 열렸습니다.", Toast.LENGTH_SHORT).show();
}
}
});
}
});
builder.setNegativeButton("취소", new DialogInterface.OnClickListener() {
......
......@@ -7,12 +7,15 @@ import androidx.core.widget.NestedScrollView;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.content.Intent;
import android.os.Bundle;
import android.telecom.Call;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.Toast;
import com.sunnni.smartdoorlock.R;
import com.sunnni.smartdoorlock.api.Api;
import com.sunnni.smartdoorlock.data.Device;
import com.sunnni.smartdoorlock.data.RemoteRecord;
......@@ -34,7 +37,20 @@ public class RemoteControlRecordActivity extends AppCompatActivity {
setToolbar(mToolbar);
setRecyclerView();
setRecordList();
Api.getRemotes(new Api.Callback() {
@Override
public void callbackMethod(Object obj) {
if(obj == null) {
Toast.makeText(getApplicationContext(), "연결 상태가 불안정합니다.", Toast.LENGTH_SHORT).show();
startActivity(new Intent(RemoteControlRecordActivity.this, MainActivity.class));
return;
} else {
mRecordList.clear();
mRecordList.addAll(0, (ArrayList<RemoteRecord>) obj);
mAdapter.notifyDataSetChanged();
}
}
});
init();
}
......@@ -66,24 +82,4 @@ public class RemoteControlRecordActivity extends AppCompatActivity {
mRecyclerView.setLayoutManager(manager);
mRecyclerView.setAdapter(mAdapter);
}
private void setRecordList(){
RemoteRecord temp;
mRecordList.add(temp = new RemoteRecord("Galaxy Note 10", "2020.10.07(수) 17:50:00"));
mRecordList.add(temp = new RemoteRecord("Galaxy Note 10", "2020.10.07(수) 17:50:00"));
mRecordList.add(temp = new RemoteRecord("Galaxy Note 10", "2020.10.07(수) 17:50:00"));
mRecordList.add(temp = new RemoteRecord("Galaxy Note 10", "2020.10.07(수) 17:50:00"));
mRecordList.add(temp = new RemoteRecord("Galaxy Note 10", "2020.10.07(수) 17:50:00"));
mRecordList.add(temp = new RemoteRecord("Galaxy Note 10", "2020.10.07(수) 17:50:00"));
mRecordList.add(temp = new RemoteRecord("Galaxy Note 10", "2020.10.07(수) 17:50:00"));
mRecordList.add(temp = new RemoteRecord("Galaxy Note 10", "2020.10.07(수) 17:50:00"));
mRecordList.add(temp = new RemoteRecord("Galaxy Note 10", "2020.10.07(수) 17:50:00"));
mRecordList.add(temp = new RemoteRecord("Galaxy Note 10", "2020.10.07(수) 17:50:00"));
mRecordList.add(temp = new RemoteRecord("Galaxy Note 10", "2020.10.07(수) 17:50:00"));
mRecordList.add(temp = new RemoteRecord("Galaxy Note 10", "2020.10.07(수) 17:50:00"));
mRecordList.add(temp = new RemoteRecord("Galaxy Note 10", "2020.10.07(수) 17:50:00"));
mRecordList.add(temp = new RemoteRecord("Galaxy Note 10", "2020.10.07(수) 17:50:00"));
mAdapter.notifyDataSetChanged();
}
}
......
......@@ -29,8 +29,8 @@ public class RemoteRecordRvAdapter extends RecyclerView.Adapter<RemoteRecordRvAd
}
void bind(RemoteRecord record){
mTvDeviceName.setText(record.deviceName);
mTvRemoteDate.setText(record.remoteDate);
mTvDeviceName.setText(record.getDeviceName());
mTvRemoteDate.setText(record.getCreated());
}
}
......
......@@ -12,7 +12,7 @@ import android.widget.Toast;
import com.sunnni.smartdoorlock.R;
import com.sunnni.smartdoorlock.api.Api;
import com.sunnni.smartdoorlock.api.Setting;
import com.sunnni.smartdoorlock.data.Setting;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
......
......@@ -8,12 +8,9 @@ import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Toast;
......@@ -22,7 +19,7 @@ import com.google.android.material.textfield.TextInputEditText;
import com.google.android.material.textfield.TextInputLayout;
import com.sunnni.smartdoorlock.R;
import com.sunnni.smartdoorlock.api.Api;
import com.sunnni.smartdoorlock.api.Auth;
import com.sunnni.smartdoorlock.data.Auth;
public class SplashActivity extends AppCompatActivity {
......
......@@ -3,15 +3,26 @@ package com.sunnni.smartdoorlock.ui;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import com.sunnni.smartdoorlock.R;
import com.sunnni.smartdoorlock.api.Api;
import com.sunnni.smartdoorlock.data.RemoteRecord;
import com.sunnni.smartdoorlock.data.Video;
import java.util.ArrayList;
import java.util.Objects;
public class VideoCheckActivity extends AppCompatActivity {
ArrayList<Video> mVideoList = new ArrayList<Video>();
Button mBtnRemoveVideo;
Button mBtnViewVideo;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
......@@ -19,6 +30,61 @@ public class VideoCheckActivity extends AppCompatActivity {
Toolbar mToolbar = findViewById(R.id.toolbar_video_check);
setToolbar(mToolbar);
mBtnRemoveVideo = (Button) findViewById(R.id.btn_remove_video);
mBtnViewVideo = (Button) findViewById(R.id.btn_view_video);
getVideos();
mBtnRemoveVideo.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// TODO : 삭제 버튼이 클릭되었을 때
// 원래는 각 비디오에 대해서 동작해야 함. 코드 의미 전달을 위해 video[0]에 대해 삭제하는 코드만 구현
Api.removeVideo(mVideoList.get(0), new Api.Callback() {
@Override
public void callbackMethod(Object obj) {
if(obj == null) {
Toast.makeText(getApplicationContext(), "연결 상태가 불안정합니다.", Toast.LENGTH_SHORT).show();
startActivity(new Intent(VideoCheckActivity.this, MainActivity.class));
return;
} else {
// 삭제가 완료되었으므로 비디오 리스트 다시 조회
// (또는 해당 비디오만 삭제하고 notifyDataSetChanged)
getVideos();
}
}
});
}
});
mBtnViewVideo.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// TODO : 비디오가 클릭되었을 때 (비디오 재생)
// 원래는 각 비디오에 대해서 동작해야 함. 코드 의미 전달을 위해 video[0]에 대해 재생하는 코드만 구현
final Video video = mVideoList.get(0);
// s3 링크를 받아오지 못한 경우에만 조회. 이미 받아온 경우 바로 해당 링크로 재생
if(video.getS3link() == null) {
Api.getVideo(mVideoList.get(0), new Api.Callback() {
@Override
public void callbackMethod(Object obj) {
if (obj == null) {
Toast.makeText(getApplicationContext(), "연결 상태가 불안정합니다.", Toast.LENGTH_SHORT).show();
startActivity(new Intent(VideoCheckActivity.this, MainActivity.class));
return;
} else {
String s3link = (String) obj;
video.setS3link(s3link);
// TODO : 비디오 재생 코드 구현 (video.setS3link를 통해)
}
}
});
} else {
// TODO : 비디오 재생 코드 구현 (video.setS3link를 통해)
}
}
});
}
private void setToolbar(Toolbar toolbar){
......@@ -35,4 +101,22 @@ public class VideoCheckActivity extends AppCompatActivity {
}
});
}
private void getVideos() {
Api.getVideos(new Api.Callback() {
@Override
public void callbackMethod(Object obj) {
// TODO : 비디오 리스트가 로드되었을 때
if(obj == null) {
Toast.makeText(getApplicationContext(), "연결 상태가 불안정합니다.", Toast.LENGTH_SHORT).show();
startActivity(new Intent(VideoCheckActivity.this, MainActivity.class));
return;
} else {
mVideoList.clear();
mVideoList.addAll(0, (ArrayList<Video>) obj);
//mAdapter.notifyDataSetChanged();
}
}
});
}
}
......
......@@ -26,4 +26,26 @@
</androidx.appcompat.widget.Toolbar>
<Button
android:id="@+id/btn_remove_video"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="563dp"
android:layout_marginStart="100dp"
android:text="btn_remove_video"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/toolbar_video_check" />
<Button
android:id="@+id/btn_view_video"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="504dp"
android:layout_marginStart="6dp"
android:text="btn_view_video"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="@+id/btn_remove_video"
app:layout_constraintTop_toBottomOf="@+id/toolbar_video_check" />
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
......