1e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov/* 2e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov * Copyright (C) 2013 The Android Open Source Project 3e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov * 4e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov * Licensed under the Apache License, Version 2.0 (the "License"); 5e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov * you may not use this file except in compliance with the License. 6e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov * You may obtain a copy of the License at 7e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov * 8e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov * http://www.apache.org/licenses/LICENSE-2.0 9e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov * 10e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov * Unless required by applicable law or agreed to in writing, software 11e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov * distributed under the License is distributed on an "AS IS" BASIS, 12e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov * See the License for the specific language governing permissions and 14e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov * limitations under the License. 15e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov */ 16e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov 17826aa7f01d059b6764002fa0fba236d7aeafee39Svetoslavpackage foo.bar.permission2; 18e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov 19e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganovimport java.io.FileOutputStream; 20e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganovimport java.io.IOException; 21e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganovimport java.util.ArrayList; 22e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganovimport java.util.Arrays; 23e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganovimport java.util.List; 24e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov 25e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganovimport android.app.Activity; 26e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganovimport android.content.Context; 27e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganovimport android.graphics.Color; 28e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganovimport android.graphics.Paint; 29e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganovimport android.graphics.pdf.PdfDocument.Page; 30e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganovimport android.os.AsyncTask; 31e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganovimport android.os.Bundle; 32e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganovimport android.os.CancellationSignal; 33e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganovimport android.os.CancellationSignal.OnCancelListener; 34e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganovimport android.os.ParcelFileDescriptor; 35e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganovimport android.print.PageRange; 36e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganovimport android.print.PrintAttributes; 37e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganovimport android.print.PrintDocumentAdapter; 38e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganovimport android.print.PrintDocumentInfo; 39e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganovimport android.print.PrintManager; 40e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganovimport android.print.pdf.PrintedPdfDocument; 41e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganovimport android.util.Log; 42e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganovimport android.util.SparseIntArray; 43e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganovimport android.view.Menu; 44e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganovimport android.view.MenuItem; 45e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganovimport android.view.View; 46e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov 4722041d55a50e12bd1a95c4202bd4023b7c4b9d7fPhilip P. Moltmannimport foo.bar.print.R; 4822041d55a50e12bd1a95c4202bd4023b7c4b9d7fPhilip P. Moltmann 49e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov/** 50e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov * Simple sample of how to use the print APIs. 51e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov */ 52e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganovpublic class PrintActivity extends Activity { 53e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov 54e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov public static final String LOG_TAG = "PrintActivity"; 55e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov 56e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov private static final int PAGE_COUNT = 50; 57e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov 58e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov @Override 59e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov protected void onCreate(Bundle savedInstanceState) { 60e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov super.onCreate(savedInstanceState); 61e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov setContentView(R.layout.activity_main); 62e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov } 63e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov 64e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov @Override 65e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov public boolean onCreateOptionsMenu(Menu menu) { 66e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov super.onCreateOptionsMenu(menu); 67e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov getMenuInflater().inflate(R.menu.activity_main, menu); 68e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov return true; 69e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov } 70e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov 71e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov @Override 72e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov public boolean onOptionsItemSelected(MenuItem item) { 73e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov if (item.getItemId() == R.id.menu_print) { 74e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov printView(); 75e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov return true; 76e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov } 77e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov return super.onOptionsItemSelected(item); 78e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov } 79e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov 80e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov private void printView() { 81e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov PrintManager printManager = (PrintManager) getSystemService(Context.PRINT_SERVICE); 82e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov final View view = findViewById(R.id.content); 83e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov 84e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov printManager.print("Print_View", 85e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov new PrintDocumentAdapter() { 86e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov private static final int RESULT_LAYOUT_FAILED = 1; 87e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov private static final int RESULT_LAYOUT_FINISHED = 2; 88e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov 89e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov private PrintAttributes mPrintAttributes; 90e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov 91e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov @Override 92e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov public void onStart() { 93e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov Log.i(LOG_TAG, "onStart"); 94e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov } 95e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov 96e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov @Override 97e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov public void onFinish() { 98e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov Log.i(LOG_TAG, "onFinish"); 99e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov } 100e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov 101e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov @Override 102e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov public void onLayout(final PrintAttributes oldAttributes, 103e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov final PrintAttributes newAttributes, 104e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov final CancellationSignal cancellationSignal, 105e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov final LayoutResultCallback callback, 106e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov final Bundle metadata) { 107e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov 108e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov Log.i(LOG_TAG, "onLayout() oldAttrs:" + oldAttributes + "\n" 109e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov + "newAttrs:" + newAttributes + "\n" 110e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov + "preview:" + metadata.getBoolean( 111e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov PrintDocumentAdapter.EXTRA_PRINT_PREVIEW) ); 112e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov 113e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov new AsyncTask<Void, Void, Integer>() { 114e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov @Override 115e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov protected void onPreExecute() { 116e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov // First register for cancellation requests. 117e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov cancellationSignal.setOnCancelListener(new OnCancelListener() { 118e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov @Override 119e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov public void onCancel() { 120e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov cancel(true); 121e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov } 122e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov }); 123e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov mPrintAttributes = newAttributes; 124e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov } 125e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov 126e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov @Override 127e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov protected Integer doInBackground(Void... params) { 128e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov try { 129e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov // Pretend we do some layout work. 130e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov for (int i = 0; i < PAGE_COUNT; i++) { 131e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov // Be nice and respond to cancellation. 132e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov if (isCancelled()) { 133e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov return null; 134e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov } 135e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov pretendDoingLayoutWork(); 136e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov } 137e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov return RESULT_LAYOUT_FINISHED; 138e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov } catch (Exception e) { 139e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov return RESULT_LAYOUT_FAILED; 140e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov } 141e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov } 142e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov 143e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov @Override 144e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov protected void onPostExecute(Integer result) { 145e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov // The task was not cancelled, so handle the layout result. 146e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov switch (result) { 147e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov case RESULT_LAYOUT_FINISHED: { 148e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov PrintDocumentInfo info = new PrintDocumentInfo 149e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov .Builder("print_view.pdf") 150e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov .setContentType(PrintDocumentInfo 151e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov .CONTENT_TYPE_DOCUMENT) 152e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov .setPageCount(PAGE_COUNT) 153e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov .build(); 154e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov callback.onLayoutFinished(info, false); 155e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov } break; 156e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov 157e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov case RESULT_LAYOUT_FAILED: { 158e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov callback.onLayoutFailed(null); 159e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov } break; 160e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov } 161e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov } 162e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov 163e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov @Override 164e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov protected void onCancelled(Integer result) { 165e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov // Task was cancelled, report that. 166e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov callback.onLayoutCancelled(); 167e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov } 168e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov 169e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov private void pretendDoingLayoutWork() throws Exception { 170e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov 171e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov } 172e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[]) null); 173e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov } 174e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov 175e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov @Override 176e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov public void onWrite(final PageRange[] pages, 177e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov final ParcelFileDescriptor destination, 178e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov final CancellationSignal cancellationSignal, 179e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov final WriteResultCallback callback) { 180e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov 181e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov Log.i(LOG_TAG, "onWrite() pages:" + Arrays.toString(pages)); 182e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov 183e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov new AsyncTask<Void, Void, Integer>() { 184e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov private static final int RESULT_WRITE_FAILED = 1; 185e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov private static final int RESULT_WRITE_FINISHED = 2; 186e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov 187e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov private final SparseIntArray mWrittenPages = new SparseIntArray(); 188e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov private final PrintedPdfDocument mPdfDocument = new PrintedPdfDocument( 189e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov PrintActivity.this, mPrintAttributes); 190e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov 191e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov @Override 192e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov protected void onPreExecute() { 193e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov // First register for cancellation requests. 194e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov cancellationSignal.setOnCancelListener(new OnCancelListener() { 195e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov @Override 196e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov public void onCancel() { 197e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov cancel(true); 198e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov } 199e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov }); 200e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov 201e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov for (int i = 0; i < PAGE_COUNT; i++) { 202e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov // Be nice and respond to cancellation. 203e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov if (isCancelled()) { 204e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov return; 205e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov } 206e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov 207e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov // Write the page only if it was requested. 208e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov if (containsPage(pages, i)) { 209e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov mWrittenPages.append(mWrittenPages.size(), i); 210e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov Page page = mPdfDocument.startPage(i); 211e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov // The page of the PDF backed canvas size is in pixels (1/72") and 212e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov // smaller that the view. We scale down the drawn content and to 213e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov // fit. This does not lead to losing data as PDF is a vector format. 214e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov final float scale = (float) Math.min(mPdfDocument.getPageWidth(), 215e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov mPdfDocument.getPageHeight()) / Math.max(view.getWidth(), view.getHeight()); 216e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov page.getCanvas().scale(scale, scale); 217e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov view.draw(page.getCanvas()); 218e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov 219e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov 220e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov Paint paint = new Paint(); 221e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov paint.setTextSize(100); 222e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov paint.setColor(Color.RED); 223e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov final int x = page.getCanvas().getWidth() / 2; 224e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov final int y = page.getCanvas().getHeight() / 2; 225e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov page.getCanvas().drawText(String.valueOf(i), x, y, paint); 226e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov 227e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov mPdfDocument.finishPage(page); 228e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov } 229e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov } 230e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov } 231e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov 232e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov @Override 233e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov protected Integer doInBackground(Void... params) { 234e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov // Write the data and return success or failure. 235e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov try { 236e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov mPdfDocument.writeTo(new FileOutputStream( 237e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov destination.getFileDescriptor())); 238e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov return RESULT_WRITE_FINISHED; 239e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov } catch (IOException ioe) { 240e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov return RESULT_WRITE_FAILED; 241e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov } 242e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov } 243e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov 244e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov @Override 245e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov protected void onPostExecute(Integer result) { 246e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov // The task was not cancelled, so handle the write result. 247e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov switch (result) { 248e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov case RESULT_WRITE_FINISHED: { 249e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov PageRange[] pageRanges = computePageRanges(mWrittenPages); 250e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov callback.onWriteFinished(pageRanges); 251e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov } break; 252e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov 253e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov case RESULT_WRITE_FAILED: { 254e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov callback.onWriteFailed(null); 255e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov } break; 256e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov } 257e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov 258e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov mPdfDocument.close(); 259e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov } 260e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov 261e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov @Override 262e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov protected void onCancelled(Integer result) { 263e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov // Task was cancelled, report that. 264e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov callback.onWriteCancelled(); 265e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov mPdfDocument.close(); 266e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov } 267e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[]) null); 268e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov } 269e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov 270e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov private PageRange[] computePageRanges(SparseIntArray writtenPages) { 271e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov List<PageRange> pageRanges = new ArrayList<PageRange>(); 272e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov 273e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov int start = -1; 274e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov int end = -1; 275e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov final int writtenPageCount = writtenPages.size(); 276e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov for (int i = 0; i < writtenPageCount; i++) { 277e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov if (start < 0) { 278e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov start = writtenPages.valueAt(i); 279e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov } 280e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov int oldEnd = end = start; 281e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov while (i < writtenPageCount && (end - oldEnd) <= 1) { 282e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov oldEnd = end; 283e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov end = writtenPages.valueAt(i); 284e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov i++; 285e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov } 286e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov PageRange pageRange = new PageRange(start, end); 287e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov pageRanges.add(pageRange); 288e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov start = end = -1; 289e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov } 290e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov 291e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov PageRange[] pageRangesArray = new PageRange[pageRanges.size()]; 292e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov pageRanges.toArray(pageRangesArray); 293e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov return pageRangesArray; 294e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov } 295e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov 296e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov private boolean containsPage(PageRange[] pageRanges, int page) { 297e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov final int pageRangeCount = pageRanges.length; 298e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov for (int i = 0; i < pageRangeCount; i++) { 299e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov if (pageRanges[i].getStart() <= page 300e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov && pageRanges[i].getEnd() >= page) { 301e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov return true; 302e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov } 303e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov } 304e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov return false; 305e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov } 306e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov }, null); 307e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov } 308e4a7362e628701bc71289888f6241cc94c9a4fbcSvet Ganov} 309