Cómo renderizar PDF en Android

81

En mi aplicación, recibiré un flujo de bytes y lo convertiré en un archivo pdf en la memoria del teléfono. ¿Cómo convierto eso en un pdf? ¿Y mostrarlo en una actividad?

Mikey
fuente
Esto ha sido respondido aquí: stackoverflow.com/a/16294833/2027232
Nicolas Tyler

Respuestas:

115

Algunos teléfonos (como el Nexus One) vienen con una versión de Quickoffice preinstalada, por lo que puede ser tan fácil como enviar el Intent apropiado una vez que haya guardado el archivo en la tarjeta SD.

public class OpenPdf extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        Button button = (Button) findViewById(R.id.OpenPdfButton);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                File file = new File("/sdcard/example.pdf");

                if (file.exists()) {
                    Uri path = Uri.fromFile(file);
                    Intent intent = new Intent(Intent.ACTION_VIEW);
                    intent.setDataAndType(path, "application/pdf");
                    intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

                    try {
                        startActivity(intent);
                    } 
                    catch (ActivityNotFoundException e) {
                        Toast.makeText(OpenPdf.this, 
                            "No Application Available to View PDF", 
                            Toast.LENGTH_SHORT).show();
                    }
                }
            }
        });
    }
}
Tim Kryger
fuente
1
Hmm, intentaré esto mañana. así que de los flujos de bytes obtendré que necesito guardarlos como un archivo y luego intentar hacer ese código.
Mikey
18
hmm ¿qué tal si no tengo QuickOffice instalado en mi Android?
Mikey
2
¿entonces? ¿Qué pasa si no tiene QuickOffice?
Necronet
Si el teléfono no tiene Office rápido, entonces?
Tofeeq Ahmad
6
¿Cómo abrir el archivo PDF directamente desde el servidor? En lugar de guardarlo en el dispositivo y luego abrirlo.
EnthuDeveloper
16

Abra el archivo pdf en webview .

public class MyPdfViewActivity extends Activity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    WebView mWebView=new WebView(MyPdfViewActivity.this);
    mWebView.getSettings().setJavaScriptEnabled(true);
    mWebView.getSettings().setPluginsEnabled(true);
    mWebView.loadUrl("https://docs.google.com/gview?embedded=true&url="+LinkTo);
    setContentView(mWebView);
  }
}
Shankar Agarwal
fuente
Creo que esto solo funciona con el enlace del visor de Google, porque solo sirve imágenes. Si usamos el enlace a PDF directamente, no funcionará. Es eso correcto ?
Nathan Do
Esto no parece funcionar para archivos locales, solo remotos.
Alfie Hanssen
2
¿Qué pasa si el enlace cambia?
Shuhrat Akramov
3
"Después de probarlo de manera persistente durante 2 días, recibí un error en los documentos de Google que decía que alcanzó el límite de ancho de banda para ver o descargar archivos que no están en formato de Google Docs ... Por lo que no parece confiable". stackoverflow.com/questions/2655972/…
Wédney Yuri
9

Android-Lollipop (api 21) presenta una nueva API: PdfRenderer

Esta API le permite crear un mapa de bits a partir de una página en un documento PDF.

En breve:

  • obtenga un descriptor de archivo de búsqueda de su documento pdf:

      ParcelFileDescriptor fd = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY)
    
  • crear el PdfRenderer

      PdfRenderer renderer = new PdfRenderer(fd);
    
  • preparar el mapa de bits

      Bitmap bitmap = Bitmap.createBitmap(WIDTH, HEIGHT, Bitmap.Config.ARGB_4444);
    
  • obtener la página PdfRenderer.Page para renderizar

      PdfRenderer.Page page = renderer.openPage(pageIndex);
    
  • renderizar la página en el mapa de bits preparado

      page.render(bitmap, null, null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY);
    
  • ahora puede hacer lo que quiera con el mapa de bits.

  • tenga en cuenta que los 2 argumentos nulos pueden permitirle recortar alguna parte de la página y realizar una transformación (utilizando una matriz ) del clip

  • hay otro modo de renderizado: RENDER_MODE_FOR_PRINT . Si necesita este modo, hay algunas pautas para usarlo correctamente: aquí están los detalles .

ben75
fuente
3
¿Hay alguna forma de lograr esto sin guardar el archivo en el teléfono? Obtengo PDF como bytestream y necesito mostrárselo al usuario sin guardarlo en el teléfono.
Gokhan Arik
la restricción es pasar un descriptor de archivo que se pueda buscar al constructor; y fd de un flujo de socket no se puede buscar. Puede intentar almacenar todos los bytes de la secuencia en un búfer y obtener un fd buscable de eso.
ben75
5

Esta biblioteca es simple y funciona bien: Visor de PDF de Android https://github.com/barteksc/AndroidPdfViewer

Respuesta anterior ...

Creo que Joan Zapata nos da la mejor y más sencilla solución:

https://github.com/JoanZapata/android-pdfview

¡Te aseguro que funciona!

1 : https://github.com/JoanZapata/android-pdfview

Alecs
fuente
1
Alecs: ¿Qué usaste para pdfName en pdfView.fromAsset(pdfName)? Intenté usar la ruta absoluta, pero no se encontró el archivo (y estoy seguro de que está allí). Ejemplo: /data/data/package.name/files/images/filename.pdf
h-bomb
1
Estimado @ h-bomb, debe usar el método fromasset cuando su pdf está en el foder de activos de su proyecto. Para cargar el pdf desde el dispositivo, puede utilizar el método fromFile .
Alecs
1
Muchas gracias. Decidí usar FileProvider de Android y permitir que una aplicación externa abra el PDF. Sorprendentemente, la documentación y el código de muestra en el documento de desarrollo de FileProvider fueron excelentes.
bomba h
3

Para los archivos PDF locales, puede renderizarlos a través de bibliotecas de terceros. por ejemplo, use la biblioteca MuPDF , sus tipos de archivos admitidos incluyen PDF, PNG y JPEG.

Una deficiencia de MuPDF es que utiliza una biblioteca nativa para cumplir con el objetivo, por lo que no será fácil migrar la aplicación a la plataforma BlackBerry más adelante.

Céfiro
fuente
0

Para abrir un pdf desde una matriz de bytes, puede usar RadaeePDF, puede hacer lo siguiente en su actividad:

private PDFReader m_vPDF = null;
private Document doc = new Document();

public void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    Global.Init(this);

    m_vPDF = new PDFReader(this);
    doc.Close();

    int ret = m_doc.OpenMem(data, password);
        switch( ret )
        {
            case -1://need input password
                finish();
                break;
            case -2://unknown encryption
                finish();
                break;
            case -3://damaged or invalid format
                finish();
                break;
            case -10://access denied or invalid file path
                finish();
                break;
            case 0://succeeded, and continue
                break;
            default://unknown error
                finish();
                break;
        }

    m_vPDF.open(doc);

    setContentView( m_vPDF );
}
Nermeen
fuente