Desarrollo parcial de app para propietarios de mascotas, que puedan logearse e ingresar sus mascotas.
Login: (imagen login)
Permite loggear con email+contraseña, google, facebook.
a.Crear cuenta (imagen login_crear_cuenta)
b.en espera verificación cuenta vía click en link email (solo para loggeo email+contraseña) (imagen login_crear_cuenta_verificacion)
c.obtener ubicación del usuario
Main:
Menu lateral (imagen menu_principal, no guiarse por los textos, es solo para ver el formato), titulo de la app. Se presentan algunos mensajes que permiten
realizar acciones:
a.crear nueva mascota si no hay ninguna
b.seleccionar lat,lgn vía google maps si no estuviese ya establecido
Menu lateral:
a.Mi perfil
b.Mis mascotas
c.Logout
Mi perfil:
Se muestra la foto del usuario (, se permite cambio de foto (solo para loggeo email+contraseña))
+ nombre + ubicación + dirección. Edición de ubicación vía google maps / dirección
Mis mascotas:
Se muestran las mascotas cargadas con su foto.
Posibilidad de ver una mascota particular
o agregar nuevas mascotas.
Mascota particular:
se ve una mascota, con su foto, nombre y fecha de nacimiento, sexo.
Permite modificar, eliminar.
Nueva mascota:
Permite ingresar nuevas mascotas con su foto, nombre y fecha de nacimiento.
Especificaciones:
Login, creación de usuarios
URL: /api/
user_create_account.php
Método: POST
Body: Objeto conteniendo el usuario:
{
"device_name": "Google Android SDK built for x86",
"email": "
usuari48pp3@hotmail.com",
"nombre": "usuario3",
"password": "1234",
"unique_id": "9e751f7a-8ad9-477f-9b0d-c504d5c8b2fk"
}
La creación de usuarios debe incluir el nombre de la plataforma donde se ejecuta, de ser
posible, y debe generar un id único en el dispositivo. Código de ejemplo en java:
public static String Generateguid() {
uuid uuid = uuid.randomUUID();
return uuid.toString();
}
Login, chequeo de usuarios que crearon cuenta vía email+contraseña, para determinar
si hicieron clic en el email de confirmación de cuenta que recibieron
URL: /api/
user_check_account.php?id_propietario=101
Método: GET
Parámetro: id_propietario
Respuesta: 1 para válido, 0 para inválido.
Login, logeo de usuario email+contraseña
URL: /api/
user_login_account.php
Método: POST
Body:
{
"email": "
nuevousuario1000@hotmail.com",
"password": "1234"
}
Respuesta:
Un objeto conteniendo un miembro de enumeración [INVALID_ACCOUNT_PASSWORD,
ACCOUNT_WAITING_FOR_EMAIL_CHECK, VALID] y un objeto propietario.
{
"Response": "VALID",
"propietario": {
"id": "98",
"nombre": "nuevousuario105",
"identificacion_regional": null,
"direccion": null,
"id_region": null,
"nombre_region": null,
"latlng": null,
"telefono": null,
"email": "
nuevousuario107@hotmail.com",
"notas": null,
"tipo_login": "EMAIL",
"valid": "1",
"access_token": "b3b2986922293fb9d9f86cfa21c5e4a2751aed702a7cfc0748577e7d435d07bd",
"photo_url": null
}
}
Mascotas, creación de mascotas:
URL: /api/
insert_mascota.php
Método: POST
Body:
Un array conteniendo un objeto mascota, un objeto que indica quién es el
propietario y un ubjeto que contiene la foto
[
{
"nombre": "Nueva mascota",
"nacimiento": "2020-09-14 00:00:00"
},
{
"id_propietario": 27
},
[
{
"file_extension": ".jpg",
"guid": "1bfc013c-2a46-415d-9e73-df0e3020224a",
"upload_finished": 1
},
{
"file_extension": ".jpg",
"guid": "0051615f-056f-4c34-96e4-7fefb3c17c3b",
"postfix": "_thumb",
"upload_finished": 1
}
]
]
La foto se debe comprimir a jpeg en el dispositivo. Luego codificar los bytes
a String en base 64.
Código en java que puede servir de guía:
public static String imageToString(Bitmap bitmap) {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
bitmap.compress(
Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStream);
byte[] imgBytes = byteArrayOutputStream.toByteArray();
return Base64.encodeToString(imgBytes, Base64.DEFAULT);
}
Mascotas, get de las mascotas del propietario:
URL: /api/
get_mascotas.php?id_propietario=101
Especificaciones para la subida de imágenes:
En la clase que se renderice para mostrar el ingreso de una nueva mascota, añadir una lista
global:
//cada archivo a ser subido tendra un guid unico, en cada getFileGuid se iran almacenando
//en esta lista
private ArrayList<Upload_file> files_guids = new ArrayList<>();
Clase Upload_file:
public class Upload_file {
private String guid;
private String file_base64;
private String file_extension;
private Boolean upload_finished;
private String postfix;
public Upload_file() {
}
public Upload_file(String guid) {
this.guid = guid;
}
public Upload_file(String guid, String file_base64, String file_extension) {
this.guid = guid;
this.file_base64 = file_base64;
this.file_extension = file_extension;
}
public String getGuid() {
return guid;
}
public void setGuid(String guid) {
this.guid = guid;
}
public String getFile_base64() {
return file_base64;
}
public void setFile_base64(String file_base64) {
this.file_base64 = file_base64;
}
public String getFile_extension() {
return file_extension;
}
public void setFile_extension(String file_extension) {
this.file_extension = file_extension;
}
public Boolean getUpload_finished() {
return upload_finished;
}
public void setUpload_finished(Boolean upload_finished) {
this.upload_finished = upload_finished;
}
public String getPostfix() {
return postfix;
}
public void setPostfix(String postfix) {
this.postfix = postfix;
}
}
Al tomar foto o elegir imagen de galeria:
1-Escalar la imagen al 20% de su tamaño original, y comprimir
con una razón del 80% de calidad en jpg:
public static Bitmap CompressBitmap(Bitmap bitmap) {
Bitmap resized = Bitmap.createScaledBitmap(bitmap,(int)(bitmap.getWidth()*0.2), (int)(bitmap.getHeight()*0.2), false);
ByteArrayOutputStream out = new ByteArrayOutputStream();
resized.compress(
Bitmap.CompressFormat.JPEG, 80, out);
Bitmap jpgCoded = BitmapFactory.decodeStream(new ByteArrayInputStream(out.toByteArray()));
return jpgCoded;
}
2-Crear una segunda imagen escalando la anterior de 64 x 64 px
3-Subir ambas imagenes, teniendo en cuenta que la segunda se adjunta con el postfijo "_thumb"
public void uploadImages() {
Upload_file file = getImageGuid();
Upload_file file_thumb = getImageGuid();
file_thumb.setPostfix("_thumb");
if (DoctorVetApp.DEBUGGING) {
Log.i(TAG, "Starting upload: " + file);
Log.i(TAG, "Starting upload: " + file_thumb);
}
DoctorVetApp.getInstance().uploadFile(file.getGuid(), file.getFile_extension(), HelperClass.imageToString(dataFragment.takePictureSupportObject.getImage()), new DoctorVetApp.VolleyCallback() {
@Override
public void onSuccess(Boolean result) {
if (DoctorVetApp.DEBUGGING)
Log.i(TAG, "upload: " + file + " result: " + result.toString());
if (result) {
file.setUpload_finished(true);
}
}
});
DoctorVetApp.getInstance().uploadFile(file_thumb.getGuid(), file.getFile_extension(), HelperClass.imageToString(dataFragment.takePictureSupportObject.getImage_thumb()), new DoctorVetApp.VolleyCallback() {
@Override
public void onSuccess(Boolean result) {
if (DoctorVetApp.DEBUGGING)
Log.i(TAG, "upload: " + file_thumb + " result: " + result.toString());
if (result) {
file_thumb.setUpload_finished(true);
}
}
});
}
protected Upload_file getImageGuid(){
Upload_file file = new Upload_file();
file.setGuid(HelperClass.generateGUID());
file.setFile_extension(".jpg");
files_guids.add(file); //la lista global de subida de archivos
return file;
}
public void uploadFile(String guid, String extension, String file_to_string_base64, @Nullable final VolleyCallback callback) {
//primero el upload_prepare
URL upload_prepareUrl = NetworkUtils.buildUploadPrepareImageUrl();
String guidJsonObject = MySqlGson.getGson().toJson(new Upload_file(guid));
StringRequest stringRequest = new StringRequest(
Request.Method.POST, upload_prepareUrl.toString(),
response -> {
try {
Integer success = Integer.parseInt(response);
if (success == 1) {
if (DoctorVetApp.DEBUGGING) Log.i(tag, "prepare upload: " + guid + " response true");
url uploadurl = networkutils.buildUploadImageUrl();
String fileGuidJsonObject = MySqlGson.getGson().toJson(new Upload_file(guid, file_to_string_base64, extension));
StringRequest stringRequest2 = new StringRequest(
Request.Method.POST, uploadUrl.toString(),
response1 -> {
try {
Integer success2 = Integer.parseInt(response1);
if (success2 == 1) {
if (DoctorVetApp.DEBUGGING) Log.i(TAG, "Imagen subida " + guid);
if (callback != null)
callback.onSuccess(true);
} else {
if (DoctorVetApp.DEBUGGING) Log.i(TAG, "Imagen NO subida " + guid);
if (callback != null)
callback.onSuccess(false);
}
} catch (Exception ex) {
handle_error(ex, ctx, tag, true);
}
},
error -> {
handle_volley_error(error, ctx, tag, false);
if (callback != null)
callback.onSuccess(false);
}
)
{
@Override
public byte[] getBody() {
return fileGuidJsonObject.getBytes();
}
};
addToRequestQueque(stringRequest2);
if (callback != null)
callback.onSuccess(true);
} else {
if (DoctorVetApp.DEBUGGING) Log.i(TAG, "prepare upload: " + guid + " response false");
if (callback != null)
callback.onSuccess(false);
}
} catch (Exception ex) {
handle_error(ex, ctx, tag, true);
}
},
error -> {
handle_volley_error(error, ctx, tag, true);
if (callback != null)
callback.onSuccess(false);
}
)
{
@Override
public byte[] getBody() {
return guidJsonObject.getBytes();
}
};
addToRequestQueque(stringRequest);
}
4-Por último, al registrar la mascota, se debe enviar la lista global
de subida de archivos como un array de objetos. Asegurarse de nunca
parsear las imagenes al miembro file_base64 en este último paso ya que
si no, estaríamos subiendo las imágenes dos veces.
Plazo de Entrega: No definido