1

我需要让我的科尔多瓦包装的 html 显示图片并运行位于外部 SD 根目录之外的视频文件。在cordova-plugin-file的 git hub 上似乎没有地方可以问这些问题。

A)如果文件位于根目录下的这两个子目录中,我不确定我是否理解在下面的 2 B&C 中使用什么路径来完成此操作?

B)如果我只需要访问 ext SD,那么 3 B 中的所有这些值是否都是必需的?

到目前为止,这是我从文档中所知道的......但显然我没有完全正确,因为我得到了错误(见下文)

1)从CMD行设置环境

    cordova create MyApp
    cd /MyApp
    cordova platform add android@latest
    cordova plugin add cordova-plugin-whitelist
    cordova plugin add cordova-plugin-file
    corddova build android (after step 3 below)

2)将这些添加到 index.html

A) cdvfile:索引页面的 Content-Security-Policy 元标记方案,例如:

 <meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap:cdvfile:https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src 

二) <img src="cdvfile:///img/logo.png" />

C) <p><a href="cdvfile://video/MyVideo.mp4">Play video</a></p>

3)将这些添加到 config.xml

一种) <access origin="cdvfile://*" />

二) <preference name="AndroidExtraFilesystems" value="files,files-external,documents,sdcard,cache,cache-external,assets,root" />

单击视频链接时,我在 Android 上遇到的错误是...

 net::ERR_UNKNOWN_URL_SCHEME (cdvfile:video/0001_a1.mp4)

=========== 编辑#1

现在尝试@DaveAlden 的推荐...使用使用[cordova.plugins.diagnostic][2]此配置调用的插件来定位 ExtSD 上的根路径以播放视频但得到错误(见下文)...

配置文件

 <preference name="android-minSdkVersion" value="14" />

 <preference name="android-targetSdkVersion" value="14" />

 <preference name="android-maxSdkVersion" value="25" />
 <plugin name="cordova-plugin-whitelist" spec="1" />

 <plugin name="cordova.plugins.diagnostic" />

索引.html

<body>

<!-- Set up path to ExtSD on Android -->
<script>
function getSdRefAndEmbed(){
    cordova.plugins.diagnostic.getExternalSdCardDetails(function(details){
    details.forEach(function(detail){
        if(detail.type === "root"){
        cordova.file.externalSdCardRoot = detail.filePath;
        embedMedia();
        }
    });
    }, function(error){
    console.error(error);
    });
}

function embedMedia(){
    $('.extSdVideo').each(function(){
        $(this).attr('href', cordova.file.externalSdCardRoot + $(this).attr('href'));
    });
}

$(document).on('deviceready', getSdRefAndEmbed);
$(document).on('pageinit', embedMedia);
</script>

<!-- Play video file -->
<a class="extSdVideo" href="video/0001_a1.mp4" id="0001_a1"> a1 </a>

</body>

应用程序错误

net::ERR_FILE_NOT_FOUND (file:///android_assest/www/HHR/hhr-cm_cameroon-cm1-fra-spa/‌​‌​hhr/hhr-cm_cameroo‌​n-‌​cm1-fra-spa/vide‌​o/00‌​01_a1.mp4

尝试将其0001_a1.mp4放在这两个目录中的任何一个中...

extSDRoot/video/0001_a1.mp4

和/或

extSDRoot/www/HHR/hhr-cm_cameroon-cm1-fra-spa/‌​‌​hhr/hhr-cm_cameroo‌​n-‌​cm1-fra-spa/vide‌​o/00‌​01_a1.mp4

==================== 编辑#2

@DaveAlden 建议尝试这三件事......

1)放在console.dir(details)里面getExternalSdCardDetails()看看插件找到了哪些本机路径。

结果:它在错误消息中给出了相同的路径

Application Error
net::ERR_FILE_NOT_FOUND
(file:///android_asset/www/hhr/cm_cameroon-cm1-fra-spa/0001_a1.mp4) 

2)在同一设备上尝试示例项目( https://github.com/dpa99c/cordova-diagnostic-plugin-example ) 以查看 ext SD 示例是否有效。

结果 1:示例项目的构建失败...

BUILD FAILED Total time: 47.426 secs Error: cmd: Command failed with exit code 1 Error output: F:\DIAGNOSTIC_WORKING\cordova-diagnostic-plugin-example\plat‌​forms\android\build\ intermediates\res\merged\debug\values-v24\values-v24.xml:3: AAPT: Error retrievi ng parent for item: No resource found that matches the given name 'android:TextA ppearance.Material.Widget.Button.Borderless.Colored'.

@DaveAlden 对构建失败的响应...

您的构建环境中缺少/过时的 Android SDK 组件和/或正在使用过时的 cordova-android 平台版本。请参阅文档 ( https://github.com/dpa99c/cordova-diagnostic-plugin#building-for-android ) 和此问题 ( https://github.com/dpa99c/cordova-diagnostic-plugin/issues/161 )。

我的行动:

我通过运行此命令检查了 Android SDK Manager 以查看所需产品的所有 API 级别都处于同一级别

C:> Android -v

Android SDK Tool 25.2.5
SDK platform 25
Android Support Repository 46
Google Play services 39
Google Repository 45

我运行了这个命令...

cordova platform check android

得到这个结果...

F:\DIAGNOSTIC_WORKING\cordova-diagnostic-plugin-example>cordova platform check android
Subproject Path: CordovaLib
android @ 6.1.2; current did not install, and thus its version cannot be determined

为什么我得到这个“当前未安装”?这可能是为什么诊断插件找不到 extSD 的正确路径的问题吗?

我运行了这个命令...

cordova platform rm android && cordova platform add android@latest && cordova build android

现在示例项目的构建成功!

请参阅示例诊断应用程序的屏幕截图,其中显示了 extSD 的路径。当我在我的应用程序中运行诊断插件时,这条路径看起来与我得到的路径非常不同。

在此处输入图像描述

请注意,“写入外部 SD 文件”按钮在按下时没有写入任何内容。我检查了我的文件管理器。

为示例项目提供的路径与诊断插件为我的应用程序提供的路径非常不同(请参阅下面的我的)。这些结果来自同一个 Galaxy S7。

net::ERR_FILE_NOT_FOUND (file:///android_assest/www/HHR/hhr-cm_cameroon-cm1-fra-spa/‌​‌​hhr/hhr-cm_cameroo‌​n-‌​cm1-fra-spa/vide‌​o/00‌​01_a1.mp4

我为我的应用程序运行了这个命令,但没有改变......

cordova platform rm android && cordova platform add android@latest && cordova build android

3) @DaveAlden 建议使用 Chrome 运行调试...接下来我会这样做。

发现这个... 在此处输入图像描述

============= EDIT 3 使用cordova-diagnostic-plugin成功地从extSD播放视频

就是这样...

最后一个障碍是,因为我有一部 Android 6+ 手机,所以我还必须添加一个函数来检查运行时读取 extSD 的权限。代码在编辑#2(见上文)中不断出现错误显示,就像它试图查看内部路径一样。一旦我添加了检查运行时权限的功能,它最终给出了正确的外部路径。提示...仅在清单中提供权限是不够的。你可以在这里读到它。感谢@DaveAlden 您的示例项目!

https://github.com/dpa99c/cordova-diagnostic-plugin-android-runtime-example

Android 运行时权限

Android 6 / API 23 引入了运行时权限的概念。与 >iOS 类似,除了在 Android 清单中列出之外,还必须在运行时请求某些“危险”权限。

运行时权限仅适用于运行应用程序的设备/模拟器具有 >Android 6.0 或更高版本并且应用程序是使用 API 23 或更高版本构建的。对于 Cordova,>这意味着使用 Cordova Android 平台版本 5.0.0 或更高版本。如果 > 应用程序是使用 4.x 或更低版本(API 22 或更低版本)构建的,则运行时权限 >不适用 - 在安装时授予所有权限。

添加到 Config.xml

<access origin="*" />
<plugin name="cordova-plugin-whitelist" version="*" />
<plugin name="cordova.plugins.diagnostic" version="*" />
<plugin name="cordova-plugin-file" version="*" />
<preference name="android-minSdkVersion" value="21" />
<preference name="android-targetSdkVersion" value="23" />


<config-file target="AndroidManifest.xml" parent="/*">
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

感谢@DaveAlden 提供此代码...我只添加了检查运行时读取权限的功能。戴夫,您应该只将这段用于从 extSD 读取媒体文件的代码添加到您的项目示例中,这样您就不必像帮助我一样帮助下一个人了。:)

添加到 Index.html

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Security-Policy" content="default-src * gap://ready file:; style-src 'self' 'unsafe-inline'; img-src * 'self' data:; script-src * 'unsafe-inline' 'unsafe-eval'">
<meta name="format-detection" content="telephone=no">
<meta name="msapplication-tap-highlight" content="no">
<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width">

<script type="text/javascript" src="cordova.js"></script>
<script type="text/javascript" src="js/jquery-2.1.3.min.js"></script>
<script type="text/javascript" src="js/index.js"></script>

<h3>Play video and img file</h3>

<img class="extSdImg" src="img/image1.png"/>
<img class="extSdImg" src="img/image2.png"/>

<p>
<a class="extSdVideo" href="video/video1.mp4">Play video</a>
</p>

<p>
<a class="extSdVideo" href="video/video2.mp4">Play video</a>
</p>
</body>
</html>

添加到 Index.js

function authorizerequestExtSD() {
cordova.plugins.diagnostic.requestExternalStorageAuthorization(function(status){
    console.log("Successfully requested external storage authorization: authorization was " + status);
    checkState();
    getSdRefAndEmbed();
               }, function(error){
     console.error(error);
    });
}

function getSdRefAndEmbed(){
    cordova.plugins.diagnostic.getExternalSdCardDetails(function(details){
    details.forEach(function(detail){
           if(detail.type === "root"){
          cordova.file.externalSdCardRoot = detail.filePath;
          embedMedia();
          }
    });
        }, function(error){
            console.error(error);
    });
}

function embedMedia(){
    $('.extSdImg').each(function(){
           $(this).attr('src', cordova.file.externalSdCardRoot + $(this).attr('src'));
    });
    $('.extSdVideo').each(function(){
            $(this).attr('href', cordova.file.externalSdCardRoot + $(this).attr('href'));
    });
}

$(document).on('deviceready', authorizerequestExtSD);
$(document).on('pageinit', embedMedia);

添加 jQuery 的本地文件副本(在此项目中找到一个https://github.com/dpa99c/cordova-diagnostic-plugin-example):

jquery-2.1.3.min.js 
4

1 回答 1

0

您的方法不起作用:cdvfile://是cordova定义的内部伪协议,其中路径的第一部分定义了内部参考点(cdvfile://localhost/persistent|temporary|another-fs-root*/path/to/file),而2B和2C定义的路径好像相对于外部SD卡根的根.

请注意,cordova-plugin-media对您没有帮助,因为它仅用于播放音频,并且本身不解析文件位置。

如果您的媒体文件位于外部可移动SD 卡上(例如在三星 Galaxy 设备中),cordova-plugin-file则不提供访问此位置的参考。cordova-plugin-file 使用的“外部”引用(例如cordova.file.externalRootDirectory)实际上指向内部内存位置 - /scard/。这是因为并非所有设备都具有可移动的外部 SD 卡(例如 Google Nexus),因此/sdcard保证存在于所有 Android 设备上的“模拟”存储位置也是如此。

如果您希望从外部可移动SD 卡读取文件,可以使用cordova-diagnostic-plugin来获取对外部 SD 卡根目录的有效文件路径引用。请注意,这需要在 JS 中动态完成,而不是在 HTML 中硬编码静态路径:

index.html

<body>
    <img class="extSdImg" src="img/image1.png"/>
    <img class="extSdImg" src="img/image2.png"/>
    <p><a class="extSdVideo" href="video/video1.mp4">Play video</a></p>
    <p><a class="extSdVideo" href="video/video2.mp4">Play video</a></p>
</body>

index.js

function getSdRefAndEmbed(){
    cordova.plugins.diagnostic.getExternalSdCardDetails(function(details){
    details.forEach(function(detail){
        if(detail.type === "root"){
        cordova.file.externalSdCardRoot = detail.filePath;
        embedMedia();
        }
    });
    }, function(error){
    console.error(error);
    });
}

function embedMedia(){
    $('.extSdImg').each(function(){
        $(this).attr('src', cordova.file.externalSdCardRoot + $(this).attr('src'));
    });
    $('.extSdVideo').each(function(){
        $(this).attr('href', cordova.file.externalSdCardRoot + $(this).attr('href'));
    });
}

$(document).on('deviceready', getSdRefAndEmbed);
$(document).on('pageinit', embedMedia);
于 2017-03-03T09:17:54.110 回答