· 6 years ago · Sep 18, 2019, 09:04 AM
1package com.repoai.myhome.Devices;
2
3import androidx.annotation.NonNull;
4import androidx.annotation.Nullable;
5import androidx.appcompat.app.AlertDialog;
6import androidx.appcompat.app.AppCompatActivity;
7import androidx.core.app.ActivityCompat;
8import androidx.core.content.ContextCompat;
9
10import android.Manifest;
11import android.content.Context;
12import android.content.DialogInterface;
13import android.content.Intent;
14import android.content.pm.PackageManager;
15import android.graphics.Bitmap;
16import android.graphics.BitmapFactory;
17import android.graphics.Matrix;
18import android.media.ExifInterface;
19import android.net.Uri;
20import android.os.Bundle;
21import android.os.Environment;
22import android.os.StrictMode;
23import android.provider.MediaStore;
24import android.util.Log;
25import android.view.LayoutInflater;
26import android.view.View;
27import android.widget.AdapterView;
28import android.widget.ImageButton;
29import android.widget.ImageView;
30import android.widget.ListView;
31import android.widget.TextView;
32import android.widget.Toast;
33
34import com.backendless.Backendless;
35import com.backendless.async.callback.AsyncCallback;
36import com.backendless.exceptions.BackendlessFault;
37import com.backendless.files.BackendlessFile;
38import com.backendless.persistence.DataQueryBuilder;
39import com.repoai.myhome.R;
40import com.repoai.myhome.Rooms.Rooms;
41import com.sdsmdg.tastytoast.TastyToast;
42import com.squareup.picasso.Picasso;
43
44import java.io.File;
45import java.io.IOException;
46import java.util.ArrayList;
47import java.util.HashMap;
48import java.util.List;
49import java.util.Map;
50import java.util.UUID;
51
52public class DeviceList extends AppCompatActivity {
53 Context context;
54 List<Devices> deviceList;
55 List<DeviceTypes> deviceTypesList;
56 ListView myDeviceList;
57 String roomName;
58 ImageButton imageButton;
59 boolean hasCamera = false;
60 String fileName;
61 String roomUUID;
62 Rooms myRoom;
63
64 @Override
65 protected void onCreate(Bundle savedInstanceState) {
66 super.onCreate(savedInstanceState);
67 setContentView(R.layout.activity_device_list);
68 this.roomName = getIntent().getStringExtra("roomName");
69 this.roomUUID = getIntent().getStringExtra("roomUUID");
70 setPointer();
71 setMyDevices();
72 //getData();
73 getPermissions();
74 }
75
76 private void getPermissions() {
77 List<String> listPermissionNeeded = new ArrayList<>();
78 //check if we have permission
79 int camPerm = ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA);
80 int writePerm = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
81 int readPerm = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE);
82 if (camPerm != PackageManager.PERMISSION_GRANTED) {
83 listPermissionNeeded.add(Manifest.permission.CAMERA);
84 }
85 if (writePerm != PackageManager.PERMISSION_GRANTED) {
86 listPermissionNeeded.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
87 }
88 if (readPerm != PackageManager.PERMISSION_GRANTED) {
89 listPermissionNeeded.add(Manifest.permission.READ_EXTERNAL_STORAGE);
90 }
91 if (listPermissionNeeded.isEmpty()) {
92 hasCamera = true;
93 } else {
94 ActivityCompat.requestPermissions(this, listPermissionNeeded.toArray(new String[listPermissionNeeded.size()]), 100);
95 }
96 }
97
98 @Override
99 public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
100 if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
101 //fire the camera dispatch
102 hasCamera = true;
103 } else {
104 Toast.makeText(context, "you need to grant all permissions", Toast.LENGTH_SHORT).show();
105 }
106 }
107
108 private void getData() {
109 String whereClause = "objectId = '"+this.roomUUID+"'";
110 DataQueryBuilder queryBuilder = DataQueryBuilder.create();
111 queryBuilder.setWhereClause( whereClause );
112 queryBuilder.setPageSize(100);
113
114 Backendless.Data.of(Rooms.class).find(queryBuilder, new AsyncCallback<List<Rooms>>() {
115 @Override
116 public void handleResponse(List<Rooms> response) {
117 myRoom = response.get(0);
118 deviceList = myRoom.getDevices();
119 if (!myRoom.getImageUrl().equals("na")){
120 Picasso.get().load(myRoom.getImageUrl()).into((ImageView)findViewById(R.id.roomImage));
121
122 }
123 if (deviceList == null){
124 deviceList = new ArrayList<>();
125 }
126 DeviceAdapter adapter = new DeviceAdapter(context, deviceList);
127 myDeviceList.setAdapter(adapter);
128 }
129
130 @Override
131 public void handleFault(BackendlessFault fault) {
132 TastyToast.makeText(context, fault.getMessage(), TastyToast.LENGTH_LONG, TastyToast.ERROR).show();
133 }
134 });
135
136
137 }
138
139
140 private void setPointer() {
141
142 this.context = this;
143 setMyDevices();
144 myDeviceList = findViewById(R.id.lstDevices);
145 ((TextView) findViewById(R.id.devicesRoomName)).setText(this.roomName);
146 findViewById(R.id.addDevice).setOnClickListener(view -> addNewDeviceDialog());
147 findViewById(R.id.imageButton).setOnClickListener(new View.OnClickListener() {
148 @Override
149 public void onClick(View view) {
150 if (hasCamera) {
151 takePhoto();
152 } else {
153 TastyToast.makeText(context, "We dont have camera permissions", TastyToast.LENGTH_LONG, TastyToast.CONFUSING).show();
154 getPermissions();
155 }
156 }
157 });
158 getData();
159 }
160
161 public void takePhoto() {
162 //to avoid api26 policy restrictions.
163 StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
164 StrictMode.setVmPolicy(builder.build());
165 //we call the android image capture
166 Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
167 //we creating a filename so we can use it later on and put the picture inside the imageView
168 fileName = Environment.getExternalStorageDirectory() + File.separator + UUID.randomUUID().toString() + ".jpg";
169 File file = new File(fileName);
170 //we setting a global pointer to the file location
171 intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
172 //since it can create exception, we surroud it with try/catch block to avoid exception and application crash
173 try {
174 startActivityForResult(intent, 200);
175 } catch (Exception e) {
176 Log.e("camera", "dispatchTakeImageIntent: error in dispatch camera");
177 }
178 }
179
180 private void setMyDevices() {
181 deviceTypesList = new ArrayList<>();
182 deviceTypesList.add(new DeviceTypes("TV", R.drawable.tv));
183 deviceTypesList.add(new DeviceTypes("Curtain", R.drawable.curtain));
184 deviceTypesList.add(new DeviceTypes("Light", R.drawable.light));
185 deviceTypesList.add(new DeviceTypes("Boiler", R.drawable.boiler));
186 deviceTypesList.add(new DeviceTypes("Air Condition", R.drawable.aircondition));
187
188 }
189
190 private void addNewDeviceDialog() {
191 AlertDialog.Builder builder = new AlertDialog.Builder(context);
192 builder.setTitle("Add Device to the Room");
193 //create the view for the alert dialog
194 View myView = LayoutInflater.from(context).inflate(R.layout.new_device_list, null);
195 //create the view
196 ListView myDevicesTypeList = myView.findViewById(R.id.deviceTypeList);
197 DeviceTypesAdapter myAdapter = new DeviceTypesAdapter(context, deviceTypesList);
198 myDevicesTypeList.setAdapter(myAdapter);
199
200 //create the builder
201 builder.setView(myView);
202 builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
203 @Override
204 public void onClick(DialogInterface dialogInterface, int i) {
205 dialogInterface.dismiss();
206 }
207 });
208 final AlertDialog deviceDialog = builder.create();
209 deviceDialog.show();
210
211 //handle on item click
212 myDevicesTypeList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
213 @Override
214 public void onItemClick(AdapterView<?> adapterView, View view, int index, long l) {
215 //deviceDialog.dismiss();
216 //Log.e("item", "onItemClick: " + deviceList.get(index).getDeviceName());
217 //add device by type:
218 Devices newDevice = new Devices();
219 switch (index) {
220 case 0:
221 newDevice.setDeviceName("Tv");
222 newDevice.setDeviceIcon(R.drawable.tv);
223 break;
224 case 1:
225 newDevice.setDeviceName("Curtain");
226 newDevice.setDeviceIcon(R.drawable.curtain);
227 break;
228
229 case 2:
230 newDevice.setDeviceName("Light");
231 newDevice.setDeviceIcon(R.drawable.light);
232 //deviceList.add(new Devices("Light"));
233 break;
234
235 case 3:
236 newDevice.setDeviceName("Boiler");
237 newDevice.setDeviceIcon(R.drawable.boiler);
238 break;
239
240 case 4:
241 newDevice.setDeviceName("Air Condition");
242 newDevice.setDeviceIcon(R.drawable.aircondition);
243 break;
244
245 case 5: //TV type:5 mode:X ch:XXX vol:XXX output:X time:XXXX day:X
246
247 break;
248 }
249 newDevice.saveAsync(new AsyncCallback<Devices>() {
250 @Override
251 public void handleResponse(Devices response) {
252 TastyToast.makeText(context, "Device list was update", TastyToast.LENGTH_LONG, TastyToast.SUCCESS).show();
253 //create an hash map to identify objects by key and value.
254 HashMap<String, Object> parentObject = new HashMap<>();
255 //insert the parent into the hashmap
256 parentObject.put("objectId", getIntent().getStringExtra("roomUUID"));
257
258 //create hash map for child
259 HashMap<String, Object> childObject = new HashMap<>();
260 //put child into hash map
261 childObject.put("objectId", response.getObjectId());
262
263 //we need to put one object, but we choose 1:N, simply create an array list
264 ArrayList<Map> children = new ArrayList<>();
265 children.add(childObject);
266
267 Backendless.Data.of("Rooms").addRelation(parentObject, "devices", children, new AsyncCallback<Integer>() {
268 @Override
269 public void handleResponse(Integer response) {
270 Log.e("relation", "handleResponse: " + response.toString());
271 }
272
273 @Override
274 public void handleFault(BackendlessFault fault) {
275 TastyToast.makeText(context, "Error", TastyToast.LENGTH_LONG, TastyToast.ERROR).show();
276 Log.e("relation", "handleFault: " + fault.getDetail());
277 }
278 });
279 }
280
281 @Override
282 public void handleFault(BackendlessFault fault) {
283 TastyToast.makeText(context, "Error in updating", TastyToast.LENGTH_LONG, TastyToast.CONFUSING).show();
284
285 }
286 });
287
288 deviceDialog.dismiss();
289 deviceList.add(newDevice);
290 DeviceAdapter adapter = new DeviceAdapter(context, deviceList);
291 myDeviceList.setAdapter(adapter);
292
293 }
294 });
295
296 }
297
298 @Override
299 protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
300 super.onActivityResult(requestCode, resultCode, data);
301 if (requestCode == 200) {
302 try {
303 //get our saved file into a bitmap object
304 Log.e("file", "onActivityResult: " + fileName);
305 final File file = new File(fileName);
306
307 //read the image from the file and convert it to bitmap
308 Bitmap myBitmap = BitmapFactory.decodeFile(fileName);
309
310 //get exif data (extra information) from the image so we will know the oriention of the image
311 ExifInterface exif = null;
312 try {
313 exif = new ExifInterface(fileName);
314 } catch (IOException e) {
315 e.printStackTrace();
316 }
317
318 assert exif != null;
319 //get the image orienation
320 int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED);
321 //we will rotate the image with method
322 Bitmap bm = rotateImage(myBitmap, orientation);
323 //myImage.setImageBitmap(bm);
324 ((ImageView) findViewById(R.id.roomImage)).setImageBitmap(bm);
325 //save new image to backendless
326 Backendless.Files.Android.upload(bm, Bitmap.CompressFormat.JPEG, 100, roomName + ".jpg", "rooms", new AsyncCallback<BackendlessFile>() {
327 @Override
328 public void handleResponse(BackendlessFile response) {
329 Log.e("image", "handleResponse: " + response.getFileURL());
330 myRoom.setImageUrl(response.getFileURL());
331 myRoom.saveAsync(new AsyncCallback<Rooms>() {
332 @Override
333 public void handleResponse(Rooms response) {
334 Log.e("img", "handleResponse: updated" );
335 }
336
337 @Override
338 public void handleFault(BackendlessFault fault) {
339 Log.e("img", "handleFault: "+fault.getDetail() );
340 }
341 });
342 }
343
344 @Override
345 public void handleFault(BackendlessFault fault) {
346
347 }
348 });
349 } catch (Exception e) {
350 e.printStackTrace();
351 }
352 }
353 }
354
355 private Bitmap rotateImage(Bitmap myBitmap, int orientation) {
356 //we create a matrix, so we can put the image on it and just rotate
357 //it will be faster then copy pixel by pixel
358 Matrix matrix = new Matrix();
359 //depending on the orientation that we got from the exif we will rotate
360 //in this sample we will deall with all kind of rotating from api 15 to api 29
361 switch (orientation) {
362 case ExifInterface.ORIENTATION_NORMAL:
363 //all is o.k. no need to rotate just return the image
364 break;
365 case ExifInterface.ORIENTATION_FLIP_HORIZONTAL:
366 //flip the matrix horzintal
367 matrix.setScale(-1, 1);
368 break;
369 case ExifInterface.ORIENTATION_ROTATE_180:
370 //rotate the matrix 180 degress
371 matrix.setRotate(180);
372 break;
373 case ExifInterface.ORIENTATION_FLIP_VERTICAL:
374 //flip the matrix vertical
375 matrix.setRotate(180);
376 matrix.postScale(-1, 1);
377 break;
378 case ExifInterface.ORIENTATION_TRANSPOSE:
379 //rotate 90 degress and flip
380 matrix.setRotate(90);
381 matrix.postScale(-1, 1);
382 break;
383 case ExifInterface.ORIENTATION_ROTATE_90:
384 //rotate 90 degress and flip
385 matrix.setRotate(90);
386 break;
387 case ExifInterface.ORIENTATION_TRANSVERSE:
388 //rotate 90 degress to other side and flip
389 matrix.setRotate(-90);
390 matrix.postScale(-1, 1);
391 break;
392 case ExifInterface.ORIENTATION_ROTATE_270:
393 //rotate 90 degres to other side
394 matrix.setRotate(-90);
395 break;
396 default:
397 return myBitmap;
398 }
399 try {
400 //create an image from our rotated matrix
401 Bitmap bmRotated = Bitmap.createBitmap(myBitmap, 0, 0, myBitmap.getWidth(), myBitmap.getHeight(), matrix, true);
402 //recycke the data by calling a garbage collector
403 //in this case, we free memory for big pictures
404 myBitmap.recycle();
405 //return the rotated image
406 return bmRotated;
407 } catch (OutOfMemoryError e) {
408 //if we have a memory leak , we need to know about it
409 e.printStackTrace();
410 return myBitmap;
411 }
412 }
413}