我的应用程序具有浏览手机和SD卡上的文件并使用其他应用程序打开文件的功能。我想要一个解决方案,我不必指定MimeType,可以使用任何类型的文件。
这是我的代码:
Intent myIntent = new Intent(Intent.ACTION_VIEW);
myIntent.setData(Uri.fromFile(item));
startActivity(myIntent);
但是,我收到以下错误:
android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.PICK dat=file:///sdcard/dropbox/test.pdf }
答案 0 :(得分:111)
这应检测mimetype并使用默认值打开:
MimeTypeMap myMime = MimeTypeMap.getSingleton();
Intent newIntent = new Intent(Intent.ACTION_VIEW);
String mimeType = myMime.getMimeTypeFromExtension(fileExt(getFile()).substring(1));
newIntent.setDataAndType(Uri.fromFile(getFile()),mimeType);
newIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
try {
context.startActivity(newIntent);
} catch (ActivityNotFoundException e) {
Toast.makeText(context, "No handler for this type of file.", Toast.LENGTH_LONG).show();
}
使用此功能:
private String fileExt(String url) {
if (url.indexOf("?") > -1) {
url = url.substring(0, url.indexOf("?"));
}
if (url.lastIndexOf(".") == -1) {
return null;
} else {
String ext = url.substring(url.lastIndexOf(".") + 1);
if (ext.indexOf("%") > -1) {
ext = ext.substring(0, ext.indexOf("%"));
}
if (ext.indexOf("/") > -1) {
ext = ext.substring(0, ext.indexOf("/"));
}
return ext.toLowerCase();
}
}
答案 1 :(得分:11)
createChooser应该做的诀窍:
Intent myIntent = new Intent(Intent.ACTION_VIEW);
myIntent.setData(Uri.fromFile(item));
Intent j = Intent.createChooser(myIntent, "Choose an application to open with:");
startActivity(j);
答案 2 :(得分:7)
Intent myIntent = new Intent(Intent.ACTION_VIEW);
String mime=URLConnection.guessContentTypeFromStream(new FileInputStream(item));
if(mime==null) mime=URLConnection.guessContentTypeFromName(item.getName());
myIntent.setDataAndType(Uri.fromFile(item), mime);
startActivity(myIntent);
首先我尝试用文件内容猜测,但是我发现它总是返回null。
答案 3 :(得分:5)
Android不会根据文件扩展名启动活动,除非有应用程序为其指定特定的意图过滤器。你需要mime类型到Intent
告诉android足够的信息才能启动正确的Activity
。
您可以选择使用MimeTypeMap类自动执行此任务。检查方法String getMimeTypeFromExtension(String extension)
。
顺便说一下,您的设备中是否安装了PDF阅读器?
你也应该处理这个异常,可能是通过显示一个漂亮的弹出窗口,说明该特定类型的文件没有应用程序。
答案 4 :(得分:5)
尝试这个几乎涵盖所有文件扩展名
public void openFile(File url) {
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") || url.toString().contains(".rar")) {
// WAV audio file
intent.setDataAndType(uri, "application/x-wav");
} 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 {
//if you want you can also define the intent type for any other file
//additionally use else clause below, to manage other unknown extensions
//in this case, Android will show all applications installed on the device
//so you can choose which application to use
intent.setDataAndType(uri, "*/*");
}
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
答案 5 :(得分:4)
您可以找到文件的mime类型,并自己打算打开文件。
使用以下代码打开任何文件......
File temp_file=new File("YOUR FILE PATH");
Intent intent = new Intent();
intent.setAction(android.content.Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(temp_file),getMimeType(temp_file.getAbsolutePath()));
startActivity(intent);
其中getMimeType()是....(此方法将返回所需的mime类型,如果文件没有任何正确的mime类型,则返回null)...
private String getMimeType(String url)
{
String parts[]=url.split("\\.");
String extension=parts[parts.length-1];
String type = null;
if (extension != null) {
MimeTypeMap mime = MimeTypeMap.getSingleton();
type = mime.getMimeTypeFromExtension(extension);
}
return type;
}
答案 6 :(得分:2)
简单共享文件(“multipart /”)
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file));
intent.setType("multipart/");
startActivity(intent);
答案 7 :(得分:2)
这肯定会有效..
private void showFile(File file, String filetype)
{
MimeTypeMap myMime = MimeTypeMap.getSingleton();
Intent intent = new Intent(Intent.ACTION_VIEW);
String mimeType =
myMime.getMimeTypeFromExtension(filetype);
if(android.os.Build.VERSION.SDK_INT >=24) {
Uri fileURI = FileProvider.getUriForFile(getContext(),
BuildConfig.APPLICATION_ID + ".provider",
file);
intent.setDataAndType(fileURI, mimeType);
}else {
intent.setDataAndType(Uri.fromFile(file), mimeType);
}
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_GRANT_READ_URI_PERMISSION);
try {
context.startActivity(intent);
}catch (ActivityNotFoundException e){
Toast.makeText(context, "No Application found to open this type of file.", Toast.LENGTH_LONG).show();
}
}
答案 8 :(得分:0)
NoBugs的答案存在问题。这直接来自eclipse功能信息窗口:
String android.webkit.MimeTypeMap.getMimeTypeFromExtension(String 扩展)
public String getMimeTypeFromExtension(String extension)
自:API Level 1
返回给定扩展名的MIME类型。
参数
扩展名没有前导'。'的文件扩展名
返回给定扩展名的MIME类型,如果没有,则返回null。
答案 9 :(得分:0)
使用此方法从文件的URI中获取MIME类型:
public static String getMimeType(String url) {
String type = null;
String extension = url.substring(url.lastIndexOf(".") + 1);
if (extension != null) {
type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
}
return type;
}
答案 10 :(得分:0)
您应该始终使用
检查相同内容PackageManager packageManager = getActivity().getPackageManager();
if (intent.resolveActivity(packageManager) != null) {
startActivity(intent);
} else {
Log.d(TAG, "No Intent available to handle action");
}
要获取文件的MimeTpye,您可以使用: -
public String getMimeType(Uri uri, Context context) {
String mimeType = null;
if (uri.getScheme().equals(ContentResolver.SCHEME_CONTENT)) {
ContentResolver cr = context.getContentResolver();
mimeType = cr.getType(uri);
} else {
String fileExtension = MimeTypeMap.getFileExtensionFromUrl(uri
.toString());
mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(
fileExtension.toLowerCase());
}
return mimeType;
}
答案 11 :(得分:0)
我用Kotlin编写了这几行,它的工作就像一种魅力。享受它。
val file = File(path)
val mimeType = URLConnection.guessContentTypeFromName(file.absolutePath)
Intent().apply {
setDataAndType(Uri.fromFile(file), mimeType)
flags = Intent.FLAG_ACTIVITY_NEW_TASK
}.let {
try {
itemView.context.startActivity(it)
} catch (e: ActivityNotFoundException) {
Toast.makeText(itemView.context, "There's no program to open this file", Toast.LENGTH_LONG).show()
}
}
答案 12 :(得分:0)
您必须使用 MimeTypeMap 并使用文件扩展名获取类型。然后将其传递给意图以打开任何类型的文件。
科特林
fun getIntentForFile(filePath: String, context: Context): Intent {
val intent = Intent()
val uri = FileProvider.getUriForFile(
context,
context.applicationContext.packageName + ".fileprovider",
File(filePath)
)
intent.action = Intent.ACTION_VIEW
intent.putExtra(Intent.EXTRA_STREAM, uri)
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
intent.setDataAndType(uri, getFileContentType(filePath))
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
return intent
}
fun getFileContentType(filePath: String): String? {
val file = File(filePath)
val map = MimeTypeMap.getSingleton()
val ext = MimeTypeMap.getFileExtensionFromUrl(file.name)
var type = map.getMimeTypeFromExtension(ext)
if (type == null) type = "*/*"
return type
}