I am writing an app with custom camera facility. In my custom camera after capturing i am drawing the captured image to canvas and providing free hand drawing over that captured imgae and then save option. At the time of saving i am save it as two images which means the one which contains free hand drawing and another one which contains no drawing. Saving is done by writing output stream and compressing bitmaps. The saving and compression of bitmaps done in two separate async tasks. The issue is that i can capture image up to 16 or 17 times but after that capturing and editing then pressing save button i am getting the exception "vm aborting Fatal signal 11 (SIGSEGV) at 0xdeadd00d (code=1)" .
Async Task one
public class SaveOriginalImage extends AsyncTask<String, Void, String> {
OutputStream dataOutputStream;
Bitmap bitMapOriginalImage;
String fileName;
Activity activityContext;
ProgressDialog progressDialog;
String sbCaption;
String fileType;
public SaveOriginalImage(Bitmap bitMap, String filePath,
Activity currentActivity, String fileCaption) {
this.bitMapOriginalImage = bitMap;
this.fileName = filePath;
this.activityContext = currentActivity;
this.sbCaption = fileCaption;
}
#Override
protected String doInBackground(String... params) {
try {
dataOutputStream = new FileOutputStream(fileName);
bitMapOriginalImage
.compress(CompressFormat.PNG, 100, dataOutputStream);
Collection.lastImageFilePath = fileName;
dataOutputStream.flush();
dataOutputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected void onPostExecute(String result) {
if (bitMapOriginalImage != null) {
bitMapOriginalImage.recycle();
bitMapOriginalImage = null;
}
}
}
Async Task 2
public class SaveFreeHandImage extends AsyncTask<String, Void, String> {
OutputStream dataOutputStream;
Bitmap bitMapToSave;
String fileName;
Activity activityContext;
ProgressDialog progressDialog;
String sbCaption;
String className;
String fileType;
public SaveFreeHandImage(Bitmap bitMap, String filePath,
Activity currentActivity, String fileCaption, String className) {
this.bitMapToSave = bitMap;
this.fileName = filePath;
this.activityContext = currentActivity;
this.sbCaption = fileCaption;
this.className = className;
}
#Override
protected String doInBackground(String... params) {
try {
dataOutputStream = new FileOutputStream(fileName);
bitMapToSave.compress(CompressFormat.PNG, 100, dataOutputStream);
Collection.lastImageFilePath = fileName;
try {
dataOutputStream.flush();
dataOutputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String result) {
// super.onPostExecute(result);
progressDialog.dismiss();
HomeFinal.showCustomToast("Drawing saved to SD card ", 0, 0,
activityContext);
Collection.isNewImageAdded = false;
DrawingView.colorD = Color.parseColor("#000000");
if (DrawingView.paths != null) {
if (DrawingView.paths.size() >= 1) {
DrawingView.paths.clear();
}
}
if (bitMapToSave != null) {
if (!bitMapToSave.isRecycled()) {
bitMapToSave.recycle();
bitMapToSave = null;
}
}
}
#Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog = ProgressDialog.show(activityContext, "", "Saving..");
}
}
I am testing on lenovo a-300h 7 inch tablet . Please give me solution. Thanks in advance.
i solved myself. It is because of excess use of bitmaps, after handling bitmaps it worked perfectly.
Related
I create several picture objects that each download their own image. But frequently, the same image shows up for several (or all) of the objects.
public class Picture {
private String userID;
private String fileName;
private String baseURI;
private Bitmap img;
public Picture () {
this.userID = "";
this.fileName = "";
this.baseURI = "";
}
/**
* Retrieves the UUID of the User
*
* #return - String
*/
public String getUserID() {return userID;}
public void setUserID(String _userID) {userID = _userID;}
/**
* Retrieves the Filename of the Picture
*
* #return - String
*/
public String getFileName() {return fileName;}
public void setFileName(String fileName) {
this.fileName = fileName;
//Don't retrieve a file from the server if the filename is empty or it is a placeholder
if (fileName != "" && fileName != "NoNewPicure" && fileName != "NewPicture") {
new RetrieveImageTask(getFileNameURI(), img) {
#Override
protected void onPostExecute(Bitmap result) {
super.onPostExecute(result);
setPreview(result);
}
}.execute();
}
}
private URI getFileNameURI() {
return URI.create(baseURI.concat(fileName));
}
private void setBaseURI(String baseURI) {
this.baseURI = baseURI;
}
/**
* Accesors for preview image
* #return - Image
*/
#Bindable
public Bitmap getPreview() {return img;}
public void setPreview(Bitmap img) {
this.img = img;
notifyPropertyChanged(BR.preview);
}
private static class RetrieveImageTask extends AsyncTask<URI, Void, Bitmap> {
static URI uriString;
static Bitmap myBitmap;
private Exception exception;
RetrieveImageTask(URI uri, Bitmap bitmap) {
uriString = uri;
this.myBitmap = bitmap;
}
protected Bitmap doInBackground(URI... src) {
try {
Log.e("src",uriString.toString());
URL url = new URL(uriString.toString());
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
Bitmap myBitmap = BitmapFactory.decodeStream(input);
Log.e("Bitmap","returned");
return myBitmap;
} catch (IOException e) {
e.printStackTrace();
Log.e("Exception",e.getMessage());
return null;
}
}
protected void onPostExecute(Bitmap result) {
//Do nothing
}
}
}
In code the images are called from a for loop:
for (int i = 0; i < jArray.length(); i++) {
JSONObject json_data = jArray.getJSONObject(i);
Picture pic = new Picture();
pic.fromJSON(json_data);
result.add(pic);
}
It appears as though when the Async task returns, several (or all) of the handlers fire. Any ideas on how to fix this? I've tried adding in this:
#Override
protected void onPostExecute(Bitmap result) {
super.onPostExecute(result);
URI thisURI = getFileNameURI();
if (uriString.equals(thisURI)) {
setPreview(result);
}
}
But then only one Picture object actually gets an image.
The answer was quite simple after hearing Another brick in the wall. You can't have any pudding if you don't eat your meat! I can't have my bitmap if the file hasn't downloaded. But I CAN put my bowl where the pudding is going to be so that after I eat my meat, I can eat my pudding. I changed my AsynTask like such:
private class RetrieveImageTask extends AsyncTask<URI, Void, Boolean> {
public URI uriString;
public Picture pic;
RetrieveImageTask(URI uri) {
uriString = uri;
}
protected Boolean doInBackground(URI... src) {
try {
Log.e("src",uriString.toString());
URL url = new URL(uriString.toString());
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
Bitmap bitmap = BitmapFactory.decodeStream(input);
Log.e("Bitmap","returned");
pic.setPreview(bitmap);
return true;
} catch (IOException e) {
e.printStackTrace();
Log.e("Exception",e.getMessage());
return null;
}
}
protected void onPostExecute() {
//Do nothing
}
}
Note the public variables in the class wrapper. Now when I call my task (code changed from above):
RetrieveImageTask task = new RetrieveImageTask(getFileNameURI());
task.pic = this;
task.execute();
my bowl will be where the pudding is going to be. IE. I put the calling object as a variable in the private AsyncTask class which populates what I need when it is finished running. :D My bowl of pudding is full after I eat my meat!!!!
My code,
public static Bitmap retriveVideoFrameFromVideo(String videoPath) throws Throwable {
Bitmap bitmap = null;
MediaMetadataRetriever mediaMetadataRetriever = null;
try {
mediaMetadataRetriever = new MediaMetadataRetriever();
if (Build.VERSION.SDK_INT >= 14)
mediaMetadataRetriever.setDataSource(videoPath, new HashMap<String, String>());
else
mediaMetadataRetriever.setDataSource(videoPath);
// mediaMetadataRetriever.setDataSource(videoPath);
bitmap = mediaMetadataRetriever.getFrameAtTime();
} catch (Exception e) {
e.printStackTrace();
throw new Throwable(
"Exception in retriveVideoFrameFromVideo(String videoPath)"
+ e.getMessage());
} finally {
if (mediaMetadataRetriever != null) {
mediaMetadataRetriever.release();
}
}
return bitmap;
}
This is Create thumbnail but take much time I used this with ListView then ListView being hangup.
You need run this task in Async Method Like this in onBindViewHolder() if you are using RecycleView or put on getView() if your are using ListView:
new AsyncTask<String, String, String>() {
Bitmap bitmapVideo;
#Override
protected String doInBackground(String... strings) {
try {
//Your method call here
bitmapVideo =retriveVideoFrameFromVideo(strings[0]);
} catch (Throwable throwable) {
throwable.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String id) {
super.onPostExecute(id);
if (bitmapVideo != null) {
//Load your bitmap here
holder.imgVideoThumb.setImageBitmap(bitmapVideo);
}
}
}.execute(getYourVideolink());
For better efficiency you save the bitmap image in local and before calling AsyncTask() check weather this image is already save in local if its their than load from local and no new to run AsyncTask() again
This is my first async task, which gets called first, it gets data from server and then onPostExecute it executes other async task, which downloads and sets image.
private class GetData extends AsyncTask<String, Void, Void> {
private final HttpClient client = new DefaultHttpClient();
private String content;
private String error = null;
#Override
protected void onPreExecute() {
}
#Override
protected void onProgressUpdate(Void... progress) {
}
#Override
protected Void doInBackground(String... params) {
try {
HttpGet httpget = new HttpGet(params[0]);
ResponseHandler<String> responseHandler = new BasicResponseHandler();
content = client.execute(httpget, responseHandler);
} catch (ClientProtocolException e) {
error = e.getMessage();
cancel(true);
} catch (IOException e) {
error = e.getMessage();
cancel(true);
}
return null;
}
#Override
protected void onPostExecute(Void result) {
if (error == null) {
try {
JSONObject dataDishes = new JSONObject(content);
Log.d("DISHES", dataDishes.toString());
ArrayList<DishModel> dishData = new ArrayList<DishModel>();
for (int i = 0; i < 8; i++) {
DishModel model = new DishModel();
model.setName("Company " + i);
model.setDesc("desc" + i);
//TODO: set data img
new GetImage(model).execute("http://example.com/" + (i + 1) + ".png");
dishData.add(model);
}
ListView listAllDishes = (ListView) getView().findViewById(R.id.listView);
DishRowAdapter adapterAllDishes = new DishRowAdapter(getActivity(),
R.layout.dish_row, dishData);
listAllDishes.setAdapter(adapterAllDishes);
} catch (JSONException e) {
Log.d("DISHES", e.toString());
}
} else {
Log.e("DISHES", error);
}
}
}
This is another async task, it downloads image and onPostExecute it sets image to passed model.
private class GetImage extends AsyncTask<String, Void, Void> {
private DishModel model;
private Bitmap bmp;
public getImage(DishModel model) {
this.model = model;
}
#Override
protected void onPreExecute() {
}
#Override
protected void onProgressUpdate(Void... progress) {
}
#Override
protected Void doInBackground(String... params) {
try {
URL url = new URL(params[0]);
Log.d("DISHES", params[0]);
try {
bmp = BitmapFactory.decodeStream(url.openConnection().getInputStream());
} catch (IOException e) {
Log.d("DISHES", e.toString());
}
} catch (MalformedURLException e) {
Log.d("DISHES", e.toString());
}
return null;
}
#Override
protected void onPostExecute(Void result) {
model.setPhoto(bmp);
}
}
It works if I do both data/image download proccess in one AsyncTask doInBackground(String... params), but it doesnt when I split data and image downloading into seperate async tasks. Furthermore I dont get any exceptions or errors.
UPDATE: Images shows up when i switch views..
At first, getImage and getData are classes, and classes names in Java are capitalized.
Technically, you can run another AsyncTask from onProgressUpdate() or onPostExecute() - https://stackoverflow.com/a/5780190/1159507
So, try to put the breakpoint in second AsyncTask call and debug is it called.
In my app iam trying to retrieve the images of the phonebook contact images and display in a list.below is my code
public InputStream getContactPhoto(Context context, String profileId){
try{
ContentResolver cr = context.getContentResolver();
Uri uri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, Long.parseLong(profileId));
return ContactsContract.Contacts.openContactPhotoInputStream(cr, uri);
}catch(Exception e){
return null;
}
}
private Bitmap loadContactPhoto(ContentResolver cr, long id) {
Uri uri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, id);
InputStream input = ContactsContract.Contacts.openContactPhotoInputStream(cr, uri);
if (input == null) {
return null;
}
return BitmapFactory.decodeStream(input);
}
its working but somehow it not smooth, so wanna implement getting images using asynctask
Any suggestion on how to implement using the above code
If you're using, for example, an ImageView and want to load a picture (in this example, it retrieves an image from the SDCard), you could do this:
-Create a custom class that extends ImageView
public class SDImageView extends CacheableImageView {
...
}
-Create a method called load() (or whatever you want) with your needed parameters. In my case is the path of the image:
public final void loadImage(final String tpath) {
if (tpath == null) {
return;
}
SDLoadAsyncTask.load(this, tpath);
}
-Create a class that extends AsyncTask and implement the operations you want to do in the doInBackground method
private static class SDLoadAsyncTask extends AsyncTask<Void, Void, Bitmap> {
final SDImageView view;
final String path;
private SDLoadAsyncTask(SDImageView view, String path) {
this.view = view;
this.path = path;
}
#Override
protected final Bitmap doInBackground(Void... params) {
Bitmap bmp = null;
InputStream is = null;
try {
is = new FileInputStream(mContext.getExternalFilesDir(null) + "/" + path);
bmp = BitmapFactory.decodeStream(is);
} catch (Exception e) {
Utils.logMsg("Exception for img " + path, e);
} finally {
try {
is.close();
} catch (Exception e2) {
}
}
return bmp;
#Override
protected final void onPostExecute(Bitmap result) {
view.setImageBitmap(result);
}
}
I have an Async running to get data from a page I've created. It get's the text just fine, but when I try and get the image from the image src via another class the app force closes. Here is the code that it force closes on:
public class FullReportActivity extends NavigationActivity {
private TextView textView;
private String url = "http://www.backcountryskiers.com/sac/sac-full.html";
private ImageView ivDangerRose;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
// tell which region this covers
getSupportActionBar().setSubtitle("...from Sierra Avalanche Center");
setContentView(R.layout.activity_fullreport);
textView = (TextView) findViewById(R.id.todaysReport);
ivDangerRose = (ImageView) findViewById(R.id.dangerRose);
fetcher task = new fetcher();
task.execute();
}
// GET THE IMAGE and RETURN IT
public static Bitmap getBitmapFromURL(String src) {
try {
URL url = new URL(src);
HttpURLConnection connection = (HttpURLConnection) url
.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
Bitmap myBitmap = BitmapFactory.decodeStream(input);
return myBitmap;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
class fetcher extends AsyncTask<String, Void, String> {
private ProgressDialog dialog = new ProgressDialog(
FullReportActivity.this);
private Document doc = null;
private Document parse = null;
private String results = null;
private String reportDate = null;
private Bitmap bimage = null;
#Override
protected String doInBackground(String... params) {
try {
doc = Jsoup.connect(url).get();
Log.e("Jsoup", "...is working...");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.e("Exception", e.getMessage());
}
parse = Jsoup.parse(doc.html());
results = doc.select("#fullReport").outerHtml();
Element dangerRoseImg = doc.getElementById("reportRose")
.select("img").first();
String dangerRoseSrc = dangerRoseImg.absUrl("src");
Log.i("Report Rose IMG", dangerRoseSrc);
bimage = getBitmapFromURL(dangerRoseSrc);
ivDangerRose.setImageBitmap(bimage);
return results;
}
#Override
protected void onPostExecute(String result) {
dialog.dismiss();
// smooth out the long scrolling...
textView.setMovementMethod(ScrollingMovementMethod.getInstance());
reportDate = parse.select("#reportDate").outerHtml();
textView.setText(Html.fromHtml(reportDate + results));
textView.setPadding(30, 20, 20, 10);
}
#Override
protected void onPreExecute() {
dialog.setMessage("Loading Full Report from the Sierra Avalanche Center...");
dialog.show();
}
}
}
I have run this Async alone to get the image like so without a force close and I don't understand what i am doing different besides calling the method:
public class MainActivity extends Activity {
public String durl = "http://www.sierraavalanchecenter.org/dangerrose.png?a=2955";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new DownloadImageTask((ImageView) findViewById(R.id.dangerrose))
.execute(durl);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
ImageView bmImage;
public DownloadImageTask(ImageView bmImage) {
this.bmImage = bmImage;
}
protected Bitmap doInBackground(String... urls) {
String urldisplay = urls[0];
Bitmap drose = null;
try {
InputStream in = new java.net.URL(urldisplay).openStream();
drose = BitmapFactory.decodeStream(in);
} catch (Exception e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return drose;
}
protected void onPostExecute(Bitmap result) {
bmImage.setImageBitmap(result);
}
}
}
This class gets the image src and creates a bitmap and puts it into an ImageView, what is different here than on my first class???
Frustrated.
You can not modify UI from background thread.
move ivDangerRose.setImageBitmap(bimage); in onPostExecute
In the method doInBackground
remove --> ivDangerRose.setImageBitmap(bimage);
as you can't modify UI in background process.
If you still want you can try runOnUiThread Method
In doInBackground() we should not access the content of activity.