Более недели я боролся с этой задачей для работы и надеялся, что другие точки зрения помогут мне преодолеть эту проблему. Моя цель здесь — преодолеть ужасную ошибку FileTransfer: 3 и успешно загрузить файл.
Мне было поручено создать простое приложение для Android, которое записывает аудио и загружает его по указанному адресу. Я использую Windows 10, Visual Studio 2015 с Cordova Tools 2 и тестирую Genymotion (эмулятор Android) и WAMPServer (PHP-сервер для получения загруженного файла).
Все зависимости Cordova установлены правильно. Genymotion протестирован и полностью функционален. Мой проект строится правильно.
Вот мой код:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Recording App</title>
<!-- CordovaTest references -->
<link href="css/index.css" rel="stylesheet" />
<script type="text/javascript" charset="utf-8">
// Wait for Cordova to load
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
}
// A button will call this function
function captureAudio() {
// Launch device audio recording application,
// allowing user to capture up to 1 audio clips simulataneously.
navigator.device.capture.captureAudio(captureSuccess, captureError, { limit: 1 });
}
// Uploads files to server
function uploadFile(mediaFile)
{
var options = new FileUploadOptions();
var ft = new FileTransfer();
var fileURI = mediaFile.fullPath;
var serverUri = encodeURI("http://192.168.0.110/uploadRecording.php");
options.fileName = fileURI.substr(fileURI.lastIndexOf('/') + 1);
// Suggested fix for failure to resolve path.
options.chunkedMode = false;
options.headers = {Connection: "close"};
showAlert(mediaFile.fullPath);
//showAlert(options.fileName);
//showAlert(serverUri);
checkConnection();
ft.upload(
fileURI,
serverUri,
function (result) {
showAlert("Recording uploaded to " + serverUri);
console.log('Upload success: ' + result.responseCode);
console.log(result.bytesSent + ' bytes sent');
},
function (error) {
showAlert("Could not resolve " + serverUri + ': ' + error.code);
console.log('Error uploading file ' + path + ': ' + error.code);
},
options,
true);
}
function checkConnection() {
var networkState = navigator.connection.type;
var states = {};
states[Connection.UNKNOWN] = 'Unknown connection';
states[Connection.ETHERNET] = 'Ethernet connection';
states[Connection.WIFI] = 'WiFi connection';
states[Connection.CELL_2G] = 'Cell 2G connection';
states[Connection.CELL_3G] = 'Cell 3G connection';
states[Connection.CELL_4G] = 'Cell 4G connection';
states[Connection.CELL] = 'Cell generic connection';
states[Connection.NONE] = 'No network connection';
alert('Connection type: ' + states[networkState]);
}
// alert dialog dismissed
function alertDismissed() {
// do something
}
// Show a custom alertDismissed
//
function showAlert(message) {
navigator.notification.alert(
message, // message
alertDismissed, // callback
'Alert', // title
'Ok' // buttonName
);
}
// Called when capture operation is finished
function captureSuccess(mediaFiles) {
var i, len;
for (i = 0, len = mediaFiles.length; i < len; i += 1) {
uploadFile(mediaFiles[i]);
}
}
// Called if something bad happens.
function captureError(error) {
alert('code: ' + error.code + '\n' +
'message: ' + error.message + '\n');
}
</script>
</head>
<body>
<p>Audio Capture Application</p>
<a href="#" class="btn large" onclick="captureAudio();">Record Audio</a>
<!-- Cordova reference, this is added to your app when it's built. -->
<script src="cordova.js"></script>
<script src="scripts/platformOverrides.js"></script>
<script src="scripts/index.js"></script>
</body>
</html>
<?xml version="1.0" encoding="utf-8"?>
<widget xmlns:cdv="http://cordova.apache.org/ns/1.0" xmlns:vs="http://schemas.microsoft.com/appx/2014/htmlapps" id="io.cordova.myapp9612dd" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" defaultlocale="en-US">
<name>RecorderApp</name>
<description>A blank project that uses Apache Cordova to help you build an app that targets multiple mobile platforms: Android, iOS, Windows, and Windows Phone.</description>
<author href="http://cordova.io" email="[email protected]">Apache Cordova Team </author>
<content src="index.html" />
<access origin="192.168.0.110" subdomains="true" />
<vs:features />
<preference name="SplashScreen" value="screen" />
<preference name="windows-target-version" value="8.1" />
<!-- Support for Cordova 5.0.0 plugin system -->
<plugin name="cordova-plugin-whitelist" version="1" />
<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">
<allow-intent href="market:*" />
</platform>
<platform name="ios">
<allow-intent href="itms:*" />
<allow-intent href="itms-apps:*" />
</platform>
<platform name="android">
<icon src="res/icons/android/icon-36-ldpi.png" density="ldpi" />
<icon src="res/icons/android/icon-48-mdpi.png" density="mdpi" />
<icon src="res/icons/android/icon-72-hdpi.png" density="hdpi" />
<icon src="res/icons/android/icon-96-xhdpi.png" density="xhdpi" />
</platform>
<platform name="ios">
<!-- iOS 8.0+ -->
<!-- iPhone 6 Plus -->
<icon src="res/icons/ios/icon-60-3x.png" width="180" height="180" />
<!-- iOS 7.0+ -->
<!-- iPhone / iPod Touch -->
<icon src="res/icons/ios/icon-60.png" width="60" height="60" />
<icon src="res/icons/ios/icon-60-2x.png" width="120" height="120" />
<!-- iPad -->
<icon src="res/icons/ios/icon-76.png" width="76" height="76" />
<icon src="res/icons/ios/icon-76-2x.png" width="152" height="152" />
<!-- iOS 6.1 -->
<!-- Spotlight Icon -->
<icon src="res/icons/ios/icon-40.png" width="40" height="40" />
<icon src="res/icons/ios/icon-40-2x.png" width="80" height="80" />
<!-- iPhone / iPod Touch -->
<icon src="res/icons/ios/icon-57.png" width="57" height="57" />
<icon src="res/icons/ios/icon-57-2x.png" width="114" height="114" />
<!-- iPad -->
<icon src="res/icons/ios/icon-72.png" width="72" height="72" />
<icon src="res/icons/ios/icon-72-2x.png" width="144" height="144" />
<!-- iPhone Spotlight and Settings Icon -->
<icon src="res/icons/ios/icon-small.png" width="29" height="29" />
<icon src="res/icons/ios/icon-small-2x.png" width="58" height="58" />
<!-- iPad Spotlight and Settings Icon -->
<icon src="res/icons/ios/icon-50.png" width="50" height="50" />
<icon src="res/icons/ios/icon-50-2x.png" width="100" height="100" />
</platform>
<platform name="windows">
<icon src="res/icons/windows/Square150x150Logo.scale-100.png" width="150" height="150" />
<icon src="res/icons/windows/Square150x150Logo.scale-240.png" width="360" height="360" />
<icon src="res/icons/windows/Square30x30Logo.scale-100.png" width="30" height="30" />
<icon src="res/icons/windows/Square310x310Logo.scale-100.png" width="310" height="310" />
<icon src="res/icons/windows/Square44x44Logo.scale-240.png" width="106" height="106" />
<icon src="res/icons/windows/Square70x70Logo.scale-100.png" width="70" height="70" />
<icon src="res/icons/windows/Square71x71Logo.scale-240.png" width="170" height="170" />
<icon src="res/icons/windows/StoreLogo.scale-100.png" width="50" height="50" />
<icon src="res/icons/windows/StoreLogo.scale-240.png" width="120" height="120" />
<icon src="res/icons/windows/Wide310x150Logo.scale-100.png" width="310" height="150" />
<icon src="res/icons/windows/Wide310x150Logo.scale-240.png" width="744" height="360" />
</platform>
<platform name="wp8">
<icon src="res/icons/wp8/ApplicationIcon.png" width="62" height="62" />
<icon src="res/icons/wp8/Background.png" width="173" height="173" />
</platform>
<platform name="android">
<splash src="res/screens/android/screen-hdpi-landscape.png" density="land-hdpi" />
<splash src="res/screens/android/screen-ldpi-landscape.png" density="land-ldpi" />
<splash src="res/screens/android/screen-mdpi-landscape.png" density="land-mdpi" />
<splash src="res/screens/android/screen-xhdpi-landscape.png" density="land-xhdpi" />
<splash src="res/screens/android/screen-hdpi-portrait.png" density="port-hdpi" />
<splash src="res/screens/android/screen-ldpi-portrait.png" density="port-ldpi" />
<splash src="res/screens/android/screen-mdpi-portrait.png" density="port-mdpi" />
<splash src="res/screens/android/screen-xhdpi-portrait.png" density="port-xhdpi" />
</platform>
<platform name="ios">
<splash src="res/screens/ios/screen-iphone-portrait.png" width="320" height="480" />
<splash src="res/screens/ios/screen-iphone-portrait-2x.png" width="640" height="960" />
<splash src="res/screens/ios/screen-ipad-portrait.png" width="768" height="1024" />
<splash src="res/screens/ios/screen-ipad-portrait-2x.png" width="1536" height="2048" />
<splash src="res/screens/ios/screen-ipad-landscape.png" width="1024" height="768" />
<splash src="res/screens/ios/screen-ipad-landscape-2x.png" width="2048" height="1536" />
<splash src="res/screens/ios/screen-iphone-568h-2x.png" width="640" height="1136" />
<splash src="res/screens/ios/screen-iphone-portrait-667h.png" width="750" height="1334" />
<splash src="res/screens/ios/screen-iphone-portrait-736h.png" width="1242" height="2208" />
<splash src="res/screens/ios/screen-iphone-landscape-736h.png" width="2208" height="1242" />
</platform>
<platform name="windows">
<splash src="res/screens/windows/SplashScreen.scale-100.png" width="620" height="300" />
<splash src="res/screens/windows/SplashScreen.scale-240.png" width="1152" height="1920" />
<splash src="res/screens/windows/SplashScreenPhone.scale-240.png" width="1152" height="1920" />
</platform>
<platform name="wp8">
<splash src="res/screens/wp8/SplashScreenImage.jpg" width="480" height="800" />
</platform>
<vs:plugin name="cordova-plugin-media-capture" version="1.0.1" />
<preference name="KeepRunning" value="False" />
<preference name="ShowTitle" value="True" />
<preference name="InAppBrowserStorageEnabled" value="False" />
<preference name="SuppressesIncrementalRendering" value="True" />
<vs:plugin name="cordova-plugin-dialogs" version="1.1.1" />
<vs:plugin name="cordova-plugin-network-information" version="1.0.1" />
<vs:plugin name="cordova-plugin-file-transfer" version="1.3.0" />
<vs:plugin name="cordova-plugin-file" version="3.0.0" />
</widget>
<?php
# Receiver for uploaded audio recordings
echo "I'm here";
#if(isset($_POST["submit"]))
#{
$targetDir = "uploads";
$targetFile = $targetDir . "/" . basename($_FILES["fileToUpload"]["name"]);
createOutputDir($targetDir);
echo "uploads/" . basename($_FILES["fileToUpload"]["name"]);
if(isValid($targetFile) == true)
{
uploadFile($targetFile);
}
#}
#
function uploadFile($targetFile)
{
if (move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file))
{
echo "The file ". basename( $_FILES["fileToUpload"]["name"]). " has been uploaded.";
}
else
{
echo "Sorry, there was an error uploading your file.";
}
}
#
function createOutputDir($targetDir)
{
if(!file_exists($targetDir))
{
if(!mkdir($targetDir)) {
die("failed to create save folder $targetDir");
}
}
}
#
function isValid($targetFile)
{
if (file_exists($targetFile))
{
echo "This file has already been submitted.";
return false;
}
if (! isValidExt($targetFile)) {
return false;
}
# If we made it this far...
return true;
}
#
function isValidExt($targetFile)
{
# Android recording formats
# High quality recording = m4a (Windows Phone / Android / Apple)
# Normal quality recording = amr (Android)
$allowedFileTypes = ["m4a", "amr"];
# Restrict file formats
$uploadFileType = pathinfo($targetFile, PATHINFO_EXTENSION);
if(in_array($uploadFileType, $allowedFileTypes) == false)
{
echo "This service is for audio recordings only.";
return false;
}
return true;
}
?>
И вот что я уже пытался решить эту проблему (благодаря StackOverflow и другим):
Любая помощь будет принята с благодарностью. Заранее спасибо, что нашли время, чтобы прочитать все это.
Задача ещё не решена.
Других решений пока нет …