LuaSocket and Android

I am connecting to a web service, making a query, parsing the returned XML file then decoding a photo that is embedded in that XML file that is encoded with base64. I am using Luasocket for connectivity and mime decoding and xml_parser for XML processing. Everything is working great on IOS devices, the IOS simulator and the Corona simulator on the Mac.

However, on Android devices (I have tested with 2.2 and 4.1) I get an error when it tries to decode the photo that says: getBitmapAsset: Unable to decode file ‘/data/data/(program name)/cache/tmp/lPhoto.jpg’.

Strangely enough, the Corona simulator on the PC will try to display the photo (no errors in terminal) but it appears as a grainy, multi-colored object as if it had trouble decoding the photo. Below is sample code with company-specific info removed. I am using build 904.

Any assistance is greatly appreciated! Scott

require("xml\_parser")  
local http = require("socket.http")  
local ltn12 = require("ltn12")  
local mime = require("mime")  
  
local source = ltn12.source.file(io.stdin)  
local sink = ltn12.sink.file(io.stdout)  
  
local photo  
local photoArr = {}   
  
local srn = "016137S3"  
local url = "http://phony.webserver.address.asmx/getIndividual?srn="..srn  
local srcfile = "IndividualDetail.xml"  
  
-- function to get xml file from web service  
function getXMLData(url)  
 local myPath = system.pathForFile(srcfile, system.TemporaryDirectory)  
 local myFile = io.open( myPath, "w" )  
 local xmltext = http.request{url = url, sink = ltn12.sink.file(myFile),}  
 return XmlParser:ParseXmlFile(myPath)  
end  
  
-- pull out data we need from parsed xml data   
function parseXML(xmlTree)  
 xmlFile = xmlNodes(xmlTree, "Individual")  
 for i,xmlNode in pairs(xmlFile) do  
 if(xmlNode.Name == "IndividualDetail") then   
 -- photo info  
 local imageNodes = xmlNodes(xmlNode, "ImageDetail")  
 photoArr[1] = imageNodes[3].Value  
  
 -- setup path for photo  
 local lPhoto = "lPhoto.jpg"   
 local lPath = system.pathForFile(lPhoto, system.TemporaryDirectory)  
  
 -- decode photo  
 local myPhoto = io.open(lPath, "w")  
 local source = ltn12.source.string(photoArr[1])  
 local sink = ltn12.sink.file(myPhoto)  
 local convert = mime.decode("base64")  
 sink = ltn12.sink.chain(convert, sink)  
 ltn12.pump.all(source, sink)  
 end  
 end  
end  
  
-- xmlNodes function returns xml node(s)  
function xmlNodes(xmlTree, nodeName)  
 for i,xmlNode in pairs(xmlTree.ChildNodes) do  
 if(xmlNode.Name==nodeName) then  
 return xmlNode.ChildNodes  
 end  
 end  
end  
  
-- function to display photo  
function displayPhoto()   
 photo = display.newImage("lPhoto.jpg", system.TemporaryDirectory, 0, 0)  
 photo:setReferencePoint(display.TopLeftReferencePoint)  
 photo:scale(lwidScale, lhtScale)  
 photo.x = 2  
 photo.y = 58  
end  
  
-- function to check for network connectivity  
local function checkNetwork()  
 local host = "www.google.com"  
 local con = socket.tcp()  
 con:settimeout( 4 )   
 resp = con:connect(host, 80)   
 con:close()  
end  
  
-- blast off!  
checkNetwork()  
if resp == nil then   
 local alert = native.showAlert( "Display Photo", "Network error. Please check your network connection.", { "OK" }, onNetwork)   
else  
 -- get the XML file  
 local xmlData = getXMLData(url)  
  
 -- extract the data that we need from the XML file   
 parseXML(xmlData)  
  
 -- calculate scaling ratio needed for photo  
 local loffPhoto = display.newImage("lPhoto.jpg", system.TemporaryDirectory)  
 local lcurWidth = loffPhoto.width  
 local lcurHeight = loffPhoto.height  
 lwidScale = (display.contentWidth / lcurWidth) / 3.01  
 lhtScale = 141 / lcurHeight  
 loffPhoto:removeSelf()  
  
 -- display photo  
 displayPhoto()  
end  

[import]uid: 85963 topic_id: 31578 reply_id: 331578[/import]

I had some error with base64 encoding decoding when was sending data via socket. It was adding some chars at the end of base64 string. You should try to save you encoded base64 string and make a confront with your decoded base64 string. Maybe this is the error. [import]uid: 138389 topic_id: 31578 reply_id: 126174[/import]

I confirm the unexpected behavior of the built-in Base64 encoding function. In my case somehow the encoded string was 30% larger than what it was supposed to be which resulted in corrupted files when decoding it. Maybe iOS is more tolerant of junk data on jpg images than Android. Try a standalone base64 command to compare the results. [import]uid: 61899 topic_id: 31578 reply_id: 126219[/import]

I had some error with base64 encoding decoding when was sending data via socket. It was adding some chars at the end of base64 string. You should try to save you encoded base64 string and make a confront with your decoded base64 string. Maybe this is the error. [import]uid: 138389 topic_id: 31578 reply_id: 126174[/import]

I confirm the unexpected behavior of the built-in Base64 encoding function. In my case somehow the encoded string was 30% larger than what it was supposed to be which resulted in corrupted files when decoding it. Maybe iOS is more tolerant of junk data on jpg images than Android. Try a standalone base64 command to compare the results. [import]uid: 61899 topic_id: 31578 reply_id: 126219[/import]

UPDATE: changing the mode on the io.open statement to allow “binary”, corrected the grainy effect I was getting but has created an even stranger issue. All of the photos now decode and display correctly on the Windows Android simulator but will not decode and display on the Android device itself.

local myPhoto = io.open(lPath, "wb") [import]uid: 85963 topic_id: 31578 reply_id: 129484[/import]

UPDATE: changing the mode on the io.open statement to allow “binary”, corrected the grainy effect I was getting but has created an even stranger issue. All of the photos now decode and display correctly on the Windows Android simulator but will not decode and display on the Android device itself.

local myPhoto = io.open(lPath, "wb") [import]uid: 85963 topic_id: 31578 reply_id: 129484[/import]