I'm trying to finish my android project, which is to develop an app which uses the camera for scanning tollbooth tickets. The problem is when I try to implement my code for calling the camera, it's when Android Studio shows me the "PERMISSION UTILS can not resolve" mistake. Could anyone guide me in the truth path and show me the answer to my question? Thanks for your attention. enter image description here
Here is my Main Activity code (is the only one activity)
package com.truiton.cloudvisionapi;
//import permission.utils.permissions.get_app_perms;
import android.Manifest;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.hardware.Camera;
import android.net.Uri;
import android.os.AsyncTask;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gms.auth.GoogleAuthUtil;
import com.google.android.gms.common.AccountPicker;
import com.google.api.client.extensions.android.http.AndroidHttp;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
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.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.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
public class MainActivity extends AppCompatActivity {
private static String accessToken;
static final int REQUEST_GALLERY_IMAGE = 10;
static final int REQUEST_CODE_PICK_ACCOUNT = 11;
static final int REQUEST_ACCOUNT_AUTHORIZATION = 12;
static final int REQUEST_PERMISSIONS = 13;
/* Variables Nuevas */
static final int CAMERA_PERMISSIONS_REQUEST=10;
static final int READ_EXTERNAL_STORAGE=10;
static final int CAMERA=1;
static final int ACTION_IMAGE_CAPTURE=10;
static final int EXTRA_OUTPUT=10;
static final int CAMERA_IMAGE_REQUEST=10;
static final String GALLERY_IMAGE_REQUEST="requestCode";
private static final String CLOUD_VISION_API_KEY = "AIzaSyC6SWJiwFLi3Q_YCmSRLwd8PN5CNE1DQ7U";
private static final String VisionRequestInitializer="";
private static final String TAG ="";
private static final String mIMAGEDETAILS="";
private static final String loading_message="";
private final String LOG_TAG = "MainActivity";
private ImageView selectedImage;
private TextView resultTextView;
Account mAccount;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button selectImageButton = (Button) findViewById(R.id
.select_image_button);
selectedImage = (ImageView) findViewById(R.id.selected_image);
resultTextView = (TextView) findViewById(R.id.result);
selectImageButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.GET_ACCOUNTS},
REQUEST_PERMISSIONS);
}
});
}
private void launchImagePicker() {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select an image"),
REQUEST_GALLERY_IMAGE);
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case REQUEST_PERMISSIONS:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
getAuthToken();
if (PermissionUtils.permissionGranted(
requestCode,
CAMERA_PERMISSIONS_REQUEST,
grantResults)) {
startCamera();
}
} else {
Toast.makeText(MainActivity.this, "Permission Denied!", Toast.LENGTH_SHORT).show();
}
}
}
public void StartCamera() {
if (PermissionUtils.requestPermission(
Manifest.permission.CAMERA)) {
this, CAMERA_PERMISSIONS_REQUEST, CAMERA_PERIntent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(getCameraFile()));
startActivityForResult(intent, CAMERA_IMAGE_REQUEST);
}
}
public File getCameraFile() {
File dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
return new File(dir, FILE_NAME);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_GALLERY_IMAGE && resultCode == RESULT_OK && data != null) {
uploadImage(data.getData());
} else if (requestCode == CAMERA_IMAGE_REQUEST && resultCode == RESULT_OK) {
uploadImage(Uri.fromFile(getCameraFile()));
} else if (resultCode == RESULT_CANCELED) {
Toast.makeText(this, "No Account Selected", Toast.LENGTH_SHORT)
.show();
Toast.makeText(this, "Authorization Failed", Toast.LENGTH_SHORT)
.show();
}
}
/* @Override
private void callCloudVision(final Bitmap bitmap) throws IOException {
// Switch text to loading
mImageDetails.setText(R.string.loading_message);
Log.i(TAG, "callCloudVision: Entra a callCloudVision");
//Se puede borrar solo es para hacer pruebas de debug.
// Do the real work in an async task, because we need to use the network anyway
new AsyncTask<Object, Void, String>() {
@Override
protected String doInBackground(Object... params) {
try {
HttpTransport httpTransport = AndroidHttp.newCompatibleTransport();
JsonFactory jsonFactory = GsonFactory.getDefaultInstance();
Vision.Builder builder = new Vision.Builder(httpTransport, jsonFactory, null);
builder.setVisionRequestInitializer(new
VisionRequestInitializer(CLOUD_VISION_API_KEY));
Vision vision = builder.build();
}
}
}
}*/
public void uploadImage(Uri uri) {
if (uri != null) {
try {
Bitmap bitmap = resizeBitmap(
MediaStore.Images.Media.getBitmap(getContentResolver(), uri));
callCloudVision(bitmap);
selectedImage.setImageBitmap(bitmap);
} catch (IOException e) {
Log.e(LOG_TAG, e.getMessage());
}
} else {
Log.e(LOG_TAG, "Null image was returned.");
}
}
private void callCloudVision(final Bitmap bitmap) throws IOException {
resultTextView.setText("Retrieving results from cloud");
new AsyncTask<Object, Void, String>() {
@Override
protected String doInBackground(Object... params) {
try {
GoogleCredential credential = new GoogleCredential().setAccessToken(accessToken);
HttpTransport httpTransport = AndroidHttp.newCompatibleTransport();
JsonFactory jsonFactory = GsonFactory.getDefaultInstance();
Vision.Builder builder = new Vision.Builder
(httpTransport, jsonFactory, credential);
Vision vision = builder.build();
List<Feature> featureList = new ArrayList<>();
// Feature labelDetection = new Feature();
// labelDetection.setType("LABEL_DETECTION");
// labelDetection.setMaxResults(10);
// featureList.add(labelDetection);
Feature textDetection = new Feature();
textDetection.setType("TEXT_DETECTION");
textDetection.setMaxResults(100000);
featureList.add(textDetection);
// Feature landmarkDetection = new Feature();
//landmarkDetection.setType("LANDMARK_DETECTION");
//landmarkDetection.setMaxResults(10);
//featureList.add(landmarkDetection);
List<AnnotateImageRequest> imageList = new ArrayList<>();
AnnotateImageRequest annotateImageRequest = new AnnotateImageRequest();
Image base64EncodedImage = getBase64EncodedJpeg(bitmap);
annotateImageRequest.setImage(base64EncodedImage);
annotateImageRequest.setFeatures(featureList);
imageList.add(annotateImageRequest);
BatchAnnotateImagesRequest batchAnnotateImagesRequest =
new BatchAnnotateImagesRequest();
batchAnnotateImagesRequest.setRequests(imageList);
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(LOG_TAG, "sending request");
BatchAnnotateImagesResponse response = annotateRequest.execute();
return convertResponseToString(response);
} catch (GoogleJsonResponseException e) {
Log.e(LOG_TAG, "Request failed: " + e.getContent());
} catch (IOException e) {
Log.d(LOG_TAG, "Request failed: " + e.getMessage());
}
return "Cloud Vision API request failed.";
}
protected void onPostExecute(String result) {
resultTextView.setText(result);
}
}.execute();
}
private String convertResponseToString(BatchAnnotateImagesResponse response) {
StringBuilder message = new StringBuilder("Results:\n\n");
message.append("Labels:\n");
List<EntityAnnotation> labels = response.getResponses().get(0).getLabelAnnotations();
if (labels != null) {
for (EntityAnnotation label : labels) {
message.append(String.format(Locale.getDefault(), "%.3f: %s",
label.getScore(), label.getDescription()));
message.append("\n");
}
} else {
message.append("nothing\n");
}
message.append("Texts:\n");
List<EntityAnnotation> texts = response.getResponses().get(0)
.getTextAnnotations();
if (texts != null) {
for (EntityAnnotation text : texts) {
message.append(String.format(Locale.getDefault(), "%s: %s",
text.getLocale(), text.getDescription()));
message.append("\n");
}
} else {
message.append("nothing\n");
}
message.append("Landmarks:\n");
List<EntityAnnotation> landmarks = response.getResponses().get(0)
.getLandmarkAnnotations();
if (landmarks != null) {
for (EntityAnnotation landmark : landmarks) {
message.append(String.format(Locale.getDefault(), "%.3f: %s",
landmark.getScore(), landmark.getDescription()));
message.append("\n");
}
} else {
message.append("nothing\n");
}
return message.toString();
}
public Bitmap resizeBitmap(Bitmap bitmap) {
int maxDimension = 1024;
int originalWidth = bitmap.getWidth();
int originalHeight = bitmap.getHeight();
int resizedWidth = maxDimension;
int resizedHeight = maxDimension;
if (originalHeight > originalWidth) {
resizedHeight = maxDimension;
resizedWidth = (int) (resizedHeight * (float) originalWidth / (float) originalHeight);
} else if (originalWidth > originalHeight) {
resizedWidth = maxDimension;
resizedHeight = (int) (resizedWidth * (float) originalHeight / (float) originalWidth);
} else if (originalHeight == originalWidth) {
resizedHeight = maxDimension;
resizedWidth = maxDimension;
}
return Bitmap.createScaledBitmap(bitmap, resizedWidth, resizedHeight, false);
}
public Image getBase64EncodedJpeg(Bitmap bitmap) {
Image image = new Image();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, byteArrayOutputStream);
byte[] imageBytes = byteArrayOutputStream.toByteArray();
image.encodeContent(imageBytes);
return image;
}
private void pickUserAccount() {
String[] accountTypes = new String[]{GoogleAuthUtil.GOOGLE_ACCOUNT_TYPE};
Intent intent = AccountPicker.newChooseAccountIntent(null, null,
accountTypes, false, null, null, null, null);
startActivityForResult(intent, REQUEST_CODE_PICK_ACCOUNT);
}
private void getAuthToken() {
String SCOPE = "oauth2:https://www.googleapis.com/auth/cloud-platform";
if (mAccount == null) {
pickUserAccount();
} else {
new GetTokenTask(MainActivity.this, mAccount, SCOPE, REQUEST_ACCOUNT_AUTHORIZATION)
.execute();
}
}
public void onTokenReceived(String token){
accessToken = token;
launchImagePicker();
}
}
/* CÓDIGO DE API KEY DESECHADO */
/*AccountManager am = AccountManager.get(this);
Account[] accounts = am.getAccountsByType(GoogleAuthUtil.);
for (Account account : accounts) {
if (account.name.equals(email)) {
mAccount = account;
break;
}
}
else
if (requestCode == REQUEST_ACCOUNT_AUTHORIZATION) {
if (resultCode == RESULT_OK) {
Bundle extra = data.getExtras();
onTokenReceived(extra.getString("authtoken"));
}
*/
Here is my Manifest file:
> <?xml version="1.0" encoding="utf-8"?> <manifest
> package="com.truiton.cloudvisionapi"
> xmlns:android="http://schemas.android.com/apk/res/android">
>
> <uses-permission android:name="android.permission.GET_ACCOUNTS"/>
> <uses-permission android:name="android.permission.INTERNET"/>
>
> <uses-permission android:name="android.permission.CLOUD_VISION_API_KEY"/>
> <uses-permission android:name="android.permission.CAMERA_PERMISSIONS_REQUEST"/>
> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
> <uses-permission android:name="android.permission.CAMERA"/>
> <uses-permission android:name="android.permission.ACTION_IMAGE_CAPTURE"/>
> <uses-permission android:name="android.permission.EXTRA_OUTPUT"/>
> <uses-permission android:name="android.permission.CAMERA_IMAGE_REQUEST"/>
> <uses-permission android:name="android.permission.GALLERY_IMAGE_REQUEST"/>
>
>
> <application
> android:allowBackup="true"
> android:icon="@mipmap/ic_launcher"
> android:label="@string/app_name"
> android:supportsRtl="true"
> android:theme="@style/AppTheme">
> <activity android:name=".MainActivity">
> <intent-filter>
> <action android:name="android.intent.action.MAIN"/>
>
> <category android:name="android.intent.category.LAUNCHER"/>
> </intent-filter>
> </activity>
> </application>
>
> </manifest>