i'm getting this error which i can't understand why. I'm fairly new to java. What i'm trying to do is start a new thread which will handle all the save image processes.
Error:
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
at android.os.Handler.<init>(Handler.java:200)
at android.os.Handler.<init>(Handler.java:114)
at android.app.Dialog.<init>(Dialog.java:108)
at android.app.AlertDialog.<init>(AlertDialog.java:125)
at android.app.AlertDialog$Builder.create(AlertDialog.java:967)
at android.app.AlertDialog$Builder.show(AlertDialog.java:986)
at com.example.matts.myapplication.MainActivity$1.handleMessage(MainActivity.java:37)
at com.example.matts.myapplication.Saving.run(Saving.java:54)
at java.lang.Thread.run(Thread.java:818)
Here's my code.
Main:
package com.example..myapplication;
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.net.Uri;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.provider.MediaStore;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Date;
import java.text.SimpleDateFormat;
public class MainActivity extends Activity {
static final int REQUEST_IMAGE_CAPTURE = 1;
ImageView imageView;
private static final String TAG = "MyActivity";
Bitmap image;
Handler goodHandler = new Handler() {
@Override
public void handleMessage(Message message) {
AlertDialog.Builder builder = new AlertDialog.Builder(getApplicationContext());
builder.setMessage("File Saved").show();
}
};
Handler badHandler = new Handler() {
@Override
public void handleMessage(Message message) {
AlertDialog.Builder builder = new AlertDialog.Builder(getApplicationContext());
builder.setMessage("File Save failed").show();
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
openCamera();
setContentView(R.layout.activity_main);
findViewById(R.id.captureImage).bringToFront();
findViewById(R.id.saveImage).bringToFront();
imageView = (ImageView) findViewById(R.id.imageView2);
}
protected void onSaveInstanceState(Bundle outState){
File file = new File(Environment.getExternalStorageDirectory() + File.separator + "TMP.jpg");
file.delete();
}
public void openCamera() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File file = new File(Environment.getExternalStorageDirectory() + File.separator + "TMP.jpg");
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
//Check that request code matches ours:
if (requestCode == REQUEST_IMAGE_CAPTURE) {
//Get our saved file into a bitmap object:
File file = new File(Environment.getExternalStorageDirectory() + File.separator + "TMP.jpg");
Bitmap image = decodeSampledBitmapFromFile(file.getAbsolutePath(), 1000, 700);
imageView.setImageBitmap(image);
}
}
// Reduce the amount of dynamic heap used by expanding the JPEG into a memory array that's already scaled to match the size of the destination view
public static Bitmap decodeSampledBitmapFromFile(String path, int reqWidth, int reqHeight) { // BEST QUALITY MATCH
//First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, options);
// Calculate inSampleSize, Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
options.inPreferredConfig = Bitmap.Config.RGB_565;
int inSampleSize = 1;
if (height > reqHeight) {
inSampleSize = Math.round((float) height / (float) reqHeight);
}
int expectedWidth = width / inSampleSize;
if (expectedWidth > reqWidth) {
//if(Math.round((float)width / (float)reqWidth) > inSampleSize) // If bigger SampSize..
inSampleSize = Math.round((float) width / (float) reqWidth);
}
options.inSampleSize = inSampleSize;
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(path, options);
}
public void capture_btn(View v) {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File file = new File(Environment.getExternalStorageDirectory() + File.separator + "TMP.jpg");
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
public void storeImage(Bitmap image) {
imageView.buildDrawingCache();
Bitmap bm_img = imageView.getDrawingCache();
Saving saving = new Saving(bm_img, goodHandler, badHandler);
Thread thread = new Thread(saving);
thread.start();
}
public void save_btn(View v) {
DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
switch (which){
case DialogInterface.BUTTON_POSITIVE:
storeImage(image);
break;
case DialogInterface.BUTTON_NEGATIVE:
break;
}
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Are you sure?").setPositiveButton("Yes", dialogClickListener)
.setNegativeButton("No", dialogClickListener).show();
} //notification messages
}
Saving:
package com.example..myapplication;
import android.graphics.Bitmap;
import android.os.Environment;
import android.os.Message;
import android.util.Log;
import android.os.Handler;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Saving implements Runnable {
private Bitmap image;
private android.os.Handler goodHandler;
private android.os.Handler badHandler;
private static final String TAG = "Saving";
public Saving(Bitmap in, Handler hinGood,Handler hinBad) {
image = in;
goodHandler = hinGood;
badHandler = hinBad;
}
@Override
public void run() {
File file = getOutputMediaFile();
if (file == null) {
return;
}
try {
FileOutputStream fos = new FileOutputStream(file);
image.compress(Bitmap.CompressFormat.PNG, 90, fos);
fos.close();
} catch (FileNotFoundException e) {
Log.d(TAG, "File not found: " + e.getMessage());
badHandler.handleMessage(new Message());
return;
} catch (IOException e) {
Log.d(TAG, "Error accessing file: " + e.getMessage());
badHandler.handleMessage(new Message());
return;
}
goodHandler.handleMessage(new Message());
}
public File getOutputMediaFile(){
// To be safe, you should check that the SDCard is mounted
// using Environment.getExternalStorageState() before doing this.
File mediaStorageDir = new File(Environment.getExternalStorageDirectory()
+ "/Pictures/Wiki_camera"
+ "/Photos");
// This location works best if you want the created images to be shared
// between applications and persist after your app has been uninstalled.
// Create the storage directory if it does not exist
if (! mediaStorageDir.exists()){
if (! mediaStorageDir.mkdirs()){
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("ddMMyyyy_HHmm").format(new Date());
File mediaFile;
String mImageName="camera_wiki"+ timeStamp +".jpg";
mediaFile = new File(mediaStorageDir.getPath() + File.separator + mImageName);
return mediaFile;
}
}
I've added whole of the main class and the saving class.
storeImage()
code please. – pathfinderelitegoodHandler
andbadHandler
defined? – pathfinderelite