Problem description
Customer wants to upload a file thru a webservice. When we test this code in iOS, works like a charm. When trying to upload with Android, it fails. (same webservice, user, etc).
Actual Results
The file can't be uploaded when running the program from Android
Expected results
The app being able to upload files to the webservice
Test case
1. Create a new mobile project
2. Paste the code
3. Run it
4. Press "Click" button
5. See the logs
var win = Titanium.UI.createWindow({
backgroundColor : '#FFFFFF',
exitOnClose : true,
navBarHidden : true
});
var imageView = Titanium.UI.createImageView({
image : 'KS_nav_ui.png',
height : '46dp',
width : '43dp',
top:'10dp'
});
win.add(imageView);
var button = Titanium.UI.createButton({
title : 'Click',
top:'100dp'
});
button.addEventListener('click', function() {
uploadImage();
});
win.add(button);
win.open();
function uploadImage() {
var request = 'http://app.cardfiler.com/cardfiler/c/' + 'UploadCardPhoto';
Titanium.API.error('Web Service Call ' + request);
var req = Titanium.Network.createHTTPClient({
timeout : 60000,
onload : function(e) {
Titanium.API.error('Web Service Response - On Image Upload ' + this.responseText);
var data = JSON.parse(this.responseText)
if(data.status == true) {
Titanium.API.error('uToken is ' + Titanium.App.Properties.getString('uToken'));
var alertDialog = Titanium.UI.createAlertDialog({
title : 'Alert',
message : data,
buttonNames : ['OK']
});
alertDialog.show();
} /* else {
Titanium.API.error('Response Status false ' + data.message + ' Code ' + data.code);
var alertDialog = Titanium.UI.createAlertDialog({
title : 'Alert',
message : data,
buttonNames : ['OK']
});
alertDialog.show();
}*/
},
onerror : function(e) {
Titanium.API.error('Web Service Response - On Error' + this.responseText);
var alertDialog = Titanium.UI.createAlertDialog({
title : 'Alert',
message : Titanium.Locale.getString('internet_connection_not_available'),
buttonNames : ['OK']
});
alertDialog.show();
}
});
req.open('POST', request);
req.setRequestHeader("ContentType", "multipart/form-data");
req.send({
'aToken' : '60113f81-6f06-4acc-8002-2c0066f88619',
'uToken' : '9c7ab91c-fccd-4282-b611-c5dec7e402d8',
'fileType' : 2,
'fileObject' : imageView.toBlob()
});
}
Replace following code with line no. 68 to 73 if(Titanium.Platform.name == 'android') { req.send({ 'aToken' : Titanium.Locale.getString('app_token_only'), 'uToken' : Titanium.App.Properties.getString('uToken'), 'fileType' : '2', // Only Change, Added single quote for Android 'fileObject' : blob }); } else { req.send({ 'aToken' : Titanium.Locale.getString('app_token_only'), 'uToken' : Titanium.App.Properties.getString('uToken'), 'fileType' : 2, // Only Change, No change needed for IPhone 'fileObject' : blob }); }
Thanks for the feedback. PR https://github.com/appcelerator/titanium_mobile/pull/1610 is being reviewed. This should be fixed in 2.0 Release and you will no longer need to use that workaround.
This is a side-effect of our Kroll conversion layer. Unfortunately, since
req.send
accepts an object, we must convert every Number we encounter in the object as a Java Double so we don't lose precision when the data is passed into our Java implementation. In practice, this conversion means that when the Java code does atoString()
on the Double object, the result will be2.0
for a JS literal of2
. There isn't an easy way for us to solve this unfortunately, short of completely rewriting our binding layer, which we won't have time for in 2.0. Since the workaround of just quoting the value is working for this use case, it's recommend that you use this workaround until we can find a suitable solutionClosing issue Tested with Ti Studio build 2.0.0.201203182248 Ti Mob SDK 2.0.0.v20120319003254 hash r60b6da4c OSX Lion 10.7.3 Nexus S OS 2.3.6 Verified that this works correctly in v8
Anvil test case added. PR link: https://github.com/appcelerator/titanium_mobile/pull/5011