这是我之前quesion.的延续,我想在应用中打开pdf,而不是使用第三方应用打开它。我重写了代码,以便assets
文件夹中的pdf文件可以复制到SD卡中
这是我的代码:
package com.dell.pdfreader;
import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.AssetManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import net.sf.andpdf.pdfviewer.PdfViewerActivity;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class PdfMainActivity extends AppCompatActivity implements View.OnClickListener {
private static String TAG = PdfMainActivity.class.getCanonicalName();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pdf_main);
Button click = (Button) findViewById(R.id.click);
click.setOnClickListener(this);
}
@Override
public void onClick(View view) {
Context mContext = getApplicationContext();
switch (view.getId()) {
case R.id.click:
try {
AssetManager assetManager = getAssets();
String[] files = null;
try {
files = assetManager.list("pdffiles");
} catch (IOException e) {
Log.e(TAG, e.getMessage());
}
for (String fileName : files != null ? files : new String[0]) {
InputStream is = null;
OutputStream os = null;
try {
is = assetManager.open("pdffiles/" + fileName);
os = new FileOutputStream(Environment.getExternalStorageDirectory().toString() + "/" + fileName);
copyFile(is, os);
is.close();
os.flush();
os.close();
} catch (Exception e) {
Log.e(TAG, e.getMessage());
}
}
Uri path = Uri.parse(Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "Dojo_lab_tour.pdf");
String oPath = path.toString();
Intent intent = new Intent(PdfMainActivity.this, ReaderActivity.class);
if (ContextCompat.checkSelfPermission(PdfMainActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
intent.setDataAndType(path, "application/pdf");
intent.putExtra(PdfViewerActivity.EXTRA_PDFFILENAME, oPath);
startActivity(intent);
} else {
Log.d(TAG, "No permission!");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
private void copyFile(InputStream is, OutputStream os) throws IOException {
byte[] buffer = new byte[1024];
int read;
while ((read = is.read(buffer)) != -1) {
os.write(buffer, 0, read);
}
}
}
这是我的第二项活动:
package com.dell.pdfreader;
import android.os.Bundle;
public class ReaderActivity extends net.sf.andpdf.pdfviewer.PdfViewerActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_reader);
}
@Override
public int getPreviousPageImageResource() {
return R.drawable.left_arrow;
}
@Override
public int getNextPageImageResource() {
return R.drawable.right_arrow;
}
@Override
public int getZoomInImageResource() {
return R.drawable.zoom_in;
}
@Override
public int getZoomOutImageResource() {
return R.drawable.zoom_out;
}
@Override
public int getPdfPasswordLayoutResource() {
return 0;
}
@Override
public int getPdfPageNumberResource() {
return 0;
}
@Override
public int getPdfPasswordEditField() {
return 0;
}
@Override
public int getPdfPasswordOkButton() {
return 0;
}
@Override
public int getPdfPasswordExitButton() {
return 0;
}
@Override
public int getPdfPageNumberEditField() {
return 0;
}
}
当我运行该代码时,我收到此错误:
03-05 16:19:43.000 14997-14997/com.dell.pdfreader E/com.dell.pdfreader.PdfMainActivity: /storage/emulated/0/Dojo_Lab_Tour.pdf (Permission denied)
03-05 16:19:43.049 14997-14997/com.dell.pdfreader I/PDFVIEWER: onCreate
03-05 16:19:43.049 14997-14997/com.dell.pdfreader E/PDFVIEWER: restoreInstance
03-05 16:19:43.119 14997-14997/com.dell.pdfreader I/PDFVIEWER: Intent { dat=/storage/emulated/0/Dojo_lab_tour.pdf typ=application/pdf cmp=com.dell.pdfreader/.ReaderActivity (has extras) }
03-05 16:19:43.124 14997-14997/com.dell.pdfreader I/PDFVIEWER: ST='file '/storage/emulated/0/Dojo_lab_tour.pdf' not found'
在mainfest
文件中,我添加了以下两行:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
如何解决此错误?
修改
我的资产文件夹结构如下:
我根据Tommin和Commonsware的建议修改了我的代码:
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
Intent intent = new Intent(PdfMainActivity.this, ReaderActivity.class);
if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
intent.setDataAndType(path, "application/pdf");
intent.putExtra(PdfViewerActivity.EXTRA_PDFFILENAME, oPath);
startActivity(intent);
} else {
Log.d(TAG, "No permission!");
}
}
立即收到此错误:
03-05 17:45:26.526 7888-7888/com.dell.pdfreader E/com.dell.pdfreader.PdfMainActivity: /storage/emulated/0/Dojo_Lab_Tour.pdf (Permission denied)
答案 0 :(得分:2)
1-在您的清单中添加权限,就像您一样:
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.....">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
2-这两个权限被认为是危险权限,您应该在运行时请求onClick on on on方法:
@Override
public void onClick (View view) {
if (ContextCompat.checkSelfPermission (PdfMainActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED ||
ContextCompat.checkSelfPermission (PdfMainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions (PdfMainActivity.this, new String [] { Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE }, 1000);
return;
}
...
}
3-在将流复制到其中之前,确保外部存储器是可写的:
if (!isExternalStorageWritable ()) {
throw new Exception ("External Storage Not Writable");
}
private boolean isExternalStorageWritable () {
return Environment.MEDIA_MOUNTED.equals (Environment.getExternalStorageState ());
}
4-您的代码变为:
@Override
public void onClick (View v) {
if (ContextCompat.checkSelfPermission (PdfMainActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED ||
ContextCompat.checkSelfPermission (PdfMainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions (PdfMainActivity.this, new String [] { Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE }, 1000);
return;
}
AssetManager assetManager = getAssets ();
String dir = "pdffiles";
try {
String [] paths = assetManager.list (dir);
for (String path : paths) {
if (!isExternalStorageWritable ()) {
throw new Exception ("External Storage Not Writable");
}
InputStream is = assetManager.open (dir + File.separator + path);
OutputStream os = new FileOutputStream (Environment.getExternalStorageDirectory () + File.separator + path);
copy (is, os);
closeQuietly (os, is);
}
} catch (Exception e) {
// TODO Catch your exception here
}
}
public static int copy (InputStream is, OutputStream os) throws IOException {
long count = 0;
int n;
byte [] buffer = new byte [4 * 1024];
while (-1 != (n = is.read (buffer))) {
os.write (buffer, 0, n);
count += n;
}
if (count > Integer.MAX_VALUE) {
return -1;
}
return (int) count;
}
public static void closeQuietly (Closeable... closeables) {
if (closeables == null || closeables.length == 0) {
return;
}
try {
for (Closeable closeable : closeables) {
if (closeable != null) {
closeable.close ();
}
}
} catch (final IOException ignore) { }
}
5-尝试阅读PDF时,请确保外部存储器也可以通过以下方式读取:
private boolean isExternalStorageReadable() {
String state = Environment.getExternalStorageState ();
return Environment.MEDIA_MOUNTED.equals (state) || Environment.MEDIA_MOUNTED_READ_ONLY.equals (state);
}
6-将复制处理放在后台线程上,不要阻止UI。并且可能向用户显示进度弹出窗口。
答案 1 :(得分:0)
我明白了,伙计们。我修改了我的代码:
Uri path = Uri.parse(Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "EPSF.pdf");
String oPath = path.toString();
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
&& checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED ) {
ActivityCompat.requestPermissions(PdfMainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE}, 1000);
Log.d(TAG, "No permission!");
} else {
Intent intent1 = new Intent(PdfMainActivity.this, ReaderActivity.class);
intent1.setDataAndType(path, "application/pdf");
intent1.putExtra(PdfViewerActivity.EXTRA_PDFFILENAME, oPath);
startActivity(intent1);
}
}
我添加了运行时权限,并根据Mehdi的建议进行了修改。