Cordova:Android 上的 sdcard 访问不起作用

Posted

技术标签:

【中文标题】Cordova:Android 上的 sdcard 访问不起作用【英文标题】:Cordova: sdcard access on Android does not work 【发布时间】:2017-09-06 01:50:42 【问题描述】:

我目前正在尝试一个科尔多瓦测试项目,该项目包含下载文件以在音乐播放器上播放。基本上,应用程序应该从我的服务器下载一个 .mp3 文件并将其保存在应用程序存储或用户定义的路径(文件夹选择)中。 截至目前,我已成功下载文件,我可以选择自定义路径并在文件资源管理器应用程序中播放音乐文件,但不知何故,它们没有出现在音乐播放器应用程序或其他地方。此外,即使我在配置文件中定义了外部访问,我也无法将文件写入 sdcard。 我当前访问文件系统的代码如下所示:

app.log('Filesystem', 'Requesting filesystem...');
		if (device.platform.toLowerCase() == "android") 
			app.log('Filesystem', 'Detected android device...');
			if(window.saveInMusic && window.musicPath)
				app.log('Filesystem', 'Selected storage persistent SD');
				window.resolveLocalFileSystemURL(window.musicPath, app.gotFS, app.fsFail);
			 else 
				app.log('Filesystem', 'Selected storage persistent Internal');
				window.resolveLocalFileSystemURL(cordova.file.externalRootDirectory, app.gotFS, app.fsFail);
			
		 else 
			app.log('Filesystem', 'No device detected...');
			app.log('Filesystem', 'Selected storage DEFAULT (sandbox)');
			window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, app.gotFS, app.fsFail);
		

不知何故,所有的 cordova.file.external* 目录都是空的(就像插件 md 文件中提到的那样)并且 externalRootDirectory 正在返回“storage/emulated/0/appdir”(应该返回 sdcard 路径)。我检查了 config.xml 和 AndroidManifest.xml 中的权限,如下所示:

<?xml version='1.0' encoding='utf-8'?>
<widget id="com.someorg.appname" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
    <name>AppName</name>
    <description>
        A basic Framework7 template for PhoneGap.
    </description>
    <author email="dev@cordova.apache.org" href="http://cordova.io">
        Apache Cordova Team
    </author>
    <content src="index.html" />
    <access origin="*" />
    <allow-intent href="http://*/*" />
    <allow-intent href="https://*/*" />
    <allow-intent href="tel:*" />
    <allow-intent href="sms:*" />
    <allow-intent href="mailto:*" />
    <allow-intent href="geo:*" />
    <platform name="android">
        <preference name="android-minSdkVersion" value="14" />
		<preference name="AndroidPersistentFileLocation" value="Compatibility" />
		<preference name="AndroidExtraFilesystems" value="sdcard,cache" />
        <allow-intent href="market:*" />
    </platform>
    <platform name="ios">
        <allow-intent href="itms:*" />
        <allow-intent href="itms-apps:*" />
        <preference name="BackupWebStorage" value="none" />
    </platform>
    <preference name="DisallowOverscroll" value="true" />
    <plugin name="cordova-plugin-whitelist" spec="~1.2.0" />
    <plugin name="cordova-plugin-console" spec="~1.0.1" />
    <plugin name="cordova-plugin-statusbar" spec="~1.0.1" />
	<plugin name="cordova-plugin-compat" spec="~1.1.0" />
	<plugin name="cordova-plugin-device" spec="~1.1.5" />
	<plugin name="cordova-plugin-file" spec="~4.3.2" />
	<plugin name="cordova-plugin-file-transfer" spec="~1.6.2" />
	<plugin spec="https://github.com/ourcodeworld/cordova-ourcodeworld-filebrowser.git#96a57ef" source="git" />
</widget>

<?xml version='1.0' encoding='utf-8'?>
<manifest android:hardwareAccelerated="true" android:versionCode="10000" android:versionName="1.0.0" package="com.someorg.appname" xmlns:android="http://schemas.android.com/apk/res/android">
    <supports-screens android:anyDensity="true" android:largeScreens="true" android:normalScreens="true" android:resizeable="true" android:smallScreens="true" android:xlargeScreens="true" />
    <uses-permission android:name="android.permission.INTERNET" />
    <application android:hardwareAccelerated="true" android:icon="@mipmap/icon" android:label="@string/app_name" android:supportsRtl="true">
        <activity android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale" android:label="@string/activity_name" android:launchMode="singleTop" android:name="MainActivity" android:theme="@android:style/Theme.DeviceDefault.NoActionBar" android:windowSoftInputMode="adjustResize">
            <intent-filter android:label="@string/launcher_name">
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:label="Our Code World filepicker" android:name="com.ourcodeworld.plugins.filebrowser.DialogShowPicker">
            <intent-filter>
                <action android:name="com.ourcodeworld.plugins.filebrowser.DialogShowPicker" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
        <activity android:label="Filepicker" android:name="com.nononsenseapps.filepicker.FilePickerActivity" android:theme="@style/FilePickerTheme">
            <intent-filter>
                <action android:name="android.intent.action.GET_CONTENT" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
    </application>
    <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="25" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
</manifest>
该应用程序实际上是在安装时要求这些权限。 我还实施了一种解决方法(文件夹选择器)来手动选择 sdcard 路径。可悲的是,当我尝试我的 getDirectory 函数时它失败了。

gotFS: function(fileSystem)
		window.fileSystem = fileSystem;
		app.log('Filesystem', 'Filesystem got!');
		var entry = "";
		if (device.platform.toLowerCase() == "android") 
			entry = fileSystem;
		 else 
			entry = fileSystem.root;
		
		app.log('Filesystem', 'Setting up directory...');
		entry.getDirectory(window.appRootDirName, 
			create: true,
			exclusive: false
		, app.dirReady, app.fsFail);
	,

我已经搜索了许多 *** 页面和文档,但我没有提出任何解决方案。我已经安装了最新的 cordova 6.5 并将所有插件更新到最新的稳定版本。我很乐意提供任何建议。

更新:更清楚地说,应用程序的用户应该能够按照他的习惯使用下载的媒体文件,而不是通过应用程序管理和打开它们。

【问题讨论】:

【参考方案1】:

看看here。插件cordova-plugin-file-opener2解决了这个问题!

【讨论】:

我不确定这是如何解决问题的。问题是下载的文件不能被其他应用程序识别,比如音乐播放器,就像沙盒一样。我已经读到我必须使用 resolveLocalFileSystemURL 而不是 resolveFileSystem 来获取永久位置而不是模拟位置,但这也不起作用。 @user285814 opener2 将模拟位置转换为永久位置,在我的情况下,系统正确打开了PDF'sMP3。你所要做的就是传递你想要的MIME TYPE 我已经在我的应用程序中实现了插件并对其进行了评估。这个插件只是打开文件。这不是我的问题。问题是其他应用程序不会访问文件。例如,下载的 mp3 文件不会显示在音乐播放器应用程序(股票 android)中。我还重新启动了设备以验证媒体库是否已更新。遗憾的是,文件不会像上面所说的那样显示出来。 好的!对不起我的解释错误。那么,您保存文件的目录是私有的吗?在这里 (cordova.apache.org/docs/en/6.x/reference/cordova-plugin-file/…) 我们知道哪个目录是私有的还是没有的。

以上是关于Cordova:Android 上的 sdcard 访问不起作用的主要内容,如果未能解决你的问题,请参考以下文章

android-get nullpointerexception 尝试访问外部存储(sdcard)上的视频

如何在 Android 上的 SDCard 上打开 HTML 文件

如何使用 Android 应用程序重命名 sdcard 上的文件?

Android读取sdcard卡上的全部图片而且显示,读取的过程有进度条显示

卸载 android 应用程序会删除存储在 sdcard 上的数据库吗?

在android中使用http比较服务器上文件的大小和sdcard上的文件大小