从我的 Android 应用程序以编程方式打开选定的文件(图像、pdf、...)?
Posted
技术标签:
【中文标题】从我的 Android 应用程序以编程方式打开选定的文件(图像、pdf、...)?【英文标题】:Open a selected file (image, pdf, ...) programmatically from my Android Application? 【发布时间】:2013-10-25 16:03:10 【问题描述】:我正在开发一个应该能够从特定文件夹打开选定文件的 android 应用程序。
我已经尝试过了,但是在选择了我要打开的应用程序后,我收到了这条消息:
无法加载
在尝试了很多thread 1和thread 2之后,我用这几行代码来做:
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.parse("/mnt/sdcard/xxx/xxx/Pictures/xxx.jpg"), "image/*");
myContext.startActivity(intent);
我该如何解决这个问题?
【问题讨论】:
这是一个简单有效的方法:indyvision.net/2010/03/android-using-intents-open-files ***.com/a/59104787/3141844 + github.com/criss721/Android-FileSelector 【参考方案1】:试试下面的代码。我正在使用此代码打开 PDF 文件。您也可以将其用于其他文件。
File file = new File(Environment.getExternalStorageDirectory(),
"Report.pdf");
Uri path = Uri.fromFile(file);
Intent pdfOpenintent = new Intent(Intent.ACTION_VIEW);
pdfOpenintent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
pdfOpenintent.setDataAndType(path, "application/pdf");
try
startActivity(pdfOpenintent);
catch (ActivityNotFoundException e)
如果要打开文件,可以更改setDataAndType(path, "application/pdf")
。如果你想以相同的意图打开不同的文件,你可以使用Intent.createChooser(intent, "Open in...");
。如需更多信息,请查看How to make an intent with multiple actions。
【讨论】:
感谢@Ameer 的回答。这真的很有帮助。因此,为了管理所有类型的文件,我将 "application/pdf" 替换为 "*/*"。 图片、音频或其他文件格式@Ameer 呢?【参考方案2】:使用这段代码,它帮助我打开所有类型的文件......
private void openFile(File url)
try
Uri uri = Uri.fromFile(url);
Intent intent = new Intent(Intent.ACTION_VIEW);
if (url.toString().contains(".doc") || url.toString().contains(".docx"))
// Word document
intent.setDataAndType(uri, "application/msword");
else if (url.toString().contains(".pdf"))
// PDF file
intent.setDataAndType(uri, "application/pdf");
else if (url.toString().contains(".ppt") || url.toString().contains(".pptx"))
// Powerpoint file
intent.setDataAndType(uri, "application/vnd.ms-powerpoint");
else if (url.toString().contains(".xls") || url.toString().contains(".xlsx"))
// Excel file
intent.setDataAndType(uri, "application/vnd.ms-excel");
else if (url.toString().contains(".zip"))
// ZIP file
intent.setDataAndType(uri, "application/zip");
else if (url.toString().contains(".rar"))
// RAR file
intent.setDataAndType(uri, "application/x-rar-compressed");
else if (url.toString().contains(".rtf"))
// RTF file
intent.setDataAndType(uri, "application/rtf");
else if (url.toString().contains(".wav") || url.toString().contains(".mp3"))
// WAV audio file
intent.setDataAndType(uri, "audio/x-wav");
else if (url.toString().contains(".gif"))
// GIF file
intent.setDataAndType(uri, "image/gif");
else if (url.toString().contains(".jpg") || url.toString().contains(".jpeg") || url.toString().contains(".png"))
// JPG file
intent.setDataAndType(uri, "image/jpeg");
else if (url.toString().contains(".txt"))
// Text file
intent.setDataAndType(uri, "text/plain");
else if (url.toString().contains(".3gp") || url.toString().contains(".mpg") ||
url.toString().contains(".mpeg") || url.toString().contains(".mpe") || url.toString().contains(".mp4") || url.toString().contains(".avi"))
// Video files
intent.setDataAndType(uri, "video/*");
else
intent.setDataAndType(uri, "*/*");
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
catch (ActivityNotFoundException e)
Toast.makeText(context, "No application found which can open the file", Toast.LENGTH_SHORT).show();
【讨论】:
一些高级技巧:也许你想考虑使用正则表达式模式来简化 if..else 那里的条件。【参考方案3】:从这里下载源代码 (https://deepshikhapuri.wordpress.com/2017/04/24/open-pdf-file-from-sdcard-in-android-programmatically/)
activity_main.xml:
<?xml version=”1.0″ encoding=”utf-8″?>
<RelativeLayout xmlns:android=”http://schemas.android.com/apk/res/android”
xmlns:tools=”http://schemas.android.com/tools”
android:id=”@+id/activity_main”
android:layout_width=”match_parent”
android:layout_height=”match_parent”
android:background=”#efefef”>
<ListView
android:layout_width=”match_parent”
android:id=”@+id/lv_pdf”
android:divider=”#efefef”
android:layout_marginLeft=”10dp”
android:layout_marginRight=”10dp”
android:layout_marginTop=”10dp”
android:layout_marginBottom=”10dp”
android:dividerHeight=”5dp”
android:layout_height=”wrap_content”>
</ListView>
</RelativeLayout>
MainActivity.java:
package com.pdffilefromsdcard;
import android.Manifest;
import android.app.ProgressDialog;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Environment;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.Toast;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class MainActivity extends AppCompatActivity
ListView lv_pdf;
public static ArrayList<File> fileList = new ArrayList<File>();
PDFAdapter obj_adapter;
public static int REQUEST_PERMISSIONS = 1;
boolean boolean_permission;
File dir;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
private void init()
lv_pdf = (ListView) findViewById(R.id.lv_pdf);
dir = new File(Environment.getExternalStorageDirectory().getAbsolutePath());
fn_permission();
lv_pdf.setOnItemClickListener(new AdapterView.OnItemClickListener()
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l)
Intent intent = new Intent(getApplicationContext(), PdfActivity.class);
intent.putExtra(“position”, i);
startActivity(intent);
Log.e(“Position”, i + “”);
);
public ArrayList<File> getfile(File dir)
File listFile[] = dir.listFiles();
if (listFile != null && listFile.length > 0)
for (int i = 0; i < listFile.length; i++)
if (listFile[i].isDirectory())
getfile(listFile[i]);
else
boolean booleanpdf = false;
if (listFile[i].getName().endsWith(“.pdf”))
for (int j = 0; j < fileList.size(); j++)
if (fileList.get(j).getName().equals(listFile[i].getName()))
booleanpdf = true;
else
if (booleanpdf)
booleanpdf = false;
else
fileList.add(listFile[i]);
return fileList;
private void fn_permission()
if ((ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED))
if ((ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, android.Manifest.permission.READ_EXTERNAL_STORAGE)))
else
ActivityCompat.requestPermissions(MainActivity.this, new String[]android.Manifest.permission.READ_EXTERNAL_STORAGE,
REQUEST_PERMISSIONS);
else
boolean_permission = true;
getfile(dir);
obj_adapter = new PDFAdapter(getApplicationContext(), fileList);
lv_pdf.setAdapter(obj_adapter);
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults)
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_PERMISSIONS)
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
boolean_permission = true;
getfile(dir);
obj_adapter = new PDFAdapter(getApplicationContext(), fileList);
lv_pdf.setAdapter(obj_adapter);
else
Toast.makeText(getApplicationContext(), “Please allow the permission”, Toast.LENGTH_LONG).show();
activity_pdf.xml:
<?xml version=”1.0″ encoding=”utf-8″?>
<LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android”
android:layout_width=”match_parent”
android:background=”#ffffff”
android:layout_height=”match_parent”
android:orientation=”vertical”>
<com.github.barteksc.pdfviewer.PDFView
android:id=”@+id/pdfView”
android:layout_margin=”10dp”
android:layout_width=”match_parent”
android:layout_height=”match_parent” />
</LinearLayout>
PdfActivity.java:
package com.pdffilefromsdcard;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
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.io.File;
import java.util.List;
public class PdfActivity extends AppCompatActivity implements OnPageChangeListener,OnLoadCompleteListener
PDFView pdfView;
Integer pageNumber = 0;
String pdfFileName;
String TAG=”PdfActivity”;
int position=-1;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pdf);
init();
private void init()
pdfView= (PDFView)findViewById(R.id.pdfView);
position = getIntent().getIntExtra(“position”,-1);
displayFromSdcard();
private void displayFromSdcard()
pdfFileName = MainActivity.fileList.get(position).getName();
pdfView.fromFile(MainActivity.fileList.get(position))
.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 + “-“);
谢谢!
【讨论】:
【参考方案4】:试试下面的代码。
File file = new File(path); // path = your file path
lastSlash = file.toString().lastIndexOf('/');
if (lastSlash >= 0)
fileName = url.toString().substring(lastSlash + 1);
if (fileName.endsWith("pdf"))
mimeType = "application/pdf";
else
mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension
(MimeTypeMap.getFileExtensionFromUrl(path));
Uri uri_path = Uri.fromFile(file);
Intent intent = new Intent(android.content.Intent.ACTION_VIEW);
intent.putExtra(PATH, path);
intent.putExtra(MIMETYPE, mimeType);
intent.setType(mimeType);
intent.setDataAndType(uri_path, mimeType);
startActivity(intent);
【讨论】:
【参考方案5】:要以编程方式在 Android 中打开文件,您可以使用以下代码:- 我们使用 File Provider 进行内部文件访问。您还可以在此链接中查看有关 File Provider 的详细信息fileprovidr1,file provider2,file provider3。 创建一个文件提供程序并在清单文件中定义。
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.packagename.app.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths">
</meta-data>
</provider>
在资源文件中定义file_path。
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path
name="my_images"
path="Android/data/com.packagename.app/files/Pictures" />
<external-files-path name="vivalinkComProp" path="Android/data/com.vivalink.app/vivalinkComProp/docs"/>
<external-path
name="external"
path="." />
<external-files-path
name="external_files"
path="." />
<cache-path
name="cache"
path="." />
<external-cache-path
name="external_cache"
path="." />
<files-path
name="files"
path="." />
</paths>
定义视图意图
String directory_path = Environment.getExternalStorageDirectory().getPath() + "/MyFile/";
String targetPdf = directory_path + fileName + ".pdf";
File filePath = new File(targetPdf);
Intent intentShareFile = new Intent(Intent.ACTION_VIEW);
File fileWithinMyDir = new File(targetPdf);
Uri bmpUri = FileProvider.getUriForFile(activity, "com.packagename.app.fileprovider", filePath);
if (fileWithinMyDir.exists())
intentShareFile.setDataAndType(bmpUri,"application/pdf");
intentShareFile.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intentShareFile.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(Intent.createChooser(intentShareFile, "Open File Using..."));
您可以使用不同的方式在 android 中创建文件提供程序。希望这会对你有所帮助。
【讨论】:
【参考方案6】:试试这个 将此代码添加到您的清单文件中
<provider
android:name="androidx.core.content.FileProvider"
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>
提供您的路径类型 path.xml
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external_files" path="."/>
</paths>
并将此代码添加到您的功能中
File file = new File(tempPathNameFileString);
Intent viewPdf = new Intent(Intent.ACTION_VIEW);
viewPdf.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
Uri URI = FileProvider.getUriForFile(ReportsActivity.this, ReportsActivity.this.getApplicationContext().getPackageName() + ".provider", file);
viewPdf.setDataAndType(URI, "application/pdf");
viewPdf.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
ReportsActivity.this.startActivity(viewPdf);
【讨论】:
【参考方案7】:您可以直接使用此代码打开所有类型的文件
Intent sharingIntent = new Intent(Intent.ACTION_VIEW);
Uri screenshotUri = Uri.fromFile(your_file);
sharingIntent.setType("image/png");
sharingIntent.putExtra(Intent.EXTRA_STREAM, screenshotUri);
String type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(MimeTypeMap.getFileExtensionFromUrl(screenshotUri.toString()));
sharingIntent.setDataAndType(screenshotUri, type == null ? "text/plain" : type);
startActivity(Intent.createChooser(sharingIntent, "Share using"));
【讨论】:
添加 Intent.ACTION_VIEW 代替 Intent.ACTION_SEND【参考方案8】:你可以试试这个
File file = new File(filePath);
MimeTypeMap map = MimeTypeMap.getSingleton();
String ext = MimeTypeMap.getFileExtensionFromUrl(file.getName());
String type = map.getMimeTypeFromExtension(ext);
if (type == null)
type = "*/*";
Intent intent = new Intent(Intent.ACTION_VIEW);
Uri data = Uri.fromFile(file);
intent.setDataAndType(data, type);
startActivity(intent);
【讨论】:
【参考方案9】:MimeTypeMap.getSingleton().getExtensionFromMimeType(file.getName());
或许,这是最简单的解决方案。
https://developer.android.com/reference/android/webkit/MimeTypeMap
https://developer.android.com/reference/java/net/URLConnection.html#guessContentTypeFromName(java.lang.String)
private void openFile(File file)
Uri uri = Uri.fromFile(file);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(uri, MimeTypeMap.getSingleton().getExtensionFromMimeType(file.getName()));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(Intent.createChooser(intent, "Open " + file.getName() + " with ..."));
【讨论】:
【参考方案10】:您可以使用 getContentResolver().getType(uri) 获取任何文件 mime 类型:
protected static void openFile(Context context, Uri localUri)
Intent i = new Intent(Intent.ACTION_VIEW);
i.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
i.setDataAndType(localUri, context.getContentResolver().getType(localUri));
context.startActivity(i);
【讨论】:
以上是关于从我的 Android 应用程序以编程方式打开选定的文件(图像、pdf、...)?的主要内容,如果未能解决你的问题,请参考以下文章
如何以编程方式从 Android 的默认应用列表中删除应用?
以编程方式从 Android 的内置图库应用程序中获取/选择图像