Android的库中不支持PDF。有没有办法在Android应用程序中呈现PDF文件?
当前回答
我使用下面的代码使用Wi-Fi打开并打印PDF。我正在发送我的整个代码,我希望它是有用的。
public class MainActivity extends Activity {
int Result_code = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button mButton = (Button)findViewById(R.id.button1);
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
PrintManager printManager = (PrintManager)getSystemService(Context.PRINT_SERVICE);
String jobName = " Document";
printManager.print(jobName, pda, null);
}
});
}
public void openDocument(String name) {
Intent intent = new Intent(android.content.Intent.ACTION_VIEW);
File file = new File(name);
String extension = android.webkit.MimeTypeMap.getFileExtensionFromUrl(Uri.fromFile(file).toString());
String mimetype = android.webkit.MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
if (extension.equalsIgnoreCase("") || mimetype == null) {
// if there is no extension or there is no definite mimetype, still try to open the file
intent.setDataAndType(Uri.fromFile(file), "text/*");
}
else {
intent.setDataAndType(Uri.fromFile(file), mimetype);
}
// custom message for the intent
startActivityForResult((Intent.createChooser(intent, "Choose an Application:")), Result_code);
//startActivityForResult(intent, Result_code);
//Toast.makeText(getApplicationContext(),"There are no email clients installed.", Toast.LENGTH_SHORT).show();
}
@SuppressLint("NewApi")
PrintDocumentAdapter pda = new PrintDocumentAdapter(){
@Override
public void onWrite(PageRange[] pages, ParcelFileDescriptor destination, CancellationSignal cancellationSignal, WriteResultCallback callback){
InputStream input = null;
OutputStream output = null;
try {
String filename = Environment.getExternalStorageDirectory() + "/" + "Holiday.pdf";
File file = new File(filename);
input = new FileInputStream(file);
output = new FileOutputStream(destination.getFileDescriptor());
byte[] buf = new byte[1024];
int bytesRead;
while ((bytesRead = input.read(buf)) > 0) {
output.write(buf, 0, bytesRead);
}
callback.onWriteFinished(new PageRange[]{PageRange.ALL_PAGES});
}
catch (FileNotFoundException ee){
//Catch exception
}
catch (Exception e) {
//Catch exception
}
finally {
try {
input.close();
output.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
@Override
public void onLayout(PrintAttributes oldAttributes, PrintAttributes newAttributes, CancellationSignal cancellationSignal, LayoutResultCallback callback, Bundle extras){
if (cancellationSignal.isCanceled()) {
callback.onLayoutCancelled();
return;
}
// int pages = computePageCount(newAttributes);
PrintDocumentInfo pdi = new PrintDocumentInfo.Builder("Name of file").setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT).build();
callback.onLayoutFinished(pdi, true);
}
};
}
其他回答
因为API Level 21 (Lollipop) Android提供了一个PdfRenderer类:
// create a new renderer
PdfRenderer renderer = new PdfRenderer(getSeekableFileDescriptor());
// let us just render all pages
final int pageCount = renderer.getPageCount();
for (int i = 0; i < pageCount; i++) {
Page page = renderer.openPage(i);
// say we render for showing on the screen
page.render(mBitmap, null, null, Page.RENDER_MODE_FOR_DISPLAY);
// do stuff with the bitmap
// close the page
page.close();
}
// close the renderer
renderer.close();
有关更多信息,请参阅示例应用程序。
对于旧的api,我推荐Android PdfViewer库,它非常快速和容易使用,在Apache许可证2.0下授权:
pdfView.fromAsset(String)
.pages(0, 2, 1, 3, 3, 3) // all pages are displayed by default
.enableSwipe(true)
.swipeHorizontal(false)
.enableDoubletap(true)
.defaultPage(0)
.onDraw(onDrawListener)
.onLoad(onLoadCompleteListener)
.onPageChange(onPageChangeListener)
.onPageScroll(onPageScrollListener)
.onError(onErrorListener)
.enableAnnotationRendering(false)
.password(null)
.scrollHandle(null)
.load();
我终于能够修改butelo的代码,使用PDF .js打开Android文件系统中的任何PDF文件。代码可以在我的GitHub上找到
我所做的是修改pdffile.js读取HTML参数文件如下:
var url = getURLParameter('file');
function getURLParameter(name) {
return decodeURIComponent((new RegExp('[?|&]' + name + '=' + '([^&;]+?)(&|#|;|$)').exec(location.search)||[,""])[1].replace(/\+/g, '%20'))||null}
所以你需要做的就是像这样在index.html后面追加文件路径:
Uri path = Uri.parse(Environment.getExternalStorageDirectory().toString() + "/data/test.pdf");
webView.loadUrl("file:///android_asset/pdfviewer/index.html?file=" + path);
更新路径变量以指向Adroid文件系统中的有效PDF。
我有GoogleDrive选项的问题,有时它会无法加载文档和“com.github.barteksc:android-pdf-viewer:2.7.0”,虽然它的文档使它看起来很容易从链接加载文档,但我未能使它工作。它总是抛出一个FileNotFoundException异常,因此经过进一步研究,我了解到它下载pdf,因此您必须使它指向该文档,我发现这有点乏味。
你可以试试这个库。它非常容易使用,并且至今仍在维护,我不知道几年之后他们是否会停止更新它。它会缓存文档,你甚至不需要跟踪它的路径。
https://levelup.gitconnected.com/open-pdf-files-in-android-without-webviews-or-intents-3cc960752cca
以下是如何在不使用任何第三方库的情况下从PDF文件中获得位图缩略图的方法。
private fun loadThumbnailFromPdfFile(file:File, thumbnailImageView: ImageView) {
Log.d(TAG, "loadThumbnailFromPdfFile: ")
val mFileDescriptor = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY)
// This is the PdfRenderer we use to render the PDF.
val mPdfRenderer = PdfRenderer(mFileDescriptor)
//check if pdf have no pages then we can't show pdf thumbnail
if (mPdfRenderer.pageCount <= 0) {
//No pages in pdf, can't show thumbnail
Log.d(TAG, "loadThumbnailFromPdfFile: No pages in pdf")
} else {
//There are page(s) in pdf, can show pdf thumbnail
//Use `openPage` to open a specific page in PDF.
val mCurrentPage = mPdfRenderer.openPage(0)
// Important: the destination bitmap must be ARGB (not RGB).
val bitmap = Bitmap.createBitmap(mCurrentPage.width, mCurrentPage.height, Bitmap.Config.ARGB_8888)
// Here, we render the page onto the Bitmap.
// To render a portion of the page, use the second and third parameter. Pass nulls to get
// the default result.
// Pass either RENDER_MODE_FOR_DISPLAY or RENDER_MODE_FOR_PRINT for the last parameter.
mCurrentPage.render(bitmap, null, null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY)
// We are ready to show the Bitmap to user.
thumbnailImageView.setImageBitmap(bitmap)
}
}
我使用下面的代码使用Wi-Fi打开并打印PDF。我正在发送我的整个代码,我希望它是有用的。
public class MainActivity extends Activity {
int Result_code = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button mButton = (Button)findViewById(R.id.button1);
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
PrintManager printManager = (PrintManager)getSystemService(Context.PRINT_SERVICE);
String jobName = " Document";
printManager.print(jobName, pda, null);
}
});
}
public void openDocument(String name) {
Intent intent = new Intent(android.content.Intent.ACTION_VIEW);
File file = new File(name);
String extension = android.webkit.MimeTypeMap.getFileExtensionFromUrl(Uri.fromFile(file).toString());
String mimetype = android.webkit.MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
if (extension.equalsIgnoreCase("") || mimetype == null) {
// if there is no extension or there is no definite mimetype, still try to open the file
intent.setDataAndType(Uri.fromFile(file), "text/*");
}
else {
intent.setDataAndType(Uri.fromFile(file), mimetype);
}
// custom message for the intent
startActivityForResult((Intent.createChooser(intent, "Choose an Application:")), Result_code);
//startActivityForResult(intent, Result_code);
//Toast.makeText(getApplicationContext(),"There are no email clients installed.", Toast.LENGTH_SHORT).show();
}
@SuppressLint("NewApi")
PrintDocumentAdapter pda = new PrintDocumentAdapter(){
@Override
public void onWrite(PageRange[] pages, ParcelFileDescriptor destination, CancellationSignal cancellationSignal, WriteResultCallback callback){
InputStream input = null;
OutputStream output = null;
try {
String filename = Environment.getExternalStorageDirectory() + "/" + "Holiday.pdf";
File file = new File(filename);
input = new FileInputStream(file);
output = new FileOutputStream(destination.getFileDescriptor());
byte[] buf = new byte[1024];
int bytesRead;
while ((bytesRead = input.read(buf)) > 0) {
output.write(buf, 0, bytesRead);
}
callback.onWriteFinished(new PageRange[]{PageRange.ALL_PAGES});
}
catch (FileNotFoundException ee){
//Catch exception
}
catch (Exception e) {
//Catch exception
}
finally {
try {
input.close();
output.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
@Override
public void onLayout(PrintAttributes oldAttributes, PrintAttributes newAttributes, CancellationSignal cancellationSignal, LayoutResultCallback callback, Bundle extras){
if (cancellationSignal.isCanceled()) {
callback.onLayoutCancelled();
return;
}
// int pages = computePageCount(newAttributes);
PrintDocumentInfo pdi = new PrintDocumentInfo.Builder("Name of file").setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT).build();
callback.onLayoutFinished(pdi, true);
}
};
}
推荐文章
- 警告:API ' variable . getjavacompile()'已过时,已被' variable . getjavacompileprovider()'取代
- 安装APK时出现错误
- 在流中使用Java 8 foreach循环移动到下一项
- 访问限制:'Application'类型不是API(必需库rt.jar的限制)
- 用Java计算两个日期之间的天数
- 碎片中的onCreateOptionsMenu
- 如何配置slf4j-simple
- 在Jar文件中运行类
- 带参数的可运行?
- TextView粗体通过XML文件?
- 如何使线性布局的孩子之间的空间?
- 我如何得到一个字符串的前n个字符而不检查大小或出界?
- 我可以在Java中设置enum起始值吗?
- Java中的回调函数
- c#和Java中的泛型有什么不同?和模板在c++ ?