使用默认应用程序的Xamarin Android Open文件在Android 7或更高版本中不起作用 [英] Xamarin Android Open file using default app not work in Android 7 or above

查看:117
本文介绍了使用默认应用程序的Xamarin Android Open文件在Android 7或更高版本中不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要使用Android手机中的默认应用打开文档或图像.因此我实现了以下代码,效果很好,但仅在Android 7或更高版本上不起作用.请让我知道问题出在哪里以及如何解决.

I need to open documents or images using default app in android phone. so I implemented following codes and it works good but not work only on Android 7 or above. Please let me know what is wrong and how to fix.

var documentsPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
var filePath = Path.Combine(documentsPath, fileName);

var bytes = File.ReadAllBytes(filePath);

//Copy the private file's data to the EXTERNAL PUBLIC location
string externalStorageState = global::Android.OS.Environment.ExternalStorageState;
var externalPath = global::Android.OS.Environment.ExternalStorageDirectory.Path + "/" + global::Android.OS.Environment.DirectoryDownloads + "/" + fileName;
File.WriteAllBytes(externalPath, bytes);

Java.IO.File file = new Java.IO.File(externalPath);
file.SetReadable(true);

string application = "";
string extension = Path.GetExtension(filePath);

// get mimeTye
switch (extension.ToLower())
{
    case ".txt":
    application = "text/plain";
    break;
    case ".doc":
    case ".docx":
    application = "application/msword";
    break;
    case ".pdf":
    application = "application/pdf";
    break;
    case ".xls":
    case ".xlsx":
    application = "application/vnd.ms-excel";
    break;
    case ".jpg":
    case ".jpeg":
    case ".png":
    application = "image/jpeg";
    break;
    default:
    application = "*/*";
    break;
}

Intent intent = new Intent(Intent.ActionView);
Android.Net.Uri uri = Android.Net.Uri.FromFile(file);
Context context = MainActivity.instance;

if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.N)
{
    uri = FileProvider.GetUriForFile(context, context.PackageName + ".fileprovider", file);
    intent.SetDataAndType(uri, application);
    intent.SetFlags(ActivityFlags.GrantReadUriPermission);
    intent.AddFlags(ActivityFlags.NoHistory);
}
else
{
    intent.SetDataAndType(uri, application);
    intent.SetFlags(ActivityFlags.ClearWhenTaskReset | ActivityFlags.NewTask);
}

context.StartActivity(intent);

最初,我不是对应于此功能的android版本,但是在阅读了 this ,我添加了它.

Originally I wasn't corresponding the android version for this functionality but after I read some questions like this, I added it.

这是我的清单

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1" package="com.ibase.mtwpublicapp">
    <uses-sdk android:minSdkVersion="15" android:targetSdkVersion="26" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <application android:label="OKS" android:largeHeap="true">
        <provider android:name="android.support.v4.content.FileProvider" android:authorities="com.oks.mobileapp.fileprovider" android:exported="false" android:grantUriPermissions="true">
            <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths"></meta-data>
        </provider>
        <meta-data android:name="com.facebook.sdk.ApplicationId" android:value="@string/facebook_app_id" />
    </application>
</manifest>

当我测试该应用程序时,它在此行中显示一个异常.

When I test the app, it shows an exception in this line.

uri = FileProvider.GetUriForFile(context, context.PackageName + ".fileprovider", file);

这是异常消息.

 {Java.Lang.IllegalArgumentException: Failed to find configured root that contains /storage/emulated/0/Download/237309880.doc
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in <657aa8fea4454dc898a9e5f379c58734>:0 
  at Java.Interop.JniEnvironment+StaticMethods.CallStaticObjectMethod (Java.Interop.JniObjectReference type, Java.Interop.JniMethodInfo method, Java.Interop.JniArgumentValue* args) [0x00069] in <54816278eed9488eb28d3597fecd78f8>:0 
  at Android.Runtime.JNIEnv.CallStaticObjectMethod (System.IntPtr jclass, System.IntPtr jmethod, Android.Runtime.JValue* parms) [0x00000] in /Users/builder/data/lanes/5749/d8c6e504/source/xamarin-android/src/Mono.Android/Android.Runtime/JNIEnv.g.cs:562 
  at Android.Support.V4.Content.FileProvider.GetUriForFile (Android.Content.Context context, System.String authority, Java.IO.File file) [0x00077] in <e43264129f744fc09346a273ec4f6c48>:0 
  at FileManagement.Helpers.FileHelper.OpenFileByName (System.String fileName) [0x0022a] in FileManagement/Helpers/FileHelper.cs:141 
  --- End of managed Java.Lang.IllegalArgumentException stack trace ---
java.lang.IllegalArgumentException: Failed to find configured root that contains /storage/emulated/0/Download/237309880.doc
    at android.support.v4.content.FileProvider$SimplePathStrategy.getUriForFile(FileProvider.java:712)
    at android.support.v4.content.FileProvider.getUriForFile(FileProvider.java:401)
    at android.support.v7.app.AlertDialog_IDialogInterfaceOnClickListenerImplementor.n_onClick(Native Method)
    at android.support.v7.app.AlertDialog_IDialogInterfaceOnClickListenerImplementor.onClick(AlertDialog_IDialogInterfaceOnClickListenerImplementor.java:30)
    at android.support.v7.app.AlertController$ButtonHandler.handleMessage(AlertController.java:162)
    at android.os.Handler.dispatchMessage(Handler.java:102)
    at android.os.Looper.loop(Looper.java:154)
    at android.app.ActivityThread.main(ActivityThread.java:6776)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1518)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1408)
}

这是file_paths.xml

Here is the file_paths.xml

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-files-path name="my_images" path="Pictures" />
    <external-files-path name="my_movies" path="Movies" />
</paths>

我认为它可能与清单中声明的​​FileProvider有关.

I think it may be related to the FileProvider that I declare in manifest.

感谢您的帮助!

推荐答案

经过一番讨论,我从@CommonsWare得到了答案.

I got the answer from @CommonsWare after having some discussion.

它需要在file_path.xml中添加一行

It needs to add one line to file_path.xml

<external-path name="my_downloads" path="Download" />

这是完整的xml.

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="my_downloads" path="Download" />
    <external-files-path name="my_images" path="Pictures" />
    <external-files-path name="my_movies" path="Movies" />
</paths>

这篇关于使用默认应用程序的Xamarin Android Open文件在Android 7或更高版本中不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆