【问题标题】:Open a selected file (image, pdf, ...) programmatically from my Android Application?从我的 Android 应用程序以编程方式打开选定的文件(图像、pdf、...)?
【发布时间】:2013-10-25 16:03:10
【问题描述】:

我正在开发一个应该能够从特定文件夹打开选定文件的 Android 应用程序。

我已经尝试过了,但是在选择了我要打开的应用程序后,我收到了这条消息:

无法加载

在尝试了很多thread 1thread 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);

我该如何解决这个问题?

【问题讨论】:

标签: android image pdf android-intent


【解决方案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&#8221;
xmlns:tools=”http://schemas.android.com/tools&#8221;
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&#8221;
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);
                  }
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2010-11-28
                • 2015-12-08
                • 1970-01-01
                • 1970-01-01
                • 2011-01-11
                相关资源
                最近更新 更多