Learn, Share, Build

207
September 23, 2017, at 03:15 AM

I've to generate some charts from DB data and then print them to PDF. Currently, I've made this AsyncTask:

public class PDFGeneration extends AsyncTask<GeneratePDFParams, Void, Void>
{
    LineChart pdfChartView;
    View pdfView;
    ImageView pdfChartImage;
    ImageView pdfChartBg;
    Exam currentExam;
    public static int mPdfChartWidthInPx;
    public static int mPdfChartHeightInPx;
    public final static int mChartWidth = 842;
    public final static int mChartHeight = 595;
    public final static int mA4WidthInPx = 842;
    public final static int mA4HeightInPx = 595;
    public final static int mA4HeightInCm = 21;
    public final static double numberOfVerticalSquareDesired = 36.0; // 4 quadrati a GFX
    public final static double yMod  = numberOfVerticalSquareDesired * 0.5;
    public final static double verticalSquare = yMod / numberOfVerticalSquareDesired;
    private LineData chartLineData;
    private LineDataSet D1DataPoint;
    private LineDataSet D2DataPoint;
    private LineDataSet D3DataPoint;
    private LineDataSet aVRDataPoint;
    private LineDataSet aVFDataPoint;
    private LineDataSet aVLDataPoint;
    private LineDataSet V2DataPoint;
    private LineDataSet V5DataPoint;
    private TextView firstLabel;
    private TextView secondLabel;
    private String firstLabelString, secondLabelString, examUUID, fullName, deviceID;
    private PDFTaskDelegate delegate;
    public PDFGeneration(PDFTaskDelegate delegate) {
        this.delegate = delegate;
    }
    protected void onPreExecute (){
        super.onPreExecute();
        pdfChartView = new LineChart(DApplication.getDContext());
        mPdfChartHeightInPx = (int) (mA4HeightInPx * (numberOfVerticalSquareDesired / 2)) / mA4HeightInCm;
        mPdfChartWidthInPx = 774;
        pdfChartView.measure(mPdfChartWidthInPx * 4, mPdfChartHeightInPx * 4);
        pdfChartView.layout(0, 0, mPdfChartWidthInPx * 4, mPdfChartHeightInPx * 4);
        LayoutInflater inflater = (LayoutInflater)DApplication.getDContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        pdfView = inflater.inflate(R.layout.pdf_sample, null);
        pdfChartImage = (ImageView) pdfView.findViewById(R.id.pdf_chart_bitmap);
        firstLabel = (TextView) pdfView.findViewById(R.id.pdf_line_one_data_label);
        secondLabel = (TextView) pdfView.findViewById(R.id.pdf_line_two_data_label);
        pdfView.measure(mA4WidthInPx, mA4HeightInPx);
        pdfView.layout(0, 0, mA4WidthInPx, mA4HeightInPx);
    }
    protected Void doInBackground(GeneratePDFParams... params) {
        examUUID = params[0].examUUID;
        deviceID = params[0].deviceID;
        currentExam = RealmManager.getExamWithUUID(examUUID);
        if(currentExam == null) {
            delegate.PDFGenerationTaskCompleted(false, examUUID);
            cancel(true);
        }
        firstLabelString = String.format("%s - %s", currentExam.getPatient().fullnameWithMe(false), currentExam.getFormattedDateForPDF());
        secondLabelString = String.format("%s %s", " n.", deviceID);
        fullName = currentExam.getPatient().fullnameWithMe(false);
        setupGraph(pdfChartView, true);
        setupDataOnGraph(pdfChartView, verticalSquare, currentExam.getECGDatas());
        return null;
    }
    protected void onPostExecute(Void result) {
        super.onPostExecute(null);
        firstLabel.setText(firstLabelString);
        secondLabel.setText(secondLabelString);
        RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) pdfChartImage.getLayoutParams();
        params.height = mPdfChartHeightInPx;
        params.width = mPdfChartWidthInPx;

        pdfChartImage.setLayoutParams(params);
        pdfChartImage.requestLayout();
        Bitmap ecgResultImage = createSingleImageFromMultipleImages(pdfChartView);
        pdfChartImage.setImageBitmap(ecgResultImage);
        Log.w("TEST TAG", "TEST PASSO 2");
        final PdfDocument document = new PdfDocument();
        PdfDocument.PageInfo pageInfo = new PdfDocument.PageInfo.Builder(mA4WidthInPx, mA4HeightInPx, 1).create();
        final PdfDocument.Page page = document.startPage(pageInfo);
        pdfView.draw(page.getCanvas());
        document.finishPage(page);
        GeneratePDFParams returnParams = new GeneratePDFParams(document, examUUID, fullName, deviceID);
        pdfView = null;
        new PDFSaveToFile(delegate).execute(returnParams);
    }

    public void setupGraph(LineChart chart, boolean forPDF)
    {
        double xMod, horizontalSquare;
        double horizontalSquareNumber;
        if(!forPDF)
            horizontalSquareNumber = mChartWidth / (mChartHeight/numberOfVerticalSquareDesired);
        else
            horizontalSquareNumber = mPdfChartWidthInPx / (mPdfChartHeightInPx /numberOfVerticalSquareDesired);
        xMod = SAMPLE_PER_SQUARE * horizontalSquareNumber;
        horizontalSquare = xMod / horizontalSquareNumber;
        chart.setDrawGridBackground(!forPDF);
        chart.setDescription(null);
        chart.getLegend().setEnabled(false);
        // set an alternative background color
        chart.setViewPortOffsets(0f, 0f, 0f, 0f);
        D1DataPoint = createSet(forPDF);
        D2DataPoint = createSet(forPDF);
        D3DataPoint = createSet(forPDF);
        aVRDataPoint = createSet(forPDF);
        aVFDataPoint = createSet(forPDF);
        aVLDataPoint = createSet(forPDF);
        V2DataPoint = createSet(forPDF);
        V5DataPoint = createSet(forPDF);
        // add empty data
        chartLineData = new LineData();
        chart.setData(chartLineData);
        chart.setScaleEnabled(false);
        chart.setPinchZoom(false);
        chart.setDragEnabled(false);
        if(!forPDF) {
            chart.setBackgroundColor(Color.rgb(255, 255, 255));
            chart.setGridBackgroundColor(Color.rgb(255, 255, 255));
        } else {
            chart.setBackgroundColor(Color.TRANSPARENT);
        }
        chart.setHardwareAccelerationEnabled(true);
        XAxis xl = chart.getXAxis();
        xl.setEnabled(!forPDF);
        xl.setAxisMaximum((float)xMod);
        if(!forPDF){
            xl.setDrawLabels(true);
            xl.setDrawGridLines(true);
            int labelCount = (int)(xMod / horizontalSquare) + 1;
            xl.setLabelCount(labelCount, true);
            xl.setGridColor(Color.rgb(239,165,191));
        }
        YAxis leftAxis = chart.getAxisLeft();
        leftAxis.setDrawLabels(false);
        leftAxis.setAxisMaximum((float)yMod);
        leftAxis.setAxisMinimum(0f);
        leftAxis.setAxisMaximum(18.0f);
        leftAxis.setEnabled(!forPDF);
        if(!forPDF){
            leftAxis.setLabelCount((int) numberOfVerticalSquareDesired + 1, true);
            leftAxis.setDrawGridLines(true);
            leftAxis.setGridColor(Color.rgb(239,165,191));
        }
        YAxis rightAxis = chart.getAxisRight();
        rightAxis.setEnabled(!forPDF);
    }
    private LineDataSet createSet(boolean forPDF) {
        LineDataSet set = new LineDataSet(null, null);
        set.setAxisDependency(YAxis.AxisDependency.LEFT);
        if(forPDF)
            set.setLineWidth(0.6f);
        else
            set.setLineWidth(1f);
        set.setFillAlpha(65);
        set.setFillColor(R.color.black);
        set.setColor(R.color.black);
        set.setDrawValues(false);
        set.setDrawCircles(false);
        set.setDrawCircleHole(false);
        set.setDrawFilled(false);
        set.setDrawHighlightIndicators(false);
        return set;
    }
    private void setupDataOnGraph(LineChart chart, double verticalSquare, RealmList<SingleECGData> examData) {
        LineData data = chart.getData();
        if (data != null) {
            ILineDataSet set = data.getDataSetByIndex(0);
            if (set == null) {
                data.addDataSet(D1DataPoint);
                data.addDataSet(D2DataPoint);
                data.addDataSet(D3DataPoint);
                data.addDataSet(aVRDataPoint);
                data.addDataSet(aVFDataPoint);
                data.addDataSet(aVLDataPoint);
                data.addDataSet(V2DataPoint);
                data.addDataSet(V5DataPoint);
            }
            for (int i = 0; i < examData.size(); i++) {
                if (i > SAMPLE_PER_SQUARE * (27 * 2))
                    break;
                SingleECGData single = examData.get(i);
                float xD1 = i;
                double yD1 = single.getDataD1() + ((verticalSquare * 4) * 8);
                D1DataPoint.addEntry(new Entry(xD1, (float) yD1));
                double yD2 = single.getDataD2() + ((verticalSquare * 4) * 7);
                D2DataPoint.addEntry(new Entry(xD1, (float) yD2));
                double yD3 = single.getDataD3() + ((verticalSquare * 4) * 6);
                D3DataPoint.addEntry(new Entry(xD1, (float) yD3));
                double yaVR = single.getDataAVR() + ((verticalSquare * 4) * 5);
                aVRDataPoint.addEntry(new Entry(xD1, (float) yaVR));
                double yaVL = single.getDataAVL() + ((verticalSquare * 4) * 4);
                aVLDataPoint.addEntry(new Entry(xD1, (float) yaVL));
                double yaVF = single.getDataAVF() + ((verticalSquare * 4) * 3);
                aVFDataPoint.addEntry(new Entry(xD1, (float) yaVF));
                double yV2 = single.getDataV2() + ((verticalSquare * 4) * 2);
                V2DataPoint.addEntry(new Entry(xD1, (float) yV2));
                double yV5 = single.getDataV5() + ((verticalSquare * 4) * 1);
                V5DataPoint.addEntry(new Entry(xD1, (float) yV5));
            }
            data.notifyDataChanged();
            // let the chart know it's data has changed
            chart.notifyDataSetChanged();
        }
    }
    private Bitmap createSingleImageFromMultipleImages(LineChart ecgChart){
        Bitmap bgImage = BitmapFactory.decodeResource(DApplication.getDContext().getResources(), R.drawable.carta_mm_bg);
        Bitmap tempBitmap = Bitmap.createBitmap(bgImage.getWidth(), bgImage.getHeight(), bgImage.getConfig());
        Canvas canvas = new Canvas(tempBitmap);
        canvas.drawBitmap(bgImage, 0f, 0f, null);
        Bitmap ecgDataBitmap = ecgChart.getChartBitmapJPG();
        canvas.drawBitmap(Bitmap.createScaledBitmap(ecgDataBitmap, bgImage.getWidth(), bgImage.getHeight(), false), 0f, 0f, null);
        bgImage.recycle();
        ecgDataBitmap.recycle();
        return tempBitmap;
    }
}

But there are so many problems:

  1. this block my UI
  2. Use HUGE quantitative of RAM, and only partially will be free at the end.

Approximately, If I request the generation of 10 PDF My app uses approx 500MB of RAM, then crash. If I create a progress HUD, It can't be updated with progress because the Asynctask requests UI thread.

Is there something to create background PDF with NO-UI block and no HUGE ram usage? I'm going crazy with this.

READ ALSO
Learn, Share, Build

Learn, Share, Build

I am looking for a kind of library or framework that takes a picture crop it according to text written in picture and then highlight the text for Android platform

172
Learn, Share, Build

Learn, Share, Build

Im using unity 20171

280
Learn, Share, Build

Learn, Share, Build

I am working on a custom ListView Element that is stored in a SQL DatabaseI tried to convert the bitmap into a byteArray and then save it in the Database but when i leave the activity and come back its not there anymore

166
Learn, Share, Build

Learn, Share, Build

I have these varibles:

230