cordova-plugin-file播放来自extSD

时间:2017-03-03 06:38:40

标签: android html cordova video cordova-plugin-file

我需要让我的cordova包装html显示图片并运行一个位于外部SD根目录下的视频文件。似乎没有地方可以在cordova-plugin-file的git中心提出这些问题。

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 

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

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

3)将这些添加到config.xml

A)<access origin="cdvfile://*" />

B)<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上的根路径以播放视频但是得到错误(见下文)......

config.xml中

 <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" />

的index.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)在同一台设备上尝试example projecthttps://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

为什么我得到这个&#34;当前没有安装&#34;?这可能是诊断插件找不到extSD的正确路径的原因吗?

我跑了这个命令......

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

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

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

enter image description here

注意按钮&#34;写入外部SD文件&#34;按下时没有写任何东西。我查看了我的文件管理器。

示例项目的路径与诊断插件为我的应用程序提供的路径非常不同(请参阅下面的内容)。这些结果来自同一个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运行调试......我接下来会这样做。

发现这个...... enter image description here

============= 编辑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引入了运行时权限的概念。类似于&gt; iOS,某些&#34;危险&#34;此外,必须在运行时请求权限&gt;才能在Android清单中列出。

     

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

添加到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 

1 个答案:

答案 0 :(得分: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);