title: Changing page count with PrintDocumentAdapter and PrintManager
body: <p>I'm extending PrintDocumentAdapter to send roster information to a printer via Cloud Print. Everything is working well, until the settings are changed so that the number of pages in the document is decreased.</p>
  
  <p>For example, a table will fit on two A4 pages, but will require three A5 pages. Cloud Print starts with A4 selected by default and a preview is generated. If the page size is changed to A5, a new preview is generated with three pages as expected. If the page size is then changed back to A4, Cloud Print gives the message "Sorry, that didn't work. Try again." and must be exited.</p>
  
  <p>This is what seems to be happening:</p>
  
  <ul>
  <li>onLayout() is called with A4 document attributes. LayoutResultCallback.onLayoutFinished() is passed a PrintDocumentInfo pageCount set to 2.</li>
  <li>onWrite() is called with a single PageRange of 0-1, as expected.</li>
  <li>I change the paper size to A5.</li>
  <li>onLayout() is called with A5 document attributes. LayoutResultCallback.onLayoutFinished() is passed a PrintDocumentInfo pageCount set to 3.</li>
  <li>onWrite() is called with a single PageRange of 0-1, <strong>which is the old range</strong></li>
  <li>onWrite() is called a second time with the correct PageRange of 0-2.</li>
  </ul>
  
  <p>This only causes an error when the old PageRange is greater than the number of pages returned, but why would onWrite() get called with an invalid PageRange?</p>
  
  <p>I've noticed many apps on my device simply scale the output so that the page count doesn't change between different settings. Are they doing this due to this problem?</p>
  
  <pre><code>public class PrintAdapter extends PrintDocumentAdapter {
  
      private static final String TAG = "PrintAdapter";
  
      private PrintedPdfBuilder mPrintedPdfBuilder;
      private int mPages;
  
      public PrintAdapter(PrintedPdfBuilder printedPdfBuilder) {
          mPrintedPdfBuilder = printedPdfBuilder;
      }
  
      @Override
      public void onLayout(PrintAttributes oldAttributes, PrintAttributes newAttributes,
                           CancellationSignal cancellationSignal, LayoutResultCallback callback,
                           Bundle extras) {
  
          Log.v(TAG, "onLayout");
          // Respond to cancellation request
          if (cancellationSignal.isCanceled()) {
              callback.onLayoutCancelled();
              return;
          }
  
          int pages = mPrintedPdfBuilder.getPageCount(newAttributes);
          Log.v(TAG, "page count = " + pages);
          if (pages &gt; 0) {
              // Return print information to print framework
              PrintDocumentInfo info = new PrintDocumentInfo
                      .Builder("print_output.pdf")
                      .setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT)
                      .setPageCount(pages)
                      .build();
              // Content layout reflow is complete
              callback.onLayoutFinished(info, mPages != pages);
              mPages = pages;
          } else {
              // Otherwise report an error to the print framework
              callback.onLayoutFailed("Page count calculation failed.");
          }
      }
  
      @Override
      public void onWrite(PageRange[] ranges, ParcelFileDescriptor destination,
                          CancellationSignal cancellationSignal, WriteResultCallback callback) {
  
          Log.v(TAG, "onWrite() ranges: " + Arrays.toString(ranges));
          // Write PDF document to file
          try {
              PrintedPdfDocument pdf = mPrintedPdfBuilder.generateDocument(ranges);
  
              // check for cancellation
              if (cancellationSignal.isCanceled()) {
                  callback.onWriteCancelled();
                  mPrintedPdfBuilder.close();
                  return;
              }
              pdf.writeTo(new FileOutputStream(destination.getFileDescriptor()));
          } catch (IOException e) {
              callback.onWriteFailed(e.toString());
              return;
          } finally {
              mPrintedPdfBuilder.close();
          }
  
          PageRange[] writtenPages = mPrintedPdfBuilder.getWrittenPages();
          Log.v(TAG, "writtenPages: " + Arrays.toString(writtenPages));
          // Signal the print framework the document is complete
          callback.onWriteFinished(writtenPages);
      }
  }
  </code></pre>
  
  <p>Logcat:</p>
  
  <pre><code>08-28 11:46:44.187 9714-9714/com.meremammal.www.staffrosterwizard V/PrintAdapter: onLayout
  08-28 11:46:44.276 9714-9714/com.meremammal.www.staffrosterwizard V/PrintAdapter: page count = 2
  08-28 11:46:44.298 9714-9714/com.meremammal.www.staffrosterwizard V/PrintAdapter: onWrite() ranges: [PageRange[0 - 1]]
  08-28 11:46:44.512 9714-9714/com.meremammal.www.staffrosterwizard V/PrintAdapter: writtenPages: [PageRange[0 - 1]]
  08-28 11:46:50.418 9714-9714/com.meremammal.www.staffrosterwizard V/PrintAdapter: onLayout
  08-28 11:46:50.499 9714-9714/com.meremammal.www.staffrosterwizard V/PrintAdapter: page count = 3
  08-28 11:46:50.509 9714-9714/com.meremammal.www.staffrosterwizard V/PrintAdapter: onWrite() ranges: [PageRange[0 - 1]]
  08-28 11:46:50.678 9714-9714/com.meremammal.www.staffrosterwizard V/PrintAdapter: writtenPages: [PageRange[0 - 1]]
  08-28 11:46:50.918 9714-9714/com.meremammal.www.staffrosterwizard V/PrintAdapter: onWrite() ranges: [PageRange[0 - 2]]
  08-28 11:46:51.160 9714-9714/com.meremammal.www.staffrosterwizard V/PrintAdapter: writtenPages: [PageRange[0 - 2]]
  08-28 11:47:34.983 9714-9714/com.meremammal.www.staffrosterwizard V/PrintAdapter: onLayout
  08-28 11:47:35.049 9714-9714/com.meremammal.www.staffrosterwizard V/PrintAdapter: page count = 2
  08-28 11:47:35.056 9714-9714/com.meremammal.www.staffrosterwizard V/PrintAdapter: onWrite() ranges: [PageRange[0 - 2]]
  08-28 11:47:35.248 9714-9714/com.meremammal.www.staffrosterwizard V/PrintAdapter: writtenPages: [PageRange[0 - 1]]
  </code></pre>
  
  <p>onLayout is called each time the settings change, but for some reason onWrite is then called with the previous PageRange[]</p>