I keep getting this error within the startOCR function :
java.lang.String android.net.Uri.getPath()' on a null object reference
I am trying to take a picture and then crop it before sending it to the perform OCR function. Can anyone help me out?
import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import com.googlecode.tesseract.android.TessBaseAPI;
public class Main3Activity extends AppCompatActivity {
//Log variable.
private static final String TAG = Main3Activity.class.getSimpleName();
//Request code is 1
static final int PHOTO_REQUEST_CODE = 1;
//Constructing an instance to the Tesseract API
private TessBaseAPI tessBaseApi;
//Getting a reference to the TextView in the XML layout
TextView textView;
//Creating a Uri variable that will be holding the point of content to the image.
Uri outputFileUri;
final int PIC_CROP = 2;
private static final String lang = "eng";
String result = "empty";
private static final String DATA_PATH = Environment.getExternalStorageDirectory().toString() + "/TesseractSample/";
private static final String TESSDATA = "tessdata";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main3);
textView = (TextView) findViewById(R.id.OcrResultTextView);
//Getting reference to the button and setting the onClickListener for the button.
Button captureImg = (Button) findViewById(R.id.CaptureImageButton);
if (captureImg != null) {
captureImg.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startCameraActivity();
}
});
}
}//end of onCreate
/*************************************************************************************************************************
Method that will start the camera of the phone.
************************************************************************************************************************/
private void startCameraActivity() {
try {
//String variable that will hold the directory of the folder which is to be created within the internal
//storage of the phone.
String IMGS_PATH = Environment.getExternalStorageDirectory().toString() + "/TesseractSample/imgs";
prepareDirectory(IMGS_PATH);
String img_path = IMGS_PATH + "/ocr.jpg";
//Uri variable (Uniform Resource Identifier) will contain the reference the uri created from a file.
outputFileUri = Uri.fromFile(new File(img_path));
//Creating an intent of type action_image_capture which is the standard action that
//can be sent to have the camera application capture an image and return it.
final Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
//Inserting into the intent extra_output because this is used to indicate a content
//resolver Uri to be used to store the requested image, can also be used for videos.
//Also passing in the output Uri which will hold the path to the output image.
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
//Ensuring that there is a camera activity to handle the intent and if there is,
//passing in the takePictureIntent and along with the photo request code.
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(takePictureIntent, PHOTO_REQUEST_CODE);
//At this current point the camera has been initated.
Log.e(TAG,"Started the camera.");
}
} catch (Exception e) {
Log.e(TAG, e.getMessage());
}
}
/*********************************************************************************************************************
This method will get called after the image is either finished taken or the user decided to cancel the camera.
********************************************************************************************************************/
#Override
public void onActivityResult(int requestCode, int resultCode,
Intent data) {
Log.e(TAG, "Photo has been taken.");
//Method of cropping has to go here
//CropFunction();
//Creating photo
if (requestCode == PHOTO_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
Log.e(TAG,"Taken to the confirmation.");
prepareTesseract();
//Put the crop here.
Log.e(TAG, "Starting crop function");
CropFunction();
//if(requestCode == PIC_CROP){
// Log.e(TAG, "Inside if statement for PIC_CROP");
//Getting the returned data and entering it into the Bundle.
//Bundle extras = data.getExtras();
//Get the cropped bitmap
// Bitmap thePic = extras.getParcelable("data");
Log.e(TAG, "Calling the startOCR function");
startOCR(outputFileUri);
// }
// startOCR(outputFileUri);
} else {
Toast.makeText(this, "ERROR: Image was not obtained.", Toast.LENGTH_SHORT).show();
}
}
/***************************************************************************************************
Method to create the directory within the internal storage of the phone.
Method will first check if the directory has not been created before, if it has not
it will create the directory and the Log will display the message it has been created.
If the internal photo directory has already been created this method will just be passed.
*************************************************************************************************/
private void prepareDirectory(String path) {
File dir = new File(path);
if (!dir.exists()) {
if (!dir.mkdirs()) {
Log.e(TAG, "ERROR: Creation of directory " + path + " failed, check does Android Manifest have permission to write to external storage.");
}
} else {
Log.i(TAG, "Created directory " + path);
}
}
/************************************************************************
Method responsible for preparing Tesseract operations.
***********************************************************************/
private void prepareTesseract() {
try {
prepareDirectory(DATA_PATH + TESSDATA);
} catch (Exception e) {
e.printStackTrace();
}
copyTessDataFiles(TESSDATA);
}
/*************************************************************************************************
****************************************************************************************************/
private void copyTessDataFiles(String path) {
try {
String fileList[] = getAssets().list(path);
for (String fileName : fileList) {
//Opening the file within the assets folder
// In the situation that the fole is no there it will copy it to the sd card
String pathToDataFile = DATA_PATH + path + "/" + fileName;
if (!(new File(pathToDataFile)).exists()) {
InputStream in = getAssets().open(path + "/" + fileName);
OutputStream out = new FileOutputStream(pathToDataFile);
// Transfer bytes from in to out
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
Log.d(TAG, "Copied " + fileName + "to tessdata");
}
}
} catch (IOException e) {
Log.e(TAG, "Unable to copy files to tessdata " + e.toString());
}
}
/************************************************************************************************
This function performs the OCR technology within the image provided.
Function that beings the Optical Character Recognition of the image.
Function expects to recieve the Uri of a captured image.
*************************************************************************************************/
private void startOCR(Uri imgUri) {
try {
BitmapFactory.Options options = new BitmapFactory.Options();
// 1 - means max size. 4 - means maxsize/4 size. Don't use value <4, because you need more memory in the heap to store your data.
options.inSampleSize = 4;
Bitmap bitmap = BitmapFactory.decodeFile(imgUri.getPath(), options);
//The result variable will hold whatever is returned from "extractText" function.
result = extractText(bitmap);
//Setting the string result to the content of the TextView.
textView.setText(result);
} catch (Exception e) {
Log.e(TAG, e.getMessage());
}
}
private String extractText(Bitmap bitmap) {
try {
tessBaseApi = new TessBaseAPI();
} catch (Exception e) {
Log.e(TAG, e.getMessage());
if (tessBaseApi == null) {
Log.e(TAG, "TessBaseAPI is null. TessFactory not returning tess object.");
}
}
tessBaseApi.init(DATA_PATH, lang);
Log.d(TAG, "Training file loaded");
tessBaseApi.setImage(bitmap);
String extractedText = "empty result";
try {
extractedText = tessBaseApi.getUTF8Text();
} catch (Exception e) {
Log.e(TAG, "Error in recognizing text.");
}
tessBaseApi.end();
return extractedText;
}
private void CropFunction(){
try{
Log.e(TAG, "Inside the crop function.");
Intent cropIntent = new Intent("com.android.camera.action.CROP");
// cropIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
//cropIntent.putExtra("crop", "true");
//cropIntent.putExtra("return-data", true);
//startActivityForResult(cropIntent,1);
//Inserting the imageType and the Uri into the intent.
cropIntent.setDataAndType(outputFileUri, "image/*");
//Passing in the crop properties to the intent.
cropIntent.putExtra("crop", "true");
//Indicating and passing in the aspect of the desired crop.
cropIntent.putExtra("aspectX", 0);
cropIntent.putExtra("aspectY", 0);
//Indicating and passing in the output for X and Y.
cropIntent.putExtra("outputX", 200);
cropIntent.putExtra("outputY", 150);
//retrieve data on return
//changed from true which gives me a bitmap to false which gives me the exact image.
cropIntent.putExtra("return-data", false);
cropIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
Log.e(TAG,"At the end of the crop function.");
startActivityForResult(cropIntent, PIC_CROP);
}catch(ActivityNotFoundException e){
String errorMessage = "Sorry, your device does not support the crop feature";
Toast toaster = Toast.makeText(this, errorMessage, Toast.LENGTH_SHORT);
toaster.show();
}
}
}// End of class
Related
I am using a "ACTION_OPEN_DOCUMENT" intent to choose a file and open it.
This works just fine when I go to read the file.
However, when the file resides on EXTERNAL storage, and I run a query to obtain the file name, my program crashes. If the file resides on INTERNAL storage, I have no issues.
I DO have (and check for) external storage access permissions.
I have the query enclosed in a try{}, but the exception is not caught. I am developing on a Chrome book, so I am unable to run the debugger on it. But I have isolated the issue to the result = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME)); statement.
I know that access to files on external storage has been limited, but I would think that if I can read a file that I should also be able to query it as well.
Here is my code:
package com.muddco.demo3;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import android.Manifest;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.OpenableColumns;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.InputStreamReader;
public class MainActivity extends AppCompatActivity {
Activity mAct;
TextView rvalue, fnamevalue;
Button btn1, btn2;
Uri fileUri;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn1 = findViewById(R.id.btn1);
btn2 = findViewById(R.id.btn2);
rvalue = findViewById(R.id.readResult);
fnamevalue = findViewById(R.id.textView2);
mAct = this;
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 1);
btn1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
/*
* Launch a file picker
*/
Intent intent = new Intent();
intent.setAction(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("*/*");
startActivityForResult(Intent.createChooser(intent, "Select a GPX file"), 1);
}
});
btn2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
/*
* Get and display file name
*/
String fname = getFileName(fileUri);
fnamevalue.setText(fname);
}
});
}
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case 1: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission granted and now can proceed
Toast.makeText(MainActivity.this, "Permission granted", Toast.LENGTH_SHORT).show();
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
Toast.makeText(MainActivity.this, "Permission denied to read your External storage", Toast.LENGTH_SHORT).show();
}
return;
}
// add other cases for more permissions
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
InputStream inputStream = null;
Uri uri = null;
if (resultCode == Activity.RESULT_OK) {
if (requestCode == 1) {
// Process GPX file
uri = data.getData();
try {
inputStream = getBaseContext().getContentResolver().openInputStream(uri);
rvalue.setText(readFile(inputStream));
} catch (FileNotFoundException e) {
Toast.makeText(this, "File not found: " + uri.toString(), Toast.LENGTH_SHORT).show();
}
//String fName = getFileName(uri);
//Toast.makeText(mAct, "Filename: "+fName, Toast.LENGTH_LONG).show();
fileUri = uri;
btn2.setVisibility(View.VISIBLE);
}
}
}
/*
* Read a FileStream
*
*/
String readFile(InputStream is) {
String ret = "";
String line = null;
try {
BufferedReader br = new BufferedReader(new InputStreamReader(is));
while ((line = br.readLine()) != null) {
ret += line + "\n";
}
br.close();
} catch (Exception e) {
// if any I/O error occurs
e.printStackTrace();
ret = "Exception!";
}
return ret;
}
/*
* Obtain the filename from a URI
*/
public String getFileName(Uri uri) {
String result = "<empty>";
Cursor cursor;
if (uri.getScheme().equals("content")) {
ContentResolver cr = getContentResolver();
try {
cursor = cr.query(uri, null, null, null, null);
} catch (Exception e) {
Toast.makeText(this, "Cursor exception: " + e.toString(), Toast.LENGTH_LONG).show();
return null;
}
try {
if (cursor != null && cursor.moveToFirst()) {
//
// THE NEXT STATEMENT CRASHES WHEN FILE RESIDES ON EXTERNAL STORAGE
//
result = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
}
else {
Toast.makeText(mAct, "Bad cursor", Toast.LENGTH_SHORT).show();
return "Bad Cursor";
}
} catch (Exception e) {
Toast.makeText(this, "Cursor exception: " + e.toString(), Toast.LENGTH_LONG).show();
return "Cursoe Exception";
} finally {
cursor.close();
}
}
else
result="Non content URI";
return result;
}
}
When I press the first button, the file requestor pops up and I select my test text file. The contents of the file are listed in a textbox, then a second button is made visible. When that second button is pressed, I query the file and place the filename in a second textbox.
The entire project, along with the test.txt file I am using to test, can be found here
package com.camerafileupload;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends Activity {
// LogCat tag
private static final String TAG = MainActivity.class.getSimpleName();
// Camera activity request codes
private static final int CAMERA_CAPTURE_IMAGE_REQUEST_CODE = 100;
private static final int CAMERA_CAPTURE_VIDEO_REQUEST_CODE = 200;
public static final int MEDIA_TYPE_IMAGE = 1;
public static final int MEDIA_TYPE_VIDEO = 2;
private Uri fileUri; // file url to store image/video
private Button btnCapturePicture, btnRecordVideo;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Changing action bar background color
// These two lines are not needed
getActionBar().setBackgroundDrawable(new ColorDrawable(Color.parseColor(getResources().getString(R.color.action_bar))));
btnCapturePicture = (Button) findViewById(R.id.btnCapturePicture);
btnRecordVideo = (Button) findViewById(R.id.btnRecordVideo);
/**
* Capture image button click event
*/
btnCapturePicture.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// capture picture
captureImage();
}
});
/**
* Record video button click event
*/
btnRecordVideo.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// record video
recordVideo();
}
});
// Checking camera availability
if (!isDeviceSupportCamera()) {
Toast.makeText(getApplicationContext(),
"Sorry! Your device doesn't support camera",
Toast.LENGTH_LONG).show();
// will close the app if the device does't have camera
finish();
}
}
/**
* Checking device has camera hardware or not
* */
private boolean isDeviceSupportCamera() {
if (getApplicationContext().getPackageManager().hasSystemFeature(
PackageManager.FEATURE_CAMERA)) {
// this device has a camera
return true;
} else {
// no camera on this device
return false;
}
}
/**
* Launching camera app to capture image
*/
private void captureImage() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
// start the image capture Intent
startActivityForResult(intent, CAMERA_CAPTURE_IMAGE_REQUEST_CODE);
}
/**
* Launching camera app to record video
*/
private void recordVideo() {
Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
fileUri = getOutputMediaFileUri(MEDIA_TYPE_VIDEO);
// set video quality
intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); // set the image file
// name
// start the video capture Intent
startActivityForResult(intent, CAMERA_CAPTURE_VIDEO_REQUEST_CODE);
}
/**
* Here we store the file url as it will be null after returning from camera
* app
*/
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
// save file url in bundle as it will be null on screen orientation
// changes
outState.putParcelable("file_uri", fileUri);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
// get the file url
fileUri = savedInstanceState.getParcelable("file_uri");
}
/**
* Receiving activity result method will be called after closing the camera
* */
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// if the result is capturing Image
if (requestCode == CAMERA_CAPTURE_IMAGE_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
// successfully captured the image
// launching upload activity
launchUploadActivity(true);
} else if (resultCode == RESULT_CANCELED) {
// user cancelled Image capture
Toast.makeText(getApplicationContext(),
"User cancelled image capture", Toast.LENGTH_SHORT)
.show();
} else {
// failed to capture image
Toast.makeText(getApplicationContext(),
"Sorry! Failed to capture image", Toast.LENGTH_SHORT)
.show();
}
} else if (requestCode == CAMERA_CAPTURE_VIDEO_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
// video successfully recorded
// launching upload activity
launchUploadActivity(false);
} else if (resultCode == RESULT_CANCELED) {
// user cancelled recording
Toast.makeText(getApplicationContext(),
"User cancelled video recording", Toast.LENGTH_SHORT)
.show();
} else {
// failed to record video
Toast.makeText(getApplicationContext(),
"Sorry! Failed to record video", Toast.LENGTH_SHORT)
.show();
}
}
}
private void launchUploadActivity(boolean isImage){
Intent i = new Intent(MainActivity.this, UploadActivity.class);
i.putExtra("filePath", fileUri.getPath());
i.putExtra("isImage", isImage);
startActivity(i);
}
/**
* ------------ Helper Methods ----------------------
* */
/**
* Creating file uri to store image/video
*/
public Uri getOutputMediaFileUri(int type) {
return Uri.fromFile(getOutputMediaFile(type));
}
/**
* returning image / video
*/
private static File getOutputMediaFile(int type) {
// External sdcard location
File mediaStorageDir = new File(
Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
Config.IMAGE_DIRECTORY_NAME);
// Create the storage directory if it does not exist
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Log.d(TAG, "Oops! Failed create "
+ Config.IMAGE_DIRECTORY_NAME + " directory");
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss",
Locale.getDefault()).format(new Date());
File mediaFile;
if (type == MEDIA_TYPE_IMAGE) {
mediaFile = new File(mediaStorageDir.getPath() + File.separator
+ "IMG_" + timeStamp + ".jpg");
} else if (type == MEDIA_TYPE_VIDEO) {
mediaFile = new File(mediaStorageDir.getPath() + File.separator
+ "VID_" + timeStamp + ".mp4");
} else {
return null;
}
return mediaFile;
}
}
I get this code from android hive, I didn't know where the code to upload the image to server. I already build this code into .apk it working when taking photo and video to local storage but not to server.
and this is uploadactivity
package com.camerafileupload;
import com.camerafileupload.AndroidMultiPartEntity.ProgressListener;
import java.io.File;
import java.io.IOException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.VideoView;
public class UploadActivity extends Activity {
// LogCat tag
private static final String TAG = MainActivity.class.getSimpleName();
private ProgressBar progressBar;
private String filePath = null;
private TextView txtPercentage;
private ImageView imgPreview;
private VideoView vidPreview;
private Button btnUpload;
long totalSize = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_upload);
txtPercentage = (TextView) findViewById(R.id.txtPercentage);
btnUpload = (Button) findViewById(R.id.btnUpload);
progressBar = (ProgressBar) findViewById(R.id.progressBar);
imgPreview = (ImageView) findViewById(R.id.imgPreview);
vidPreview = (VideoView) findViewById(R.id.videoPreview);
// Changing action bar background color
getActionBar().setBackgroundDrawable(
new ColorDrawable(Color.parseColor(getResources().getString(
R.color.action_bar))));
// Receiving the data from previous activity
Intent i = getIntent();
// image or video path that is captured in previous activity
filePath = i.getStringExtra("filePath");
// boolean flag to identify the media type, image or video
boolean isImage = i.getBooleanExtra("isImage", true);
if (filePath != null) {
// Displaying the image or video on the screen
previewMedia(isImage);
} else {
Toast.makeText(getApplicationContext(),
"Sorry, file path is missing!", Toast.LENGTH_LONG).show();
}
btnUpload.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// uploading the file to server
new UploadFileToServer().execute();
}
});
}
/**
* Displaying captured image/video on the screen
* */
private void previewMedia(boolean isImage) {
// Checking whether captured media is image or video
if (isImage) {
imgPreview.setVisibility(View.VISIBLE);
vidPreview.setVisibility(View.GONE);
// bimatp factory
BitmapFactory.Options options = new BitmapFactory.Options();
// down sizing image as it throws OutOfMemory Exception for larger
// images
options.inSampleSize = 8;
final Bitmap bitmap = BitmapFactory.decodeFile(filePath, options);
imgPreview.setImageBitmap(bitmap);
} else {
imgPreview.setVisibility(View.GONE);
vidPreview.setVisibility(View.VISIBLE);
vidPreview.setVideoPath(filePath);
// start playing
vidPreview.start();
}
}
/**
* Uploading the file to server
* */
private class UploadFileToServer extends AsyncTask<Void, Integer, String> {
#Override
protected void onPreExecute() {
// setting progress bar to zero
progressBar.setProgress(0);
super.onPreExecute();
}
#Override
protected void onProgressUpdate(Integer... progress) {
// Making progress bar visible
progressBar.setVisibility(View.VISIBLE);
// updating progress bar value
progressBar.setProgress(progress[0]);
// updating percentage value
txtPercentage.setText(String.valueOf(progress[0]) + "%");
}
#Override
protected String doInBackground(Void... params) {
return uploadFile();
}
#SuppressWarnings("deprecation")
private String uploadFile() {
String responseString = null;
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(Config.FILE_UPLOAD_URL);
try {
AndroidMultiPartEntity entity = new AndroidMultiPartEntity(
new ProgressListener() {
#Override
public void transferred(long num) {
publishProgress((int) ((num / (float) totalSize) * 100));
}
});
File sourceFile = new File(filePath);
// Adding file data to http body
entity.addPart("image", new FileBody(sourceFile));
// Extra parameters if you want to pass to server
entity.addPart("website",
new StringBody("www.fintech-dev.com/cpeco"));
entity.addPart("email", new StringBody("i117dr4#gmail.com"));
totalSize = entity.getContentLength();
httppost.setEntity(entity);
// Making server call
HttpResponse response = httpclient.execute(httppost);
HttpEntity r_entity = response.getEntity();
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode == 200) {
// Server response
responseString = EntityUtils.toString(r_entity);
} else {
responseString = "Error occurred! Http Status Code: "
+ statusCode;
}
} catch (ClientProtocolException e) {
responseString = e.toString();
} catch (IOException e) {
responseString = e.toString();
}
return responseString;
}
#Override
protected void onPostExecute(String result) {
Log.e(TAG, "Response from server: " + result);
// showing the server response in an alert dialog
showAlert(result);
super.onPostExecute(result);
}
}
/**
* Method to show alert dialog
* */
private void showAlert(String message) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(message).setTitle("Response from Servers")
.setCancelable(false)
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// do nothing
}
});
AlertDialog alert = builder.create();
alert.show();
}
}
and this is androidmultipartentity
package com.camerafileupload;
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.Charset;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntity;
#SuppressWarnings("deprecation")
public class AndroidMultiPartEntity extends MultipartEntity
{
private final ProgressListener listener;
public AndroidMultiPartEntity(final ProgressListener listener) {
super();
this.listener = listener;
}
public AndroidMultiPartEntity(final HttpMultipartMode mode,
final ProgressListener listener) {
super(mode);
this.listener = listener;
}
public AndroidMultiPartEntity(HttpMultipartMode mode, final String boundary,
final Charset charset, final ProgressListener listener) {
super(mode, boundary, charset);
this.listener = listener;
}
#Override
public void writeTo(final OutputStream outstream) throws IOException {
super.writeTo(new CountingOutputStream(outstream, this.listener));
}
public static interface ProgressListener {
void transferred(long num);
}
public static class CountingOutputStream extends FilterOutputStream {
private final ProgressListener listener;
private long transferred;
public CountingOutputStream(final OutputStream out,
final ProgressListener listener) {
super(out);
this.listener = listener;
this.transferred = 0;
}
public void write(byte[] b, int off, int len) throws IOException {
out.write(b, off, len);
this.transferred += len;
this.listener.transferred(this.transferred);
}
public void write(int b) throws IOException {
out.write(b);
this.transferred++;
this.listener.transferred(this.transferred);
}
}
}
This is config
package com.camerafileupload;
public class Config {
public static final String FILE_UPLOAD_URL = "url.com/android_upload/file_upload.php";
// Directory name to store captured images and videos
public static final String IMAGE_DIRECTORY_NAME = "android_upload";
DataHolder.FILE_UPLOAD_URL containing the url to upload.
onclick write
new UploadFileToServer().execute();
private class UploadFileToServer extends AsyncTask<Void, Integer, String> {
#Override
protected void onPreExecute() {
// setting progress bar to zero
pDialog.setProgress(0);
super.onPreExecute();
}
#Override
protected void onProgressUpdate(Integer... progress) {
// Making progress bar visible
// updating progress bar value
pDialog.setProgress(progress[0]);
// updating percentage value
// txtPercentage.setText(String.valueOf(progress[0]) + "%");
}
#Override
protected String doInBackground(Void... params) {
return uploadFile();
}
#SuppressWarnings("deprecation")
private String uploadFile() {
String responseString = null;
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(DataHolder.FILE_UPLOAD_URL);
try {
AndroidMultiPartEntity entity = new AndroidMultiPartEntity(
new ProgressListener() {
#Override
public void transferred(long num) {
publishProgress((int) ((num / (float) totalSize) * 100));
}
});
File sourceFile = new File(filePath);
// Adding file data to http body
entity.addPart("image", new FileBody(sourceFile));
// Extra parameters if you want to pass to server
entity.addPart("username", new StringBody("xyz"));
totalSize = entity.getContentLength();
httppost.setEntity(entity);
// Making server call
HttpResponse response = httpclient.execute(httppost);
HttpEntity r_entity = response.getEntity();
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode == 200) {
// Server response
responseString = EntityUtils.toString(r_entity);
} else {
responseString = "Error occurred! Http Status Code: "
+ statusCode;
}
} catch (ClientProtocolException e) {
responseString = e.toString();
} catch (IOException e) {
responseString = e.toString();
}
return responseString;
}
#Override
protected void onPostExecute(String result) {
Log.e(TAG, "Response from server: " + result);
// showing the server response in an alert dialog
showAlert(result);
super.onPostExecute(result);
}
}
/**
* Method to show alert dialog
* */
private void showAlert(String message) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setMessage(message).setTitle("Response from Servers")
.setCancelable(false)
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// do nothing
}
});
AlertDialog alert = builder.create();
alert.show();
}
I am having an issue when taking a photo with the camera on my Nexus 5. I can take photos from the gallery no problem and save them to the back end. However when I try to take a picture using the camera, after I take the picture and select the tick, then the app crashes...
I can see that the intent passed to the onActivityResult() is empty but I don't know how to fix this. Can anyone help? thanks.
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.Toast;
import com.khackett.runmate.R;
import com.khackett.runmate.utils.FileHelper;
import com.khackett.runmate.utils.ParseConstants;
import com.parse.ParseException;
import com.parse.ParseFile;
import com.parse.ParseUser;
import com.parse.SaveCallback;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
public class MyProfileFragment extends Fragment implements View.OnClickListener {
public static final String TAG = MyProfileFragment.class.getSimpleName();
protected Button mTakePicture;
protected Button mChoosePicture;
/**
* Default constructor
*/
public MyProfileFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.fragment_my_profile, container, false);
mTakePicture = (Button) rootView.findViewById(R.id.takePictureButton);
mChoosePicture = (Button) rootView.findViewById(R.id.choosePictureButton);
mTakePicture.setOnClickListener(this);
mChoosePicture.setOnClickListener(this);
return rootView;
}
/**
* Called when a view has been clicked.
*
* #param v The view that was clicked.
*/
#Override
public void onClick(View v) {
// Switch statement to select which action to take depending on button/text pressed
switch (v.getId()) {
case R.id.takePictureButton:
takeCameraPicture();
break;
case R.id.choosePictureButton:
chooseGalleryPicture();
break;
default:
System.out.println("Problem with input");
}
}
public static final int TAKE_PHOTO_REQUEST = 1888;
public static final int PICK_PHOTO_REQUEST = 1888;
private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 1888;
// member variable to store the media type as a URI, that can be stored in multiple places
// Uri = uniform resource identifier
protected Uri mMediaUri;
public void takeCameraPicture() {
// Take picture
// use an existing camera app on the phone by starting an intent
// declare intent to capture a photo using whatever camera app is available
Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// after invoking the camera,
mMediaUri = getOutputMediaFileUri();
// check that a null value is not returned
if (mMediaUri == null) {
// display an error
Toast.makeText(getActivity(), R.string.error_external_storage, Toast.LENGTH_LONG).show();
} else {
// to add extra data to an intent, use the putExtra() method
takePhotoIntent.putExtra(MediaStore.EXTRA_OUTPUT, mMediaUri);
// start an activity for a result so that the activity exits and returns a result back for us
// ie, the main activity will wait for the result
startActivityForResult(takePhotoIntent, TAKE_PHOTO_REQUEST);
}
}
public void chooseGalleryPicture() {
// Choose picture
Intent choosePhotoIntent = new Intent(Intent.ACTION_GET_CONTENT);
// need to specify which type of action we want to get - an image in this case
choosePhotoIntent.setType("image/*");
startActivityForResult(choosePhotoIntent, PICK_PHOTO_REQUEST);
}
private Uri getOutputMediaFileUri() {
// To be safe, you should check that the SD card / external storage is mounted
// using Environment.getExternalStorageState() before doing this.
// see method below...
if (isExternalStorageAvailable()) {
String appName = MyProfileFragment.this.getString(R.string.app_name);
// get the Uri
// Get the external storage directory - we want to return a file object
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), appName);
// Create our subdirectory
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdir()) {
Log.e(TAG, "Failed to create directory");
return null;
}
}
// Create a file to hold the image
File mediaFile;
// get the current date and time
Date now = new Date();
// convert the date and time into a String datetimestamp
// see http://developer.android.com/guide/topics/media/camera.html#saving-media for the methods used
// need to append a timestamp to make it unique - otherwise it will overwrite the previous photo
String timestamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.ENGLISH).format(now);
String path = mediaStorageDir.getPath() + File.separator;
// create a new file using the constructor that takes a name
mediaFile = new File(path + "IMG_" + timestamp + ".jpg");
Log.d(TAG, "File: " + Uri.fromFile(mediaFile));
// Return the files URI
Log.d(TAG, "Returning the files URI");
return Uri.fromFile(mediaFile);
} else {
return null;
}
}
/**
* check if external storage is available on the users device
*
* #return
*/
private boolean isExternalStorageAvailable() {
// find out what state external storage is in
String state = Environment.getExternalStorageState();
// if external storage is available, return true,
if (state.equals(Environment.MEDIA_MOUNTED)) {
return true;
} else {
return false;
}
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK) {
if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) {
if (data == null) {
Log.d(TAG, "Data is null");
Toast.makeText(getActivity(), getString(R.string.general_error), Toast.LENGTH_LONG).show();
} else {
Log.d(TAG, "Data: " + data);
// the intent has data, so set the media uri
Log.d(TAG, "adding the data using the getData() method");
mMediaUri = data.getData();
Log.d(TAG, "Media Uri: " + mMediaUri);
}
// ParseUser.getCurrentUser().put("profilePic", mMediaUri);
saveImageToParse();
}
} else if (resultCode != Activity.RESULT_CANCELED) {
Log.d(TAG, "Problem getting the picture from gallery");
// Toast.makeText(getActivity(), R.string.general_error, Toast.LENGTH_LONG).show();
}
}
public void saveImageToParse() {
Log.d(TAG, "entering saveImageToParse() method");
byte[] fileBytes = FileHelper.getByteArrayFromFile(getActivity(), mMediaUri);
fileBytes = FileHelper.reduceImageForUpload(fileBytes);
String fileName = FileHelper.getFileName(getActivity(), mMediaUri, "file");
ParseFile file = new ParseFile(fileName, fileBytes);
ParseUser.getCurrentUser().put("profilePic", file);
ParseUser.getCurrentUser().saveInBackground(new SaveCallback() {
public void done(ParseException e) {
if (e == null) {
Log.d(TAG, "Image saved successfully");
// myObjectSavedSuccessfully();
} else {
Log.d(TAG, "Image not saved");
// myObjectSaveDidNotSucceed();
}
}
});
}
.
package com.khackett.runmate.utils;
import android.content.Context;
import android.graphics.Bitmap;
import android.net.Uri;
import android.util.Log;
import org.apache.commons.io.IOUtils;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
// https://github.com/treehouse/treehouse_android_utilities
public class FileHelper {
public static final String TAG = FileHelper.class.getSimpleName();
public static final int SHORT_SIDE_TARGET = 1280;
public static byte[] getByteArrayFromFile(Context context, Uri uri) {
byte[] fileBytes = null;
InputStream inStream = null;
ByteArrayOutputStream outStream = null;
Log.d(TAG, "in the getByteArrayFromFile() method");
if (uri.getScheme() != null && uri.getScheme().equals("content")) {
try {
Log.d(TAG, "entering try to set inputstream");
inStream = context.getContentResolver().openInputStream(uri);
outStream = new ByteArrayOutputStream();
byte[] bytesFromFile = new byte[1024 * 1024]; // buffer size (1 MB)
int bytesRead = inStream.read(bytesFromFile);
while (bytesRead != -1) {
outStream.write(bytesFromFile, 0, bytesRead);
bytesRead = inStream.read(bytesFromFile);
}
fileBytes = outStream.toByteArray();
} catch (IOException e) {
Log.e(TAG, e.getMessage());
} finally {
try {
inStream.close();
outStream.close();
} catch (IOException e) { /*( Intentionally blank */ }
}
} else {
try {
File file = new File(uri.getPath());
FileInputStream fileInput = new FileInputStream(file);
fileBytes = IOUtils.toByteArray(fileInput);
} catch (IOException e) {
Log.e(TAG, e.getMessage());
}
}
return fileBytes;
}
public static byte[] reduceImageForUpload(byte[] imageData) {
Bitmap bitmap = ImageResizer.resizeImageMaintainAspectRatio(imageData, SHORT_SIDE_TARGET);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream);
byte[] reducedData = outputStream.toByteArray();
try {
outputStream.close();
} catch (IOException e) {
// Intentionally blank
}
return reducedData;
}
public static String getFileName(Context context, Uri uri, String fileType) {
String fileName = "uploaded_file.";
if (fileType.equals(ParseConstants.TYPE_IMAGE)) {
fileName += "png";
} else {
// For video, we want to get the actual file extension
if (uri.getScheme().equals("content")) {
// do it using the mime type
String mimeType = context.getContentResolver().getType(uri);
int slashIndex = mimeType.indexOf("/");
String fileExtension = mimeType.substring(slashIndex + 1);
fileName += fileExtension;
} else {
fileName = uri.getLastPathSegment();
}
}
return fileName;
}
}
.
09-01 20:15:49.322 23271-23271/com.khackett.runmate E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.khackett.runmate, PID: 23271
java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=67424, result=-1, data=Intent { }} to activity {com.khackett.runmate/com.khackett.runmate.ui.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.net.Uri.getScheme()' on a null object reference
at android.app.ActivityThread.deliverResults(ActivityThread.java:3574)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:3617)
at android.app.ActivityThread.access$1300(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1352)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.net.Uri.getScheme()' on a null object reference
at com.khackett.runmate.utils.FileHelper.getByteArrayFromFile(FileHelper.java:29)
at com.khackett.runmate.ui.MyProfileFragment.saveImageToParse(MyProfileFragment.java:233)
at com.khackett.runmate.ui.MyProfileFragment.onActivityResult(MyProfileFragment.java:210)
at android.support.v4.app.FragmentActivity.onActivityResult(FragmentActivity.java:165)
at android.app.Activity.dispatchActivityResult(Activity.java:6192)
at android.app.ActivityThread.deliverResults(ActivityThread.java:3570)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:3617)
at android.app.ActivityThread.access$1300(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1352)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
From the log, and your code, you can track that it is mMediaUri being null.
This should be caused by activity recreate because of screen rotation, for example, if your app usually run in Portrait, while the camera force to Landscape or you rotated when you use camera.
Anyway to solve this, you have to save the mMediaUrl and restore it in onCreate, modify your Fragment like this:
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
// Save the user's current state
savedInstanceState.putString("media_url", mMediaUrl.toString());
// Always call the superclass so it can save the view hierarchy state
super.onSaveInstanceState(savedInstanceState);
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState != null) {
mMediaUrl = Uri.parse(savedInstanceState.getString("media_url"));
}
}
Edit:
noticed another problem, change the followings:
public static final int TAKE_PHOTO_REQUEST = 1889;
public static final int PICK_PHOTO_REQUEST = 1888;
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK) {
if (requestCode == PICK_PHOTO_REQUEST) {
if (data == null) {
Log.d(TAG, "Data is null");
Toast.makeText(getActivity(), getString(R.string.general_error), Toast.LENGTH_LONG).show();
} else {
Log.d(TAG, "Data: " + data);
// the intent has data, so set the media uri
Log.d(TAG, "adding the data using the getData() method");
mMediaUri = data.getData();
Log.d(TAG, "Media Uri: " + mMediaUri);
}
// ParseUser.getCurrentUser().put("profilePic", mMediaUri);
saveImageToParse();
} else if(requestCode == TAKE_PHOTO_REQUEST) {
saveImageToParse();
}
} else if (resultCode != Activity.RESULT_CANCELED) {
Log.d(TAG, "Problem getting the picture from gallery");
// Toast.makeText(getActivity(), R.string.general_error, Toast.LENGTH_LONG).show();
}
}
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.VideoView;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
public class MainActivity extends Activity {
// Activity request codes
private static final int CAMERA_CAPTURE_VIDEO_REQUEST_CODE = 100;
public static final int MEDIA_TYPE_VIDEO = 1;
public static TextView output;
private VideoView videoPreview;
String[] fileList;
public static MainActivity ActivityContext =null;
// directory name to store captured images and videos
private static final String IMAGE_DIRECTORY_NAME = "Hello Camera";
private Uri fileUri; // file url to store image/video
private static File mediaStorageDir;
private ImageButton deletbtn, previewbtn, btnRecordVideo;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnRecordVideo = (ImageButton) findViewById(R.id.btnRecordVideo);
videoPreview = (VideoView) findViewById(R.id.videoPreview);
previewbtn = (ImageButton) findViewById(R.id.previewbtn);
deletbtn = (ImageButton) findViewById(R.id.deletbtn);
/*
* Record video button click event
*/
btnRecordVideo.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// record video
recordVideo();
}
});
previewbtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// record video
previewVideo();
}
});
deletbtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// record video
deleteVideo();
}
});
// Checking camera availability
if (!isDeviceSupportCamera()) {
Toast.makeText(getApplicationContext(),
"Sorry! Your device doesn't support camera",
Toast.LENGTH_LONG).show();
// will close the app if the device does't have camera
finish();
}
}
/**
* Checking device has camera hardware or not
* */
private boolean isDeviceSupportCamera() {
if (getApplicationContext().getPackageManager().hasSystemFeature(
PackageManager.FEATURE_CAMERA)) {
// this device has a camera
return true;
} else {
// no camera on this device
return false;
}
}
/*
* Recording video
*/
private void recordVideo() {
Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
fileUri = getOutputMediaFileUri(MEDIA_TYPE_VIDEO);
// Toast.makeText(getApplicationContext(), fileUri.toString(), Toast.LENGTH_LONG).show();
// set video quality
intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
intent.putExtra(MediaStore.EXTRA_DURATION_LIMIT, 180);
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); // set the image file
// name
// start the video capture Intent
startActivityForResult(intent, CAMERA_CAPTURE_VIDEO_REQUEST_CODE);
}
/**
* Receiving activity result method will be called after closing the camera
* */
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// if the result is capturing Image
if (requestCode == CAMERA_CAPTURE_VIDEO_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
// video successfully recorded
// preview the recorded video
//previewVideo();
Toast.makeText(getApplicationContext(),
"Video recorded", Toast.LENGTH_SHORT)
.show();
} else if (resultCode == RESULT_CANCELED) {
// user cancelled recording
Toast.makeText(getApplicationContext(),
"User cancelled video recording", Toast.LENGTH_SHORT)
.show();
} else {
// failed to record video
Toast.makeText(getApplicationContext(),
"Sorry! Failed to record video", Toast.LENGTH_SHORT)
.show();
}
}
}
/*
* Previewing recorded video
*/
private void previewVideo() {
try {
videoPreview.setVisibility(View.VISIBLE);
videoPreview.setVideoPath(fileUri.getPath());
// start playing
videoPreview.start();
} catch (Exception e) {
e.printStackTrace();
}
}
/** Create a file Uri for saving an image or video */
private static Uri getOutputMediaFileUri(int type){
return Uri.fromFile(getOutputMediaFile(type));
}
/** Create a File for saving an image or video */
private static File getOutputMediaFile(int type){
// Check that the SDCard is mounted
mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES),"MyCameraVideo");
// Create the storage directory(MyCameraVideo) if it does not exist
if (! mediaStorageDir.exists()){
if (! mediaStorageDir.mkdirs()){
output.setText("Failed to create directory MyCameraVideo.");
Toast.makeText(ActivityContext, "Failed to create directory MyCameraVideo.",
Toast.LENGTH_LONG).show();
Log.d("MyCameraVideo", "Failed to create directory MyCameraVideo.");
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss",
Locale.getDefault()).format(new Date());
File mediaFile;
if (type == MEDIA_TYPE_VIDEO) {
mediaFile = new File(mediaStorageDir.getPath() + File.separator
+ "VID_" + timeStamp + ".mp4");
} else {
return null;
}
return mediaFile;
}
private void deleteVideo( ) {
enter code here
File videoFiles = new File(Environment.getExternalStorageDirectory()+"/MyCameraVideo");
if(videoFiles.isDirectory())
{
fileList=videoFiles.list();
Log.d("hello",FileList );
}
for(int i=0;i<fileList.length;i++)
{
Log.e("Video:"+i+" File name",fileList[i]);
}
}
}
I am getting this issue.
please suggest me how to do this.
8868-8868/com.example.video.videoapp W/dalvikvm﹕ threadid=1: thread exiting with uncaught exception (group=0x41016ae0)
01-22 15:19:33.519 8868-8868/com.example.video.videoapp E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.NullPointerException
at com.example.video.videoapp.MainActivity.deleteVideo(MainActivity.java:238)
at com.example.video.videoapp.MainActivity.access$200(MainActivity.java:23)
at com.example.video.videoapp.MainActivity$3.onClick(MainActivity.java:76)
at android.view.View.performClick(View.java:4278)
at android.view.View$PerformClick.run(View.java:17429)
at android.os.Handler.handleCallback(Handler.java:725)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5099)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:803)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:570)
at dalvik.system.NativeStart.main(Native Method)
01-22 15:19:38.454 8868-8868/com.example.video.videoapp I/Process﹕ Sending signal. PID: 8868 SIG: 9
File videofiles=new File(Environment.getExternalStorageDirectory()+"/MyCameraVideo.mp4");
videofiles.delete();
Using file class you can do it
File file = new File(path_to_the_file);
boolean deleted = file.delete();
where path_to_the_fileis the path of the file you want to delete - for example:
/sdcard/YourDirectoryname/filename.extention
In your code you don't delete the file. You are just taking the files inside your MyCameraVideo folder. Use the below code to delete the files.
private void deleteVideo( ) {
File videoFiles = new File(Environment.getExternalStorageDirectory()+"/MyCameraVideo/");
if(videoFiles.isDirectory())
{
fileList=videoFiles.list();
Log.d("hello",fileList.toString());
}
for(int i=0;i<fileList.length;i++)
{
Log.e("Video:"+i+" File name",fileList[i]);
String path=Environment.getExternalStorageDirectory()+"/MyCameraVideo/"+fileList[i];
File file = new File(path);
file.delete();
}
}
Don't Forget to add these permissions in your Manifest.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
When Control is in onActivityResult, you can get the File path and with that you can delete the file if exist.
Review the code, hope it will help you.
Intent to Video Camera
intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY,
MediaRecorder.OutputFormat.MPEG_4);
long maxVideoSize = 15*1024*1024; // 15 MB
intent.putExtra(MediaStore.EXTRA_SIZE_LIMIT, maxVideoSize);
startActivityForResult(intent, REQUEST_VIDEO_CAMERA);
Code in onActivityResult:
if (requestCode == REQUEST_VIDEO_CAMERA) {
if (resultCode == RESULT_OK) {
Log.d("In video from camera", "In video from camera");
Uri videoUri = data.getData();
String[] filePathColumn = { MediaStore.Images.Media.DATA };
Cursor cursor = getContentResolver().query(videoUri,
filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String filePath = cursor.getString(columnIndex);
String mMediaFilePath = filePath; //File path of Video Recorded.
cursor.close();
//Delete File from Location.
File videoFile = new File(mMediaFilePath);
if(videoFile.exists())
{
videoFile.delete();
}
}
}
I think I'm doing something wrong with my paths but I can't figure out what. I am testing on a Nexus 7 if that's relevant. Following examples I tried to copy the tessdata folder over to the SD card however it keeps telling me unable to copy file not found. I don't quite understand why. (I have the tesseract project as a library and I have the tessdata folder copied into assets).
All help is appreciated thanks!
Code:
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import android.app.Activity;
import android.content.Intent;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.media.ExifInterface;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
import com.googlecode.tesseract.android.TessBaseAPI;
public class MainActivity extends Activity {
private static ImageView imageView;
// protected static Bitmap bit;
protected static Bitmap mImageBitmap;
// protected static String DATA_PATH;
public static final String STORAGE_PATH = Environment.getExternalStorageDirectory().toString() + "/rjb";
protected static String tesspath = STORAGE_PATH + "/tessdata";
protected static String savepath = null;
protected static String TAG = "OCR";
protected static String lang = "eng";
// main method
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// This is my image view for to show the image with
imageView = (ImageView) this.findViewById(R.id.imageView1);
// this is the take a photo button
Button photoButton = (Button) this.findViewById(R.id.button1);
//check if the rjb directory is there
//make it if its not
createmydir();
//if (!(new File(STORAGE_PATH + File.separator + "tessdata" + File.separator + lang + ".traineddata")).exists()) {
try {
AssetManager assetManager = this.getAssets();
//open the asset manager and open the traineddata path
InputStream in = assetManager.open("tessdata/eng.traineddata");
OutputStream out = new FileOutputStream(tesspath + "/eng.traineddata");
byte[] buf = new byte[8024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
} catch (IOException e) {
android.util.Log.e(TAG, "Was unable to copy " + lang
+ " traineddata " + e.toString());
android.util.Log.e(TAG, "IM PRINTING THE STACK TRACE");
e.printStackTrace();
}
//} else {
processImage(STORAGE_PATH + File.separator + "savedAndroid.jpg");
//}
photoButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// CALL THE PICTURE (this works)
dispatchTakePictureIntent(0);
}
});
}
private void createmydir() {
File t = new File(STORAGE_PATH);
if(t.exists()) {
Toast.makeText(getApplicationContext(), "IM TOASTIN CAUSE IT EXISTS", Toast.LENGTH_LONG).show();
}
else {
t.mkdirs();
Toast.makeText(getApplicationContext(), "IM TOASTIN CUZ I MADE IT EXIST", Toast.LENGTH_LONG).show();
}
}
private void handleSmallCameraPhoto(Intent intent) {
Bundle extras = intent.getExtras();
mImageBitmap = (Bitmap) extras.get("data");
imageView.setImageBitmap(mImageBitmap);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 4;
saveImageAndroid(mImageBitmap);
Bitmap bitmap = BitmapFactory.decodeFile(savepath, options);
ExifInterface exif;
try {
exif = new ExifInterface(savepath);
int exifOrientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,ExifInterface.ORIENTATION_NORMAL);
int rotate = 0;
switch (exifOrientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
rotate = 90;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
rotate = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_270:
rotate = 270;
break;
}
if (rotate != 0) {
int w = bitmap.getWidth();
int h = bitmap.getHeight();
// Setting pre rotate
Matrix mtx = new Matrix();
mtx.preRotate(rotate);
// Rotating Bitmap & convert to ARGB_8888, required by tess
bitmap = Bitmap.createBitmap(bitmap, 0, 0, w, h, mtx, false);
bitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true);
}
// DATA_PATH = getDataPath();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
handleSmallCameraPhoto(data);
}
// write bitmap to storage
// saves it as savedandroid.jpg
// saves location in savepath
private void saveImageAndroid(final Bitmap passedBitmap) {
try {
savepath = STORAGE_PATH + File.separator + "savedAndroid.jpg";
FileOutputStream mFileOutStream = new FileOutputStream(savepath);
passedBitmap.compress(Bitmap.CompressFormat.JPEG, 100,mFileOutStream);
mFileOutStream.flush();
mFileOutStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
private void dispatchTakePictureIntent(int actionCode) {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(takePictureIntent, actionCode);
}
private void processImage(final String filePath) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2;
options.inPurgeable = true;
Bitmap bitmap = BitmapFactory.decodeFile(filePath, options);
if (bitmap != null) {
/*
* was for rotating but no longer needed int width =
* bitmap.getWidth(); int height = bitmap.getHeight(); Matrix matrix
* = new Matrix(); matrix.postRotate(rotation); bitmap =
* Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, false);
* bitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true);
*/
TessBaseAPI baseApi = new TessBaseAPI();
baseApi.setDebug(true);
baseApi.init(STORAGE_PATH, "eng");
baseApi.setPageSegMode(100);
baseApi.setPageSegMode(7);
baseApi.setImage(bitmap);
String recognizedText = baseApi.getUTF8Text();
android.util.Log.i(TAG, "recognizedText: 1 " + recognizedText);
baseApi.end();
if (lang.equalsIgnoreCase("eng")) {
recognizedText = recognizedText
.replaceAll("[^a-zA-Z0-9]+", " ");
}
android.util.Log.i(TAG,
"recognizedText: 2 " + recognizedText.trim());
}
}
}
First try to place the files on sd card and just try simple ocr on an simple image like ear, if that works then go for copying the language files through program, because of that you may come to know where the error is.