所以我一直在研究这段代码,现在尝试将Google Visions应用到我之前的应用程序中,该应用程序显示pixabay的图像然后告诉我照片的标签。我有谷歌视觉应用程序和pixabay应用程序工作就好了。在这个新版本中,它应该为我提供Google Visions找到的标签和标签,但是每当我在传感器上激活UP命令时它都会崩溃。
这是我的代码:
import android.annotation.TargetApi;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.media.MediaPlayer;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Vibrator;
import android.speech.tts.TextToSpeech;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ImageView;
import android.widget.TextView;
import com.google.api.client.extensions.android.http.AndroidHttp;
import com.google.api.client.googleapis.json.GoogleJsonResponseException;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.gson.GsonFactory;
import com.google.api.services.vision.v1.Vision;
import com.google.api.services.vision.v1.VisionRequest;
import com.google.api.services.vision.v1.VisionRequestInitializer;
import com.google.api.services.vision.v1.model.AnnotateImageRequest;
import com.google.api.services.vision.v1.model.BatchAnnotateImagesRequest;
import com.google.api.services.vision.v1.model.BatchAnnotateImagesResponse;
import com.google.api.services.vision.v1.model.EntityAnnotation;
import com.google.api.services.vision.v1.model.Feature;
import com.google.api.services.vision.v1.model.Image;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import static edu.ggc.lutz.recipe.pixabaysamplerwalkthrough.R.id.tvLabels;
import static edu.ggc.lutz.recipe.pixabaysamplerwalkthrough.R.id.tvTags;
public class MainActivity extends AppCompatActivity implements SensorEventListener {
public static final String PIXABAY = "Pixabay";
private ImageView imageView;
private static PixabayQueryResult result;
private String tags;
long numberOfHits;
long selected;
float[] gravity = new float[3];
float[] accel = new float[3];
private static final float ALPHA = 0.80f; // weighing factor used by the low pass filter
private static final String TAG = "OMNI";
private static final float VERTICAL_TOL = 0.3f;
private SensorManager manager;
private long lastUpdate;
private MediaPlayer popPlayer;
private MediaPlayer backgroundPlayer;
private TextToSpeech tts;
private TextView[] tvGravity;
private TextView[] tvAcceleration;
private boolean isDown = false;
private boolean isUp = false;
private static final String CLOUD_VISION_API_KEY = "AIzaSyCt35MZjvD_3ynTbYmeUuBFyMbYrjXUmzs";
private static final String ANDROID_CERT_HEADER = "X-Android-Cert";
private static final String ANDROID_PACKAGE_HEADER = "X-Android-Package";
private static final String TAGgoogle = MainActivity.class.getSimpleName();
private TextView pixtags;
private TextView googlelab;
private String urlString;
private Bitmap bitmapT;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
pixtags= (TextView) findViewById(tvTags);
googlelab= (TextView) findViewById(tvLabels);
/* FloatingActionButton fab = (FloatingActionButton) findViewById(fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
PixabayFetchTask task = new PixabayFetchTask();
String service = "https://pixabay.com/api/";
String key = "5535853-23bc4a5e307cd5d1a5e16ebcc";
String query_params = "&editor_choice=true&safesearch=true&image_type=photo";
String urlString = service + "?key=" + key + query_params;
task.execute(urlString);
}
});*/
imageView= (ImageView) findViewById(R.id.imageView);
tts = new TextToSpeech(this, new TextToSpeech.OnInitListener() {
@Override
public void onInit(int status) {
int result1=0;
if(status == TextToSpeech.SUCCESS) {
result1 = tts.setLanguage(Locale.US);
}
if( result1 == TextToSpeech.LANG_MISSING_DATA || result1== TextToSpeech.LANG_NOT_SUPPORTED){
Log.e("TTS", "This Language is not supported");
}
else
{
Log.e("TTS", "Inizalization Failed");
}
}
});
//////////////////////////
manager = (SensorManager) getSystemService(SENSOR_SERVICE);
lastUpdate = System.currentTimeMillis();
backgroundPlayer = MediaPlayer.create(this, R.raw.mistsoftime4tmono);
//////////////////////////
//callCloudVision("https://pixabay.com/get/eb36b90f2df1053ed95c4518b7494395e67fe7d604b0154892f2c67da7eabc_640.jpg");
}
///////////////////////////////
@Override
protected void onResume() {
super.onResume();
manager.registerListener(this, manager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
SensorManager.SENSOR_DELAY_UI);
backgroundPlayer.start();
}
//////////////////////////////
@Override
protected void onPause() {
super.onPause();
manager.unregisterListener(this);
backgroundPlayer.pause();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
Intent intent = new Intent(this, About.class);
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
startActivity(intent);
return true;
}
return super.onOptionsItemSelected(item);
}
public static long getRandomLong(long minimum, long maximum)
{
return (long) (Math.random()* (maximum- minimum))+ minimum;
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
@Override
public void onSensorChanged(SensorEvent event) {
gravity[0] = lowPass(event.values[0], gravity[0]);
gravity[1] = lowPass(event.values[1], gravity[1]);
gravity[2] = lowPass(event.values[2], gravity[2]);
accel[0] = highPass(event.values[0], accel[0]);
accel[1] = highPass(event.values[1], accel[1]);
accel[2] = highPass(event.values[2], accel[2]);
long actualTime = System.currentTimeMillis();
if (actualTime - lastUpdate > 100) {
if (inRange(gravity[2], -9.81f, VERTICAL_TOL)) {
Log.i(TAG, "Down");
if (!isDown) {
Vibrator v = (Vibrator) this.getApplicationContext().getSystemService(Context.VIBRATOR_SERVICE);
v.vibrate(500);
PixabayFetchTask task = new PixabayFetchTask();
String service = "https://pixabay.com/api/";
String key = "5535853-23bc4a5e307cd5d1a5e16ebcc";
String query_params = "&editor_choice=true&safesearch=true&image_type=photo";
urlString = service + "?key=" + key + query_params;
task.execute(urlString);
backgroundPlayer.setVolume(0.1f, 0.1f);
tts.speak("The device is pointing down", TextToSpeech.QUEUE_FLUSH, null);
backgroundPlayer.setVolume(1.0f, 1.0f);
isDown = true;
isUp = false;
}
} else if (inRange(gravity[2], 9.81f, VERTICAL_TOL)) {
if (!isUp) {
try {
callCloudVision(urlString);
} catch (IOException e) {
e.printStackTrace();
}
backgroundPlayer.setVolume(0.1f, 0.1f);
Log.i(TAG, "Up");
tags= (String) result.getTags((int)selected);
pixtags.setText("Tags: "+tags, null);
/* Snackbar.make(imageView, tags, Snackbar.LENGTH_LONG)
.setAction("Action", null).show();*/
tts.speak(tags.toString(), TextToSpeech.QUEUE_ADD, null);
//tts.speak("up", TextToSpeech.QUEUE_FLUSH, null);
backgroundPlayer.setVolume(1.0f, 1.0f);
isUp = true;
isDown = false;
}
} else {
Log.i(TAG, "In between");
//isDown = false; // Rubbish!
//isUp = false;
}
lastUpdate = actualTime;
}
}
private boolean inRange(float value, float target, float tol) {
return value >= target-tol && value <= target+tol;
}
// de-emphasize transient forces
private float lowPass(float current, float gravity) {
return current * (1-ALPHA) + gravity * ALPHA; // ALPHA indicates the influence of past observations
}
// de-emphasize constant forces
private float highPass(float current, float gravity) {
return current - gravity;
}
class PixabayFetchTask extends AsyncTask<String, Void, PixabayQueryResult> {
/**
* Override this method to perform a computation on a background thread. The
* specified parameters are the parameters passed to {@link #execute}
* by the caller of this task.
* <p>
* This method can call {@link #publishProgress} to publish updates
* on the UI thread.
*
* @param params The parameters of the task.
* @return A result, defined by the subclass of this task.
* @see #onPreExecute()
* @see #onPostExecute
* @see #publishProgress
*/
@Override
protected PixabayQueryResult doInBackground(String... params) {
Log.v(PIXABAY,"String[0] =" + params[0]);
if(result==null || result.isExpired()) {
try {
String line;
URL u = new URL(params[0]);
HttpURLConnection conn = (HttpURLConnection) u.openConnection();
InputStream in = new BufferedInputStream(conn.getInputStream());
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
StringBuilder json = new StringBuilder();
while ((line = reader.readLine()) != null) json.append(line);
result = new PixabayQueryResult(json.toString());
} catch (IOException e) {
e.printStackTrace();
}
}
return result;
}
/**
* <p>Runs on the UI thread after {@link #doInBackground}. The
* specified result is the value returned by {@link #doInBackground}.</p>
* <p>
* <p>This method won't be invoked if the task was cancelled.</p>
*
* @param bitmap The result of the operation computed by {@link #doInBackground}.
* @see #onPreExecute
* @see #doInBackground
* @see #onCancelled(Object)
*/
@Override
protected void onPostExecute(PixabayQueryResult result) {
super.onPostExecute(result);
numberOfHits= result.size();
selected = getRandomLong(0, numberOfHits);
Bitmap bitmap= result.getBitmap((int)selected);
imageView.setImageBitmap(bitmap);
/* try {
callCloudVision(urlString);
} catch (IOException e) {
e.printStackTrace();
}*/
}
}
private void callCloudVision(final String loc) throws IOException {
// Switch text to loading
googlelab.setText(R.string.loading_message);
// Do the real work in an async task, because we need to use the network anyway
new AsyncTask<Object, Bitmap, String>() {
@Override
protected String doInBackground(Object... params) {
try {
HttpTransport httpTransport = AndroidHttp.newCompatibleTransport();
JsonFactory jsonFactory = GsonFactory.getDefaultInstance();
VisionRequestInitializer requestInitializer =
new VisionRequestInitializer(CLOUD_VISION_API_KEY) {
/**
* We override this so we can inject important identifying fields into the HTTP
* headers. This enables use of a restricted cloud platform API key.
*/
@Override
protected void initializeVisionRequest(VisionRequest<?> visionRequest)
throws IOException {
super.initializeVisionRequest(visionRequest);
String packageName = getPackageName();
visionRequest.getRequestHeaders().set(ANDROID_PACKAGE_HEADER, packageName);
String sig = PackageManagerUtils.getSignature(getPackageManager(), packageName);
visionRequest.getRequestHeaders().set(ANDROID_CERT_HEADER, sig);
}
};
Vision.Builder builder = new Vision.Builder(httpTransport, jsonFactory, null);
builder.setVisionRequestInitializer(requestInitializer);
Vision vision = builder.build();
BatchAnnotateImagesRequest batchAnnotateImagesRequest =
new BatchAnnotateImagesRequest();
batchAnnotateImagesRequest.setRequests(new ArrayList<AnnotateImageRequest>() {{
AnnotateImageRequest annotateImageRequest = new AnnotateImageRequest();
Bitmap bitmap = null;
try {
InputStream stream = new URL(loc).openStream();
bitmap = BitmapFactory.decodeStream(stream);
publishProgress(bitmap);
} catch (IOException e) {
e.printStackTrace();
}
// Add the image
Image base64EncodedImage = new Image();
// Convert the bitmap to a JPEG
// Just in case it's a format that Android understands but Cloud Vision
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, byteArrayOutputStream);
byte[] imageBytes = byteArrayOutputStream.toByteArray();
// Base64 encode the JPEG
base64EncodedImage.encodeContent(imageBytes);
annotateImageRequest.setImage(base64EncodedImage);
// add the features we want
annotateImageRequest.setFeatures(new ArrayList<Feature>() {{
Feature labelDetection = new Feature();
labelDetection.setType("LABEL_DETECTION");
labelDetection.setMaxResults(10);
add(labelDetection);
}});
// Add the list of one thing to the request
add(annotateImageRequest);
}});
Vision.Images.Annotate annotateRequest =
vision.images().annotate(batchAnnotateImagesRequest);
// Due to a bug: requests to Vision API containing large images fail when GZipped.
annotateRequest.setDisableGZipContent(true);
Log.d(TAGgoogle, "created Cloud Vision request object, sending request");
BatchAnnotateImagesResponse response = annotateRequest.execute();
return convertResponseToString(response);
} catch (GoogleJsonResponseException e) {
Log.d(TAGgoogle, "failed to make API request because " + e.getContent());
} catch (IOException e) {
Log.d(TAGgoogle, "failed to make API request because of other IOException " +
e.getMessage());
}
return "Cloud Vision API request failed. Check logs for details.";
}
/**
* Runs on the UI thread after {@link #publishProgress} is invoked.
* The specified values are the values passed to {@link #publishProgress}.
*
* @param bitmaps The values indicating progress.
* @see #publishProgress
* @see #doInBackground
*/
@Override
protected void onProgressUpdate(Bitmap... bitmaps) {
super.onProgressUpdate(bitmaps);
imageView.setImageBitmap(bitmaps[0]);
}
protected void onPostExecute(String result) {
googlelab.setText(result);
}
}.execute();
}
private String convertResponseToString(BatchAnnotateImagesResponse response) {
String message = "Labels:\n\n";
List<EntityAnnotation> labels = response.getResponses().get(0).getLabelAnnotations();
if (labels != null) {
for (EntityAnnotation label : labels) {
message += String.format(Locale.US, "%.3f: %s", label.getScore(), label.getDescription());
message += "\n";
}
} else {
message += "nothing";
}
return message;
}
}
这是它给我的错误:
E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #3
Process: edu.ggc.lutz.recipe.pixabaysamplerwalkthrough, PID: 21223 java.lang.RuntimeException: An error occurred while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:309)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354)
at java.util.concurrent.FutureTask.setException(FutureTask.java:223)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.graphics.Bitmap.compress(android.graphics.Bitmap$CompressFormat, int, java.io.OutputStream)' on a null object reference
at edu.ggc.lutz.recipe.pixabaysamplerwalkthrough.MainActivity$2$2.<init>(MainActivity.java:419)
at edu.ggc.lutz.recipe.pixabaysamplerwalkthrough.MainActivity$2.doInBackground(MainActivity.java:400)
at edu.ggc.lutz.recipe.pixabaysamplerwalkthrough.MainActivity$2.doInBackground(MainActivity.java:366)
at android.os.AsyncTask$2.call(AsyncTask.java:295) at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
还有另一个错误说明了文本到语音,但我认为这是此错误的结果。
我认为它与运行两个不同的异步任务同时重载它或事实上它传递的空值导致错误有关。