[英]open a pdf file programmatically
I am working on pdf.我正在处理 pdf。 I am trying to open a pdf file from my application using the code below.
我正在尝试使用以下代码从我的应用程序中打开 pdf 文件。 But I failed to open.
但是我打不开。
private void openPdf() {
File file = new File("mnt/sdcard.test.pdf");
Uri path = Uri.fromFile(file);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.setAction(Intent.ACTION_VIEW);
intent.setData(path);
intent.setType("application/pdf");
try {
startActivity(intent);
} catch (ActivityNotFoundException e) {
Toast.makeText(getActivity(), "No application found",
Toast.LENGTH_SHORT).show();
}
}
When I tried this code in emulator,it shows a toast saying "No application found"(bcoz,normally no pdf viewing application are installed in emulator).当我在模拟器中尝试这段代码时,它显示一个吐司说“找不到应用程序”(bcoz,通常模拟器中没有安装pdf查看应用程序)。 When I tested the same thing in device (specifically in funbook tab and in sony tab), it neither showed the Toast message nor it opened the pdf file.
当我在设备(特别是在 funbook 选项卡和 sony 选项卡中)测试相同的东西时,它既没有显示 Toast 消息,也没有打开 pdf 文件。 Can anybody point out the mistake in my code.
任何人都可以指出我的代码中的错误。 Actually I am working with pdf for the first time.
其实我是第一次使用pdf。 So my question is,
所以我的问题是,
I got solution of above problem, so try once;我得到了上述问题的解决方案,所以尝试一次;
Steps:-脚步:-
create assets folder in src under your app name.在您的应用程序名称下的 src 中创建资产文件夹。
In this assets folder keep your pdf files eg schedule1.pdf.在这个资产文件夹中保存您的 pdf 文件,例如 schedule1.pdf。
now come your activity ie MainActivity.java现在来你的活动,即 MainActivity.java
setListener on any UI component what you want ie ( Button
, ImageView
, ImageButton
); setListener 在任何 UI 组件上你想要什么,即(
Button
、 ImageView
、 ImageButton
);
In this listener call one user defined method ie openPDFFiles()
在此侦听器中调用一个用户定义的方法,即
openPDFFiles()
the openPDFFiles() method have below code: openPDFFiles() 方法具有以下代码:
private void openPDFFiles() {
AssetManager assetManager = getAssets();
InputStream in = null;
OutputStream out = null;
File file = new File(getFilesDir(), “schedule1.pdf”);//here schedule1.pdf is the pdf file name which is keep in assets folder.
try {
in = assetManager.open(“schedule1.pdf”);
out = openFileOutput(file.getName(), Context.MODE_WORLD_READABLE);
copyFile(in, out);
in.close();
in = null;
out.flush();
out.close();
out = null;
} catch (Exception e) {
Log.e(“tag”, e.getMessage());
}
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.parse(“file://” + getFilesDir() + “/schedule1.pdf”), “application/pdf”);
startActivity(intent);
}
private void copyFile(InputStream in, OutputStream out) throws IOException {
byte[] buffer = new byte[1024];
int read;
while ((read = in.read(buffer)) != -1) {
out.write(buffer, 0, read);
}
}
Try LuxuryMode's method: https://stackoverflow.com/a/8221594/1500067试试 LuxuryMode 的方法: https ://stackoverflow.com/a/8221594/1500067
I think your just missing the adobe package intent.setPackage("com.adobe.reader");我认为您只是缺少 adobe 包 intent.setPackage("com.adobe.reader");
for android 9 and 10
you should use this code对于
android 9 and 10
您应该使用此代码
1-create one class
1-创建一个
class
public class GenericFileProvider extends FileProvider {
}
2-in res
directory create one directory to name of xml
and create one file to name of provider_paths.xml
and add this code 2-in
res
目录创建一个以xml
命名的目录并创建一个以provider_paths.xml
命名的文件并添加此代码
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external_files" path="."/>
</paths>
3-in manifests
in application
add this code application
3-in manifests
添加此代码
<provider
android:name=".Model.Utilitys.GenericFileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths"/>
</provider>
4-you should get Permission Manifest.permission.READ_EXTERNAL_STORAGE
4-你应该得到 Permission
Manifest.permission.READ_EXTERNAL_STORAGE
5-and add this codes 5-并添加此代码
String fileName="yourfile.pdf";
File file = new File(Environment.getExternalStorageDirectory()+"/Android/data/ir.tdaapp.paymanyar/files/File",fileName);
String extension = MimeTypeMap.getFileExtensionFromUrl(Uri.fromFile(file).toString());
String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setFlags(FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_NEW_TASK);
Uri uri = FileProvider.getUriForFile(getContext(), getActivity().getApplicationContext().getPackageName() + ".provider", file);
intent.setDataAndType(uri, mimeType);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(Intent.createChooser(intent, "choseFile"));
6-I suggest you add this code to the application
in manifests
6-我建议您将此代码添加到
manifests
的application
中
android:requestLegacyExternalStorage="true"
I have nearly identical code that works fine, though I'm not opening a file from SD card in my app.我有几乎相同的代码可以正常工作,但我没有在我的应用程序中打开 SD 卡中的文件。
Activity mActivity = /* your activity */...;
String mFileName = /* path of my PDF file */...;
Uri uri = Uri.fromFile(mActivity.getFileStreamPath(mFileName));
try
{
Intent intentUrl = new Intent(Intent.ACTION_VIEW);
intentUrl.setDataAndType(uri, "application/pdf");
intentUrl.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
mActivity.startActivity(intentUrl);
}
catch (ActivityNotFoundException e)
{
Toast.makeText(mActivity, "No PDF Viewer Installed", Toast.LENGTH_LONG).show();
}
so your approach is right on.所以你的方法是正确的。 Make sure you can open the file first ... ie use mActivity.openFileInput() to ensure you have a readable PDF.
确保您可以先打开文件……即使用 mActivity.openFileInput() 确保您拥有可读的 PDF。
You can achieve this using 3rd party library integration.您可以使用 3rd 方库集成来实现这一点。 Working libraries are listed below, with SDK
下面列出了工作库,带有 SDK
https://github.com/JoanZapata/android-pdfview
https://github.com/JoanZapata/android-pdfview
https://github.com/jblough/Android-Pdf-Viewer-Libraryhttps://github.com/jblough/Android-Pdf-Viewer-Library
with NDK使用 NDK
https://code.google.com/p/mupdf/downloads/detail?name=mupdf-1.2-source.zip&can=2&q=
https://code.google.com/p/mupdf/downloads/detail?name=mupdf-1.2-source.zip&can=2&q=
guide to use @使用指南@
http://dixitpatel.com/integrating-pdf-in-android-application/
http://dixitpatel.com/integrating-pdf-in-android-application/
Download the source code here( Display PDF file inside my android application )在此处下载源代码( 在我的 android 应用程序中显示 PDF 文件)
Add this dependency in your Gradle file:在您的 Gradle 文件中添加此依赖项:
compile 'com.github.barteksc:android-pdf-viewer:2.0.3'
activity_main.xml活动_main.xml
<RelativeLayout android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff"
xmlns:android="http://schemas.android.com/apk/res/android" >
<TextView
android:layout_width="match_parent"
android:layout_height="40dp"
android:background="@color/colorPrimaryDark"
android:text="View PDF"
android:textColor="#ffffff"
android:id="@+id/tv_header"
android:textSize="18dp"
android:gravity="center"></TextView>
<com.github.barteksc.pdfviewer.PDFView
android:id="@+id/pdfView"
android:layout_below="@+id/tv_header"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
MainActivity.java主活动.java
import android.app.Activity;
import android.database.Cursor;
import android.net.Uri;
import android.provider.OpenableColumns;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import com.github.barteksc.pdfviewer.PDFView;
import com.github.barteksc.pdfviewer.listener.OnLoadCompleteListener;
import com.github.barteksc.pdfviewer.listener.OnPageChangeListener;
import com.github.barteksc.pdfviewer.scroll.DefaultScrollHandle;
import com.shockwave.pdfium.PdfDocument;
import java.util.List;
public class MainActivity extends Activity implements OnPageChangeListener,OnLoadCompleteListener{
private static final String TAG = MainActivity.class.getSimpleName();
public static final String SAMPLE_FILE = "android_tutorial.pdf";
PDFView pdfView;
Integer pageNumber = 0;
String pdfFileName;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
pdfView= (PDFView)findViewById(R.id.pdfView);
displayFromAsset(SAMPLE_FILE);
}
private void displayFromAsset(String assetFileName) {
pdfFileName = assetFileName;
pdfView.fromAsset(SAMPLE_FILE)
.defaultPage(pageNumber)
.enableSwipe(true)
.swipeHorizontal(false)
.onPageChange(this)
.enableAnnotationRendering(true)
.onLoad(this)
.scrollHandle(new DefaultScrollHandle(this))
.load();
}
@Override
public void onPageChanged(int page, int pageCount) {
pageNumber = page;
setTitle(String.format("%s %s / %s", pdfFileName, page + 1, pageCount));
}
@Override
public void loadComplete(int nbPages) {
PdfDocument.Meta meta = pdfView.getDocumentMeta();
printBookmarksTree(pdfView.getTableOfContents(), "-");
}
public void printBookmarksTree(List<PdfDocument.Bookmark> tree, String sep) {
for (PdfDocument.Bookmark b : tree) {
Log.e(TAG, String.format("%s %s, p %d", sep, b.getTitle(), b.getPageIdx()));
if (b.hasChildren()) {
printBookmarksTree(b.getChildren(), sep + "-");
}
}
}
}
I know maybe is too late for an answer, but your problem is cause by these 2 line: intent.setData(path);
我知道答案可能为时已晚,但您的问题是由以下两行引起的:
intent.setData(path);
intent.setType("application/pdf");
When you setData and after that you setType, the second command will clean the path assingned in setData.当你 setData 然后你 setType 时,第二个命令将清理 setData 中的路径。 In this situation, you should use
setDataAndType(path,"application/pdf")
在这种情况下,您应该使用
setDataAndType(path,"application/pdf")
/** * Set an explicit MIME data type. * * <p>This is used to create intents that only specify a type and not data, * for example to indicate the type of data to return. * * <p>This method automatically clears any data that was * previously set (for example by {@link #setData}). * * <p><em>Note: MIME type matching in the Android framework is * case-sensitive, unlike formal RFC MIME types. As a result, * you should always write your MIME types with lower case letters, * or use {@link #normalizeMimeType} or {@link #setTypeAndNormalize} * to ensure that it is converted to lower case.</em> * * @param type The MIME type of the data being handled by this intent. * * @return Returns the same Intent object, for chaining multiple calls * into a single statement. * * @see #getType * @see #setTypeAndNormalize * @see #setDataAndType * @see #normalizeMimeType */ public Intent setType(String type) { mData = null; mType = type; return this; }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.