Merge branch 'feature/nutritionix-api-integration' of s407312/photoeat into master
This commit is contained in:
commit
49db39ff8b
@ -20,6 +20,16 @@ android {
|
||||
sourceCompatibility = '1.8'
|
||||
targetCompatibility = '1.8'
|
||||
}
|
||||
packagingOptions {
|
||||
exclude 'META-INF/DEPENDENCIES'
|
||||
exclude 'META-INF/LICENSE'
|
||||
exclude 'META-INF/LICENSE.txt'
|
||||
exclude 'META-INF/license.txt'
|
||||
exclude 'META-INF/NOTICE'
|
||||
exclude 'META-INF/NOTICE.txt'
|
||||
exclude 'META-INF/notice.txt'
|
||||
exclude 'META-INF/ASL2.0'
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
@ -32,4 +42,7 @@ dependencies {
|
||||
implementation 'com.android.support:cardview-v7:26.1.0'
|
||||
implementation 'com.android.support:recyclerview-v7:26.1.0'
|
||||
implementation 'com.ibm.watson.developer_cloud:java-sdk:6.9.0'
|
||||
// https://mvnrepository.com/artifact/com.google.http-client/google-http-client
|
||||
implementation 'com.google.http-client:google-http-client:1.27.0'
|
||||
|
||||
}
|
||||
|
@ -31,6 +31,7 @@
|
||||
</provider>
|
||||
|
||||
<activity android:name=".ArchiveActivity" android:label="@string/archive"></activity>
|
||||
<activity android:name=".TestNutritionixActivity" android:label="Nutritionix"></activity>
|
||||
</application>
|
||||
|
||||
</manifest>
|
@ -3,6 +3,8 @@ package com.krokogator.photoeat;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Matrix;
|
||||
import android.media.ExifInterface;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
@ -14,7 +16,9 @@ import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
@ -25,6 +29,8 @@ public class MainActivity extends AppCompatActivity {
|
||||
|
||||
ImageView photo_preview;
|
||||
|
||||
File newFile;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
@ -32,6 +38,7 @@ public class MainActivity extends AppCompatActivity {
|
||||
|
||||
Button btnCamera = (Button) findViewById(R.id.button_take_photo);
|
||||
Button btnArchive = (Button) findViewById(R.id.button_archive);
|
||||
Button btnNutritionix = (Button) findViewById(R.id.button_nutritionix);
|
||||
|
||||
btnCamera.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
@ -47,6 +54,11 @@ public class MainActivity extends AppCompatActivity {
|
||||
startActivity(intent);
|
||||
});
|
||||
|
||||
btnNutritionix.setOnClickListener((view) -> {
|
||||
Intent intent = new Intent(this, TestNutritionixActivity.class);
|
||||
startActivity(intent);
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -87,15 +99,90 @@ public class MainActivity extends AppCompatActivity {
|
||||
"com.krokogator.photoeat.android.fileprovider",
|
||||
photoFile);
|
||||
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
|
||||
newFile = photoFile;
|
||||
startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void resize(String imagePath){
|
||||
File dir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
|
||||
Bitmap b = BitmapFactory.decodeFile(imagePath);
|
||||
b = getCorrectlyRotated(imagePath, b);
|
||||
Bitmap out = resize(b, 320, 320);
|
||||
|
||||
File file = new File(dir, newFile.getName());
|
||||
FileOutputStream fOut;
|
||||
try {
|
||||
fOut = new FileOutputStream(file);
|
||||
out.compress(Bitmap.CompressFormat.JPEG, 100, fOut);
|
||||
fOut.flush();
|
||||
fOut.close();
|
||||
b.recycle();
|
||||
out.recycle();
|
||||
} catch (Exception e) {}
|
||||
}
|
||||
|
||||
private Bitmap getCorrectlyRotated(String imagePath, Bitmap bitmap) {
|
||||
// Rotate Image if Needed
|
||||
try {
|
||||
// Determine Orientation
|
||||
ExifInterface exif = new ExifInterface(imagePath);
|
||||
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1);
|
||||
|
||||
// Determine Rotation
|
||||
int rotation = 0;
|
||||
if (orientation == 6) rotation = 90;
|
||||
else if (orientation == 3) rotation = 180;
|
||||
else if (orientation == 8) rotation = 270;
|
||||
|
||||
// Rotate Image if Necessary
|
||||
if (rotation != 0) {
|
||||
// Create Matrix
|
||||
Matrix matrix = new Matrix();
|
||||
matrix.postRotate(rotation);
|
||||
|
||||
// Rotate Bitmap
|
||||
Bitmap rotated = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
|
||||
|
||||
// Pretend none of this ever happened!
|
||||
bitmap.recycle();
|
||||
bitmap = rotated;
|
||||
rotated = null;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// TODO: Log Error Messages Here
|
||||
}
|
||||
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
private static Bitmap resize(Bitmap image, int maxWidth, int maxHeight) {
|
||||
if (maxHeight > 0 && maxWidth > 0) {
|
||||
int width = image.getWidth();
|
||||
int height = image.getHeight();
|
||||
float ratioBitmap = (float) width / (float) height;
|
||||
float ratioMax = (float) maxWidth / (float) maxHeight;
|
||||
|
||||
int finalWidth = maxWidth;
|
||||
int finalHeight = maxHeight;
|
||||
if (ratioMax > ratioBitmap) {
|
||||
finalWidth = (int) ((float)maxHeight * ratioBitmap);
|
||||
} else {
|
||||
finalHeight = (int) ((float)maxWidth / ratioBitmap);
|
||||
}
|
||||
image = Bitmap.createScaledBitmap(image, finalWidth, finalHeight, true);
|
||||
return image;
|
||||
} else {
|
||||
return image;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
|
||||
Intent previewPhotoIntent = new Intent(this, PhotoPreviewActivity.class);
|
||||
resize(mCurrentPhotoPath);
|
||||
previewPhotoIntent.putExtra("imagePath", mCurrentPhotoPath);
|
||||
startActivity(previewPhotoIntent);
|
||||
}
|
||||
|
@ -49,8 +49,8 @@ public class PhotoPreviewActivity extends AppCompatActivity {
|
||||
|
||||
private Bitmap getPic(String picPath) {
|
||||
// Get the dimensions of the View
|
||||
int targetW = 800;
|
||||
int targetH = 1200;
|
||||
int targetW = 320;
|
||||
int targetH = 320;
|
||||
|
||||
// Get the dimensions of the bitmap
|
||||
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
|
||||
@ -68,7 +68,7 @@ public class PhotoPreviewActivity extends AppCompatActivity {
|
||||
bmOptions.inPurgeable = true;
|
||||
|
||||
Bitmap bitmap = BitmapFactory.decodeFile(picPath, bmOptions);
|
||||
bitmap = getCorrectlyRotated(picPath, bitmap);
|
||||
//bitmap = getCorrectlyRotated(picPath, bitmap);
|
||||
|
||||
return bitmap;
|
||||
}
|
||||
|
@ -0,0 +1,88 @@
|
||||
package com.krokogator.photoeat;
|
||||
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.google.api.client.http.GenericUrl;
|
||||
import com.google.api.client.http.HttpRequest;
|
||||
import com.google.api.client.http.HttpRequestFactory;
|
||||
import com.google.api.client.http.javanet.NetHttpTransport;
|
||||
import com.krokogator.photoeat.service.NutritionixService;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class TestNutritionixActivity extends AppCompatActivity {
|
||||
|
||||
TextView textView;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_test_nutritionix);
|
||||
|
||||
EditText input = findViewById(R.id.input_nutri_food);
|
||||
|
||||
Button btnSend = findViewById(R.id.button_send);
|
||||
btnSend.setOnClickListener((view) -> {
|
||||
|
||||
//getCalories(input.getText().toString());
|
||||
new NutritionixBackground().execute(input.getText().toString());
|
||||
|
||||
});
|
||||
|
||||
textView = findViewById(R.id.text_output);
|
||||
|
||||
}
|
||||
|
||||
private void getCalories(String input) throws IOException {
|
||||
|
||||
}
|
||||
|
||||
private void setText(String results) {
|
||||
textView.setText(results);
|
||||
}
|
||||
|
||||
private class NutritionixBackground extends AsyncTask<String, Integer, JSONObject> {
|
||||
|
||||
protected JSONObject doInBackground(String... files) {
|
||||
JSONObject out = null;
|
||||
|
||||
NutritionixService service = new NutritionixService();
|
||||
try {
|
||||
out = service.test(files[0]);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
|
||||
// Escape early if cancel() is called
|
||||
if (isCancelled()) return null;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
protected void onPostExecute(JSONObject result) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
try {
|
||||
int length = 0;
|
||||
length = result.getJSONArray("foods").length();
|
||||
for (int i = 0; i < length; i++) {
|
||||
builder.append(result.getJSONArray("foods").getJSONObject(i).getString("food_name"));
|
||||
builder.append(" ");
|
||||
builder.append(result.getJSONArray("foods").getJSONObject(i).getString("nf_calories"));
|
||||
builder.append("kcal \n");
|
||||
}
|
||||
} catch (Exception e){}
|
||||
|
||||
setText(builder.toString());
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
package com.krokogator.photoeat.model;
|
||||
|
||||
import com.google.api.client.json.GenericJson;
|
||||
import com.google.api.client.util.Key;
|
||||
|
||||
public class Food extends GenericJson {
|
||||
@Key
|
||||
String food_name;
|
||||
@Key
|
||||
String nf_calories;
|
||||
|
||||
public String getFood_name() {
|
||||
return food_name;
|
||||
}
|
||||
|
||||
public void setFood_name(String food_name) {
|
||||
this.food_name = food_name;
|
||||
}
|
||||
|
||||
public String getNf_calories() {
|
||||
return nf_calories;
|
||||
}
|
||||
|
||||
public void setNf_calories(String nf_calories) {
|
||||
this.nf_calories = nf_calories;
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package com.krokogator.photoeat.model;
|
||||
|
||||
import com.google.api.client.json.GenericJson;
|
||||
import com.google.api.client.util.Key;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class Output extends GenericJson {
|
||||
@Key
|
||||
private Food[] foods;
|
||||
|
||||
public Food[] getFoods() {
|
||||
return foods;
|
||||
}
|
||||
|
||||
public void setFoods(Food[] foods) {
|
||||
this.foods = foods;
|
||||
}
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
package com.krokogator.photoeat.service;
|
||||
|
||||
import com.google.api.client.http.ByteArrayContent;
|
||||
import com.google.api.client.http.GenericUrl;
|
||||
import com.google.api.client.http.HttpContent;
|
||||
import com.google.api.client.http.HttpHeaders;
|
||||
import com.google.api.client.http.HttpRequest;
|
||||
import com.google.api.client.http.HttpRequestFactory;
|
||||
import com.google.api.client.http.javanet.NetHttpTransport;
|
||||
import com.google.api.client.json.GenericJson;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.krokogator.photoeat.model.Output;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
public class NutritionixService {
|
||||
|
||||
public JSONObject test(String input) throws IOException, JSONException {
|
||||
/**
|
||||
* NUTRITIONIX API CALL
|
||||
*/
|
||||
|
||||
String content = "{\"query\":\"" + input + "\"}";
|
||||
|
||||
|
||||
HttpRequestFactory requestFactory
|
||||
= new NetHttpTransport().createRequestFactory();
|
||||
HttpRequest request = requestFactory.buildPostRequest(
|
||||
new GenericUrl("https://trackapi.nutritionix.com/v2/natural/nutrients"),
|
||||
ByteArrayContent.fromString("application/json", content));
|
||||
|
||||
HttpHeaders headers = request.getHeaders();
|
||||
headers.set("x-app-id", "83ec2635");
|
||||
headers.set("x-app-key", "61c5dbdcecb2da0abd23e3e26b3e2437");
|
||||
|
||||
|
||||
JSONObject jsonResponse = null;
|
||||
try {
|
||||
jsonResponse = new JSONObject(request.execute().parseAsString());
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return jsonResponse;
|
||||
}
|
||||
}
|
@ -39,11 +39,25 @@
|
||||
android:layout_height="94dp"
|
||||
android:layout_marginStart="36dp"
|
||||
android:layout_marginEnd="36dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:backgroundTint="@color/colorAccent"
|
||||
android:text="@string/archive"
|
||||
app:layout_constraintBottom_toTopOf="@+id/button_nutritionix"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/button_nutritionix"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="94dp"
|
||||
android:layout_marginStart="36dp"
|
||||
android:layout_marginEnd="36dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:backgroundTint="@color/colorAccent"
|
||||
android:text="Nutritionix"
|
||||
app:layout_constraintBottom_toTopOf="@+id/button4"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.0"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<Button
|
||||
|
@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<android.support.constraint.ConstraintLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/input_nutri_food"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginTop="32dp"
|
||||
android:ems="10"
|
||||
android:inputType="textPersonName"
|
||||
android:text="Food"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text_output"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginTop="32dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:text="TextView"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/input_nutri_food" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/button_send"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="32dp"
|
||||
android:text="Send"
|
||||
app:layout_constraintStart_toEndOf="@+id/input_nutri_food"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
</android.support.constraint.ConstraintLayout>
|
Loading…
Reference in New Issue
Block a user