getWidth must be called from UI thread..How do i fix it??Im trying to create pdf file..but getWidth,getHeight and getCanvas is coming up errors!!!
private class PdfGenerationTask extends AsyncTask<Void, Void, String> {
#Override
protected String doInBackground(Void... params) {
PdfDocument document = new PdfDocument();
// repaint the user's text into the page
View content = findViewById(R.id.pdf_content);
// crate a page description
int pageNumber = 1;
PageInfo pageInfo = new PageInfo.Builder(content.getWidth(),
content.getHeight() - 20, pageNumber).create();
// create a new page from the PageInfo
Page page = document.startPage(pageInfo);
content.draw(page.getCanvas());
// do final processing of the page
document.finishPage(page);
SimpleDateFormat sdf = new SimpleDateFormat("ddMMyyyyhhmmss");
String pdfName = "pdfdemo"
+ sdf.format(Calendar.getInstance().getTime()) + ".pdf";
File outputFile = new File("/sdcard/PDFDemo_AndroidSRC/", pdfName);
try {
outputFile.createNewFile();
OutputStream out = new FileOutputStream(outputFile);
document.writeTo(out);
document.close();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
return outputFile.getPath();
}
You can get the dimension of your screen like that:
Display display = getWindowManager().getDefaultDisplay();
int screenWidth = display.getWidth();
int screenHeight = display.getHeight();
But it seems to be deprecated. Get it like that now:
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int screenWidth = metrics.heightPixels;
int screenHeight = metrics.widthPixels;
Implement onPreExecute of AsyncTask and Do the calling of getHeight,getWidth and getCanvas
private class PdfGenerationTask extends AsyncTask<Void, Void, String> {
#Override
protected String onPreExecute(Void params){
this.height=getHeight();
this.width=getWidth();
}
#Override
protected String doInBackground(Void... params) {
PdfDocument document = new PdfDocument();
// repaint the user's text into the page
View content = findViewById(R.id.pdf_content);
// crate a page description
int pageNumber = 1;
PageInfo pageInfo = new PageInfo.Builder(content.getWidth(),
content.getHeight() - 20, pageNumber).create();
// create a new page from the PageInfo
Page page = document.startPage(pageInfo);
content.draw(page.getCanvas());
// do final processing of the page
document.finishPage(page);
SimpleDateFormat sdf = new SimpleDateFormat("ddMMyyyyhhmmss");
String pdfName = "pdfdemo"
+ sdf.format(Calendar.getInstance().getTime()) + ".pdf";
File outputFile = new File("/sdcard/PDFDemo_AndroidSRC/", pdfName);
try {
outputFile.createNewFile();
OutputStream out = new FileOutputStream(outputFile);
document.writeTo(out);
document.close();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
return outputFile.getPath();
}
AsyncTask runs on Different Thread and UI operations happens on Main Thread so you can't get UI related info from different Thread. You have to pass UI related data to your AsyncTask and have work done.
In your Activity's onCreate() method get dimensions like this
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int screenWidth = metrics.heightPixels;
int screenHeight = metrics.widthPixels;
Canvas canvas = page.getCanvas();
and pass this to your asyncTask as follows
PdfGenerationTask pdfGenerationTask = new PdfGenerationTask(screenWidth, screenHeight, canvas);
pdfGenerationTask.execute();
and update your PdfGenerationTask class as follows
private class PdfGenerationTask extends AsyncTask<Void, Void, String> {
int width, height;
Canvas canvas;
PdfGenerationTask(int width, int height, Canvas canvas) {
this.width = width;
this.height = height;
this.canvas = canvas;
}
#Override
protected String doInBackground(Void... params) {
PdfDocument document = new PdfDocument();
// repaint the user's text into the page
View content = findViewById(R.id.pdf_content);
// crate a page description
int pageNumber = 1;
PageInfo pageInfo = new PageInfo.Builder(width,
height - 20, pageNumber).create();
// create a new page from the PageInfo
Page page = document.startPage(pageInfo);
content.draw(canvas);
// do final processing of the page
document.finishPage(page);
SimpleDateFormat sdf = new SimpleDateFormat("ddMMyyyyhhmmss");
String pdfName = "pdfdemo"
+ sdf.format(Calendar.getInstance().getTime()) + ".pdf";
File outputFile = new File("/sdcard/PDFDemo_AndroidSRC/", pdfName);
try {
outputFile.createNewFile();
OutputStream out = new FileOutputStream(outputFile);
document.writeTo(out);
document.close();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
return outputFile.getPath();
}
Related
I was using RecyclerView to create PDF previously. I want to add share and print functionality for which I want to create PDF with content in it. The method I was using was
public static void generatePDF(RecyclerView view, boolean isShareTrue, Context context, boolean isWeekly) {
RecyclerView.Adapter adapter = view.getAdapter();
Bitmap bigBitmap = null;
if (adapter != null) {
int size = adapter.getItemCount();
int height = 0;
Paint paint = new Paint();
int iHeight = 0;
final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
// Use 1/8th of the available memory for this memory cache.
final int cacheSize = maxMemory / 8;
LruCache<String, Bitmap> bitmaCache = new LruCache<>(cacheSize);
for (int i = 0; i < size; i++) {
RecyclerView.ViewHolder holder = adapter.createViewHolder(view, adapter.getItemViewType(i));
adapter.onBindViewHolder(holder, i);
holder.itemView.measure(View.MeasureSpec.makeMeasureSpec(view.getWidth(), View.MeasureSpec.EXACTLY),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
holder.itemView.layout(0, 0, holder.itemView.getMeasuredWidth(), holder.itemView.getMeasuredHeight());
holder.itemView.setDrawingCacheEnabled(true);
holder.itemView.buildDrawingCache();
Bitmap drawingCache = holder.itemView.getDrawingCache();
if (drawingCache != null) {
bitmaCache.put(String.valueOf(i), drawingCache);
}
height += holder.itemView.getMeasuredHeight();
}
bigBitmap = Bitmap.createBitmap(view.getMeasuredWidth(), height, Bitmap.Config.ARGB_8888);
Canvas bigCanvas = new Canvas(bigBitmap);
bigCanvas.drawColor(Color.WHITE);
Document document = new Document(PageSize.A4);
File file;
if (isWeekly)
file = new File(Environment.getExternalStorageDirectory(), "Weekly_list_" + AppPreferences.INSTANCE.getUserId() + ".pdf");
else
file = new File(Environment.getExternalStorageDirectory(), "Open_Cycle_List_" + AppPreferences.INSTANCE.getUserId() + ".pdf");
try {
PdfWriter.getInstance(document, new FileOutputStream(file));
} catch (DocumentException | FileNotFoundException e) {
e.printStackTrace();
}
for (int i = 0; i < size; i++) {
try {
//Adding the content to the document
Bitmap bmp = bitmaCache.get(String.valueOf(i));
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.PNG, 100, stream);
Image image = Image.getInstance(stream.toByteArray());
float scaler = ((document.getPageSize().getWidth() - document.leftMargin()
- document.rightMargin() - 0) / image.getWidth()) * 100; // 0 means you have no indentation. If you have any, change it.
image.scalePercent(scaler);
image.setAlignment(com.itextpdf.text.Image.ALIGN_CENTER | com.itextpdf.text.Image.ALIGN_TOP);
if (!document.isOpen()) {
document.open();
}
document.add(image);
} catch (Exception ex) {
Log.e("TAG-ORDER PRINT ERROR", ex.getMessage());
}
}
if (document.isOpen()) {
document.close();
}
if (isShareTrue) {
Intent intentShareFile = new Intent(Intent.ACTION_SEND);
if (file.exists()) {
Uri pdfUri;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
pdfUri = FileProvider.getUriForFile(context, context.getPackageName() + ".provider", file);
} else {
pdfUri = Uri.fromFile(file);
}
intentShareFile.setType("application/pdf");
intentShareFile.putExtra(Intent.EXTRA_STREAM, pdfUri);
intentShareFile.putExtra(Intent.EXTRA_SUBJECT, "Sharing File...");
intentShareFile.putExtra(Intent.EXTRA_TEXT, "Sharing File...");
context.startActivity(Intent.createChooser(intentShareFile, "Share File"));
}
} else {
Toast.makeText(context, "PDF Generated successfully", Toast.LENGTH_LONG).show();
}
}
}
Now I have replaced recycler view with ExpandableListView and my print and share functionality is not working.
I want to create PDF with ExpandableListView content.
I have created the bitmap and have created the pdf file for the bitmap.
but I need to generate pdf for the whole listview which is scrollable.
Given below is is my code, please give me any suggestion, thanks in advance!!
I could not find the pdf creating application which could copy the entire UI or say in my case the entire listview into the pdf. If anybody could suggest what could be done in this case I would be grateful.
public class MainActivity extends AppCompatActivity {
private Button btn;
private LinearLayout llScroll;
private Bitmap bitmap;
private ListView listView;
ArrayList<String> myList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn = findViewById(R.id.btn);
llScroll = findViewById(R.id.llScroll);
listView = (ListView)findViewById(R.id.listView);
String[] names= new String[]{"One","Two","Three","Four","Five","Six","Seven","One","Two","Three","Four","Five","Six","Seven"};
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,android.R.id.text1,names);
listView.setAdapter(arrayAdapter);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d("size"," "+llScroll.getWidth() +" "+llScroll.getWidth());
bitmap = loadBitmapFromView(llScroll, llScroll.getWidth(), llScroll.getHeight());
createPdf();
}
});
}
public static Bitmap loadBitmapFromView(View v, int width, int height) {
Bitmap b = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
v.draw(c);
return b;
}
private void createPdf(){
DisplayMetrics displaymetrics = new DisplayMetrics();
this.getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
float hight = displaymetrics.heightPixels ;
float width = displaymetrics.widthPixels ;
int convertHighet = (int) hight, convertWidth = (int) width;
PdfDocument document = new PdfDocument();
PdfDocument.PageInfo pageInfo = new PdfDocument.PageInfo.Builder(convertWidth, convertHighet, 1).create();
PdfDocument.Page page = document.startPage(pageInfo);
Canvas canvas = page.getCanvas();
Paint paint = new Paint();
canvas.drawPaint(paint);
bitmap = Bitmap.createScaledBitmap(bitmap, convertWidth, convertHighet, true);
paint.setColor(Color.BLUE);
canvas.drawBitmap(bitmap, 0, 0 , null);
document.finishPage(page);
// write the document content
String targetPdf = "/sdcard/pdffromScroll.pdf";
File filePath;
filePath = new File(targetPdf);
try {
document.writeTo(new FileOutputStream(filePath));
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(this, "Something wrong: " + e.toString(), Toast.LENGTH_LONG).show();
}
// close the document
document.close();
Toast.makeText(this, "PDF of Scroll is created!!!", Toast.LENGTH_SHORT).show();
openGeneratedPDF();
}
private void openGeneratedPDF(){
File file = new File("/sdcard/pdffromScroll.pdf");
if (file.exists())
{
Intent intent=new Intent(Intent.ACTION_VIEW);
Uri uri = Uri.fromFile(file);
intent.setDataAndType(uri, "application/pdf");
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
try
{
startActivity(intent);
}
catch(ActivityNotFoundException e)
{
Toast.makeText(MainActivity.this, "No Application available to view pdf", Toast.LENGTH_LONG).show();
}
}
}}
Button for creating pdf file
//button listener for creating pdf file
convert2PDF.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//pdf document created
PdfDocument document = new PdfDocument();
//pageinfo created
PdfDocument.PageInfo pageInfo = new PdfDocument.PageInfo.Builder(800, 800, 1).create();
//page created based on pageinfo
PdfDocument.Page page = document.startPage(pageInfo);
//ImageView used to draw bitmap on page's canvas
ImageView imageView = new ImageView(context);
//setting imageView height weight equal to page height weight
imageView.setMaxHeight(800);
imageView.setMaxWidth(800);
//setting the imageView to bitmap selected from list
imageView.setImageBitmap(BitmapFactory.decodeFile(selectedFileList.get(0).getPath()));
//imageView drawn on canvas
imageView.draw(page.getCanvas());
//page finished
document.finishPage(page);
File result = null;
try {
result = File.createTempFile("afew", ".pdf",
context.getCacheDir());
//writing the pdf doc to temp file
document.writeTo(new BufferedOutputStream(new
FileOutputStream(result)));
} catch (FileNotFoundException e) {
Toast.makeText(getApplicationContext(), e.getMessage(),
Toast.LENGTH_SHORT).show();
} catch (IOException e) {
Toast.makeText(getApplicationContext(),
e.getMessage(),Toast.LENGTH_SHORT).show();
}
document.close();
//main file
File a = new File("/storage/sdcard/b.pdf");
//funct transfer used for transferring bytes from one file to another
transfer(result, a);
//set content of layout with imageView
context.setContentView(imageView);
}});
**I tried running above code but the file created at /storage/sdcard/b.pdf is empty always **
i searched through many answers here but none of them worked
is there anyway i can resolve this issue plz help
wow 3 days & found answer
protected File doInBackground(ArrayList<File>... params) {
File output = null;
PdfDocument doc = new PdfDocument();
ArrayList<Bitmap> images = new ArrayList<Bitmap>();
PdfDocument.Page page = null;
ArrayList<Bitmap> bitmaps = null;
Canvas canvas = null;
File outputDir = new File(getFilesDir()+"/Output/PDF");
if(!outputDir.exists()){
outputDir.mkdirs();
}
Random rand = new Random();
output = new File(getFilesDir()+"/Output/PDF/data-"+rand.nextInt()+".pdf");
for(File a: params[0]){
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(a.getPath(), options);
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;
String imageType = options.outMimeType;
Bitmap b = decodeSampledBitmapFromResource(a, imageWidth/2, imageHeight/2);
if(b!=null){
images.add(b);
}
}
int i = 0;
for(Bitmap a: images){
PdfDocument.PageInfo pageInfo = new PdfDocument.PageInfo.Builder(a.getWidth(), a.getHeight(), i++).create();
page = doc.startPage(pageInfo);
page.getCanvas().drawBitmap(a, 0, 0, new Paint(Paint.ANTI_ALIAS_FLAG));
doc.finishPage(page);
}
try{
FileOutputStream out = new FileOutputStream(output);
doc.writeTo(out);
out.flush();
out.close();
}catch(FileNotFoundException e){}
catch(IOException e){}
doc.close();
return output;
}
I want to make Video Collage in which 2 or more videos should be displayed in one frame and then they can be converted into one Video file.
I tried examples but they just add videos at the end of each video to make a long one combine video.
Any Help Please
String FILE_PATH = "/storage/sdcard0/testing.mp4";
String FILE_PATH2 = "/storage/sdcard0/testing1.mp4";
String FILE_PATH3 = "/storage/sdcard0/testing2.mp4";
File file1 = new File(FILE_PATH);
File file2 = new File(FILE_PATH2);
File file3 = new File(FILE_PATH3);
private ProgressDialog pDialog;
ImageView img,img2,img3;
MediaMetadataRetriever retriever2 = new MediaMetadataRetriever();
MediaMetadataRetriever retriever3 = new MediaMetadataRetriever();
ArrayList<Bitmap> bitmapArray1 = new ArrayList<Bitmap>();
ArrayList<Bitmap> bitmapArray2 = new ArrayList<Bitmap>();
ArrayList<Bitmap> bitmapArray3 = new ArrayList<Bitmap>();
File ScreenDIR = new File("/sdcard/Screens/");
// have the object build the directory structure, if needed.
double id1=0,id2=0,id3=0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ScreenDIR.mkdirs();
img = (ImageView)findViewById(R.id.imageView);
img2 = (ImageView)findViewById(R.id.imageView2);
img3 = (ImageView)findViewById(R.id.imageView3);
new LoadAllProducts().execute();
}
class LoadAllProducts extends AsyncTask<String, String, String> {
/**
* Before starting background thread Show Progress Dialog
* */
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(MainActivity.this);
pDialog.setMessage("Extracting Frames. Please wait...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
}
/**
* getting All products from url
* */
protected String doInBackground(String... args) {
if(file1.exists()){
for (long i = 0; i < 5000; i += 1000/14) { // lenms - video length in milliseconds
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
retriever.setDataSource(file1.toString());
// Bitmap bitmap = retriever.getFrameAtTime((i*1000/14), MediaMetadataRetriever.OPTION_CLOSEST_SYNC);
saveBitmapToCahche( getResizedBitmap((retriever.getFrameAtTime((i*1000/14), MediaMetadataRetriever.OPTION_CLOSEST_SYNC)), 500) ,String.valueOf(id1));
id1++;
//bitmapArray1.add(bitmap);
/* File file = new File(ScreenDIR, "sketchpad1" + id1 + ".png");
FileOutputStream fOut = null;
try {
fOut = new FileOutputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
//bitmap.compress(Bitmap.CompressFormat.PNG, 30, fOut);
try {
fOut.flush();
} catch (IOException e) {
e.printStackTrace();
}
try {
fOut.close();
} catch (IOException e) {
e.printStackTrace();
}*/
}
}
/* if(file2.exists()){
retriever2.setDataSource(file2.toString());
for (long i = 0; i < 3000; i += 1000/24) { // lenms - video length in milliseconds
bitmap2 = retriever2.getFrameAtTime(i*1000/29, MediaMetadataRetriever.OPTION_CLOSEST_SYNC);
//bitmapArray2.add(bitmap2);
File file = new File(ScreenDIR, "sketchpad2" + id2 + ".png");
FileOutputStream fOut = null;
try {
fOut = new FileOutputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
bitmap2.compress(Bitmap.CompressFormat.PNG, 85, fOut);
try {
fOut.flush();
} catch (IOException e) {
e.printStackTrace();
}
try {
fOut.close();
id2++;
} catch (IOException e) {
e.printStackTrace();
}
}
}
if(file3.exists()){
retriever3.setDataSource(file3.toString());
for (long i = 0; i < 3000; i += 1000/24) { // lenms - video length in milliseconds
bitmap3 = retriever3.getFrameAtTime(i*1000/29, MediaMetadataRetriever.OPTION_CLOSEST_SYNC);
// bitmapArray3.add(bitmap3);
File file = new File(ScreenDIR, "sketchpad3" + id3 + ".png");
FileOutputStream fOut = null;
try {
fOut = new FileOutputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
bitmap3.compress(Bitmap.CompressFormat.PNG, 85, fOut);
try {
fOut.flush();
} catch (IOException e) {
e.printStackTrace();
}
try {
fOut.close();
id3++;
} catch (IOException e) {
e.printStackTrace();
}
}
}*/
return null;
}
/**
* After completing background task Dismiss the progress dialog
* **/
protected void onPostExecute(String file_url) {
// dismiss the dialog after getting all products
pDialog.dismiss();
img.setImageBitmap(retrieveBitmapFromCache(String.valueOf(id2)));
id2 = 50;
img2.setImageBitmap(retrieveBitmapFromCache(String.valueOf(id2)));
id2 = 69;
img3.setImageBitmap(retrieveBitmapFromCache(String.valueOf(id2)));
// img2.setImageBitmap(bitmapArray2.get(0));
// img3.setImageBitmap(bitmapArray3.get(0));
}
}
public void saveBitmapToCahche(Bitmap bb,String ID ){
Cache.getInstance().getLru().put(ID, bb);
}
public Bitmap retrieveBitmapFromCache(String ID) {
Bitmap bitmap = (Bitmap) Cache.getInstance().getLru().get(ID);
return bitmap;
}
public Bitmap getResizedBitmap(Bitmap image, int maxSize) {
int width = image.getWidth();
int height = image.getHeight();
float bitmapRatio = (float)width / (float) height;
if (bitmapRatio > 0) {
width = maxSize;
height = (int) (width / bitmapRatio);
} else {
height = maxSize;
width = (int) (height * bitmapRatio);
}
return Bitmap.createScaledBitmap(image, width, height, true);
}
}
`
Creating a bitmap for each frame of video is terribly slow and not storage friendly at all. besides that MediaMetadataRetriever will give you lots of redundant frames. when you are done with creating bitmaps for both videos you will only have 4-5 different bitmaps from both videos.
To extract each and every frame from videos you will have to use MediaCodec with MediaExtractor.
Creating a collage is bit tricky. one thing is H264 coded only supports certain frame sizes. when you add two video side by side it wont necessarily fit into supported frame sizes.
That said, i thinks its possible with rendering frames side by side from both videos onto GLSurfaceView and sharing that surface to Mediacodec which will encode that frames to h264. i have not implemented this but i believe this is one way to do it without dealing with NDK.
FFMPEG also has in built functionality for this. if you are comfortable with NDK.
Split video into frames, e.g.
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
File file1 = new File(directory, "file.mp4");
retriever.setDataSource(file1.toString());
for (long i = 0; i < lenms; i += 1000/fps) { // lenms - video length in milliseconds
Bitmap bitmap = retriever.getFrameAtTime(i*1000/fps, MediaMetadataRetriever.OPTION_CLOSEST_SYNC);
}
and make a new frames from bitmap
I'm trying to parse images that comes in <img> tag using ImageGetter. I'm successfully able to parse and download the images. But,in worst cases, like no coonectivity, low network, if the image is not loaded, I want to reload the image. As per my understanding , I reload the image in onPostExecute() method of Asynctask when bitmap is null. But for this, Again I have to call the Asynctask method. Is there any other alternative to reload the image.
Below is my Imagegetter Code:
public class UrlImageParser implements Html.ImageGetter {
private static String TAG = "ImageParser";
private TextView mContainer;
private Context mContext;
Point outSize=new Point();
float destWidth=1;
float destHeight=1;
public UrlImageParser(TextView t, Context context) {
mContainer = t;
mContext = context;
}
#Override
public Drawable getDrawable(String source) {
LevelListDrawable d = new LevelListDrawable();
Drawable empty = mContext.getResources().getDrawable(R.drawable.story_img_placeholder);
d.addLevel(0, 0, empty);
d.setBounds(0, 0, empty.getIntrinsicWidth(), empty.getIntrinsicHeight());
new LoadImage().execute(source, d);
return d;
}
class LoadImage extends AsyncTask<Object, Void, Bitmap> {
private LevelListDrawable mDrawable;
#Override
protected Bitmap doInBackground(Object... params) {
String source = (String) params[0];
mDrawable = (LevelListDrawable) params[1];
Log.d(TAG, "doInBackground " + source);
try {
InputStream is = new URL(source).openStream();
return BitmapFactory.decodeStream(is);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Bitmap bitmap) {
Log.d(TAG, "onPostExecute drawable " + mDrawable);
Log.d(TAG, "onPostExecute bitmap " + bitmap);
if (bitmap != null) {
BitmapDrawable d = new BitmapDrawable(scaleBitmap(bitmap));
mDrawable.addLevel(1, 1, d);
/*int width = bitmap.getWidth();
int screenWidth = Utility.getScreenWidth(mContext);
int height = (int) (screenWidth * 0.62);*/
mDrawable.setBounds(0, 0, d.getBitmap().getWidth(), d.getBitmap().getHeight());
mDrawable.setLevel(1);
/*// redraw the image by invalidating the container
UrlImageParser.this.container.invalidate(); */
if (mContainer != null) {
mContainer.setText(mContainer.getText());
}
}else{
//Some error occured, send the request again
}
}
}
private Bitmap scaleBitmap(Bitmap mFile){
Display display = ((WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
if (android.os.Build.VERSION.SDK_INT >= 13){
display.getSize(outSize);
destWidth = outSize.x;
destHeight = outSize.y;
}else{
destWidth=display.getWidth();
destHeight=display.getHeight();
}
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
Bitmap orig = mFile;
float srcWidth = orig.getWidth();
float srcHeight = orig.getHeight();
Bitmap resized=Bitmap.createScaledBitmap(orig, (int)Math.round(destWidth), (int)Math.round(destWidth * srcHeight /srcWidth), true);
destWidth=1;
destHeight=1;
return resized;
}
}
The best way to do this is to never leave doInBackground() or to start the entire AsyncTask again. You could do something like this:
int failureCounter = 0;
#Override
protected Bitmap doInBackground(Object... params) {
try {
String source = (String) params[0];
mDrawable = (LevelListDrawable) params[1];
Log.d(TAG, "doInBackground " + source);
InputStream is = new URL(source).openStream();
return BitmapFactory.decodeStream(is);
} catch (Exception e) {
e.printStackTrace();
if(this.failureCounter++ >= 5) {
return null;
} else {
return this.doInBackground(params);
}
}
}
This code snippet will retry to load the image 5 times before it returns null. You should limit the number of tries to prevent a StackOverflowError and to limit the time your task is running as AsyncTasks are not ment to be a long-running background task.