3

레이아웃 스크린 샷을 PDF로 저장 한 다음 Google 클라우드 프린트를 통해 인쇄하도록 전송하는 앱을 개발 중입니다. 모든 것이 잘 작동하지만 스크린 샷의 방향과 관련하여 문제가 있습니다.방향 변경 후 스크린 샷 프로그래밍

호스트 단편에 대해 가로 및 세로 레이아웃을 모두 만들었습니다. 스크린 샷은 항상 세로 방향이어야하므로 프로그래밍 방식으로 화면을 세로 방향으로 회전하고 스크린 샷을 찍은 다음 화면 방향을 다시 센서로 설정하십시오. 나는이 방법으로 구성을 변경 :

public void lockScreenOrientation(String orientation) {  
    if (orientation.contains("portrait")) { 
     mActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);    
    } else if (orientation.contains("auto")) { 
     mActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR); 
    } 
} 

호스트 조각

if (print) {    
     new AsyncPDF(mActivity).execute(field_client_name_txt, "birthday"); 
     prefs.edit().putBoolean("Print", false).commit(); 
} 

방향이 세로에에 확인 대화 상자에 의해 트리거되는 AsyncTask를의 스크린 샷 및 PDF 생성 발생하는 모든 위대한 작품! 이 문제는 스크린 샷과 인쇄 작업을 위해 오리엔테이션을 세로 방향으로 회전해야 할 때 발생합니다. 스크린 샷은 인물 대신 가로 레이아웃 이미지를 캡처하고 최종 PDF는 지저분하고 잘립니다!

public class AsyncPDF extends AsyncTask<String, Void, Void> { 

Activity mActivity; 
Context mContext; 

private static final int REQUEST_CODE = 4; 

private static String SDCARD = Environment.getExternalStorageDirectory().getPath(); 
private static String DIRECTORY = SDCARD + "/Amorino"; 
private static String DIR_CACHE = DIRECTORY + "/Cache/"; 
private static String DIR_BIRTHDAY_ORDERS = DIRECTORY + "/Orders/Birthday/"; 
private static String DIR_WEDDING_ORDERS = DIRECTORY + "/Orders/Wedding/"; 
private static String DIR_OTHER_ORDERS = DIRECTORY + "/Orders/Other/"; 
private static String DIR_PRODUCTION = DIRECTORY + "/Production/"; 

String pdfName, pdfType = ""; 
Utils mUtility; 

public AsyncPDF(Activity activity) { 
    this.mActivity = activity; 
    this.mContext = activity; 
} 

@Override 
protected void onPreExecute() { 
    mUtility = new Utils(mContext); 
    Toast.makeText(mActivity, "Αποθήκευση αρχείου...", Toast.LENGTH_SHORT) 
      .show(); 
     screenCapture(); 
}; 

@Override 
protected Void doInBackground(String... params) { 

    pdfName = params[0]; 
    pdfType = params[1]; 

    createPdf(); 

    return null; 
} 

@Override 
protected void onProgressUpdate(Void... values) { 
    super.onProgressUpdate(values); 

} 

@Override 
protected void onPostExecute(Void result) { 
    super.onPostExecute(result); 
    clearCacheFolder(); 
    Toast.makeText(mActivity, "Το αρχείο αποθηκέυτηκε επιτυχώς!", 
      Toast.LENGTH_SHORT).show(); 

} 

private void screenCapture() { 

    try { 

     ScrollView mLayoutRoot = (ScrollView) mActivity 
       .findViewById(R.id.print_screen_layout); 

     mLayoutRoot.setDrawingCacheEnabled(true); 
     mLayoutRoot.buildDrawingCache(); 

     Bitmap mBitmap = mLayoutRoot.getDrawingCache(); 
     File file, f = null; 
     if (android.os.Environment.getExternalStorageState().equals(
       android.os.Environment.MEDIA_MOUNTED)) { 
      file = new File(DIR_CACHE); 
      if (!file.exists()) { 
       file.mkdirs(); 
      } 

      f = new File(file.getAbsolutePath() + File.separator 
        + "temp_layout" + ".png"); 
     } 
     FileOutputStream ostream = new FileOutputStream(f); 
     mBitmap.compress(CompressFormat.PNG, 10, ostream); 
     ostream.close(); 

    } catch (Exception e) { 
     e.printStackTrace(); 
    } 

} 

private void createPdf() { 

    Document document = new Document(); 
    Image header_img, main_img; 
    InputStream inputStream_header = null; 
    String current_directory = ""; 

    try { 

     AssetManager mngr = mContext.getAssets(); 

     if (pdfType.contains("birthday")) { 
      inputStream_header = mngr.open("header_birthday.png"); 
      current_directory = DIR_BIRTHDAY_ORDERS; 
     } else if (pdfType.contains("wedding")) { 
      inputStream_header = mngr.open("header_wedding.png"); 
      current_directory = DIR_WEDDING_ORDERS; 
     } else if (pdfType.contains("other")) { 
      inputStream_header = mngr.open("header_order.png"); 
      current_directory = DIR_OTHER_ORDERS; 
     } else if (pdfType.contains("production")) { 
      inputStream_header = mngr.open("header_order.png"); 
      current_directory = DIR_PRODUCTION; 
     } 

     File file = new File(current_directory); 
     if (!file.exists()) { 
      file.mkdirs(); 
     } 

     PdfWriter.getInstance(document, new FileOutputStream(
       current_directory + "/" + pdfName + ".pdf")); 
     document.open(); 

     Bitmap bmp = BitmapFactory.decodeStream(inputStream_header); 
     ByteArrayOutputStream stream_header = new ByteArrayOutputStream(); 
     bmp.compress(Bitmap.CompressFormat.PNG, 100, stream_header); 
     header_img = Image.getInstance(stream_header.toByteArray()); 
     header_img.scalePercent(24f); 
     header_img.setAbsolutePosition(-1f, 750f); 
     document.add(header_img); 

     Paragraph paragraph = new Paragraph(
       header_img.getScaledHeight() + 50f); 
     document.add(paragraph); 

     main_img = Image.getInstance(DIR_CACHE 
       + "/temp_layout.png"); 

     main_img.scaleToFit(520f, 2000f); 
     main_img.setAlignment(Image.ALIGN_CENTER); 

     Log.d("Original Width: ", String.valueOf(main_img.getWidth())); 
     Log.d("Original Height ", String.valueOf(main_img.getHeight())); 
     Log.d("Scaled Width: ", String.valueOf(main_img.getScaledWidth())); 
     Log.d("Scaled Height ", String.valueOf(main_img.getScaledHeight())); 

     document.add(main_img); 

     document.close(); 
     File f = new File(current_directory + "/" + pdfName + ".pdf"); 
     printPdf(f, pdfName); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 

} 

private void printPdf(File f, String name) { 
    Uri docUri = Uri.fromFile(f); 
    Intent printIntent = new Intent(mContext, PrintDialogActivity.class); 
    printIntent.setDataAndType(docUri, "application/pdf"); 
    printIntent.putExtra("title", name + ".pdf"); 
    mActivity.startActivityForResult(printIntent, REQUEST_CODE); 
} 

private void clearCacheFolder() { 
    File dir = new File(DIR_CACHE); 
    if (dir.isDirectory()) { 
     String[] children = dir.list(); 
     for (int i = 0; i < children.length; i++) { 
      new File(dir, children[i]).delete(); 
     } 
    } 
} 

}

내가 결함이 mActivity 매개 변수에서 발생 믿습니다 : 여기에 참고로

내 AsyncTask를합니다. 제 생각에 그것은 초상화 하나가 아닌 원래의 풍경 레이아웃으로 조각을 전달합니다. SharedPreference에 저장된 "인쇄"플래그를 사용하고 행운을 지어 onResume 메서드에서 AsyncTask를 실행하려고했습니다. 화면 캡처는 여전히 가로 레이아웃을 잡습니다. 어떤 아이디어?

그런 다음 적절한 (세로) 레이아웃을 얻기 위해 프래그먼트 수명주기의 어느 시점에서 AsyncTask를 실행해야합니까?

P. 첫 번째 질문에 물었다 !!

답변

0

나는 일주일 전에 그것을 마침내 알아 냈습니다. 그리고 여기 해결책이 있습니다!

문제는 this answer의 힌트로 해결되었습니다. 새로운 레이아웃이 결정된 후에 AsyncPDF 클래스를 초기화하기 위해 GlobalLayoutListener를 추가하고 문제가 거의 해결되었습니다. 나중에 나는 새로운 문제를 다루어야했다 ...!

PDF에 올바른 레이아웃이 인쇄되었지만 일부 EditText 필드가 비어 있습니다. 많은 좌절과 머리 긁기, 시행 착오를 거친 후에 문제가 무엇인지 알아 냈습니다. GlobalLayoutListener는 의도 한대로 작동하지만 인쇄 기능이 너무 빨리 시작되어 필드가 제대로 그려 지거나 채워질 시간이 없었던 것으로 보입니다.

이에 대처하기 위해 Handler 클래스를 사용하여 최소 지연 (100ms)을 추가 한 다음 모든 것이 원래대로 작동했습니다. 다음은 인쇄 방법의 코드는 다음과 같습니다

public void print(String orientation) { 

    print = prefs.getBoolean("print", false); 

    if (print) 
     if (orientation.contains("portrait")) { 
      new AsyncPDF(mActivity, v).execute(field_client_name_txt, 
        "birthday"); 
     } else { 
      ViewTreeObserver observer = v.getViewTreeObserver(); 
      observer.addOnGlobalLayoutListener(new OnGlobalLayoutListener() { 
       @Override 
       public void onGlobalLayout() { 
        /* Adds a minimal wait time for the view to settle */ 
        final Handler handler = new Handler(); 
        handler.postDelayed(new Runnable() { 
         @Override 
         public void run() { 
          new AsyncPDF(mActivity, v).execute(
            field_client_name_txt, "birthday"); 
         } 
        }, 100); 

        v.getViewTreeObserver().removeOnGlobalLayoutListener(
          this); 
       } 
      }); 
     } 
    /* Reset the print flag to false */ 
    prefs.edit().putBoolean("print", false).commit(); 
} 

방법은 액션 바의 인쇄 버튼에서 시작, 우리는 초상화 이미 경우, 그것은 AsyncPDF 클래스 IMM를 시작합니다. 가로 방향의 경우 세로 레이아웃이 정착 될 때까지 기다린 다음 100ms 지연을 추가 한 다음 비동기 태스크를 시작합니다.구성 변경이 발생할 때 프린트 플래그를 트리거하고 그에 따라 작용하는 경우

public void onClick(DialogInterface dialog, int id) { 
    prefs.edit().putBoolean("print", true).commit(); 
    if (mUtility.getScreenOrientation() == 1) 
      print("portrait"); 
    else 
      mUtility.lockScreenOrientation("portrait"); 
    } 
}); 

인쇄 (문자열 방향)에있어서, 상기 onActivityCreated 내부에 배치된다() 메소드 그래서, 검사.