I originally posted this question to the Android developers Google group a few days ago, but have yet to hear a response. Maybe someone on Stack Overflow can help?
I have an app which streams mp3s from the web, proxied through a local HTTP server. At times, this local proxy server returns an HTTP error. It seems that upon receiving this error during the prepare state, the MediaPlayer makes one more attempt to stream, sending another request to the URL specified in setDataSource().
From a thread, I'm calling MediaPlayer.prepare() once. But from the proxy thread, I can see that after sending an HTTP error response, another request for the same URL is made. Can someone confirm this behavior? I'm seeing this from the emulator running a 1.6 AVD.
Can I disable this automatic retry? Is there a specific HTTP error code that I can send that will prevent this retry?
Thanks!
Related
I am trying to write my own AB STREAMING update based on https://android.googlesource.com/platform/bootable/recovery/+/master/updater_sample and after many days of developing and decomposing looks it good.
But I have big problem with using https protocol (which is required by default). When i try to call method applyUpdate(Context context, UpdateConfig config) from UpdateManager, I got error 9 (DOWNLOAD_TRANSFER_ERROR) immediately.
It's interesting, because all other metadata were downloaded without problems. It looks problem is only with downloading of payload.bin.
When I try to change protocol from https to http (by enabling in manifest of course and changing link in json file) no problem appeared.
So questions are:
Is it bug in android? Do you have the same problem (I found another question one year ago but without reaction). Is there any special request for https, webserver...
Yes, I can leave http protocol enable, but I am afraid of new steps from Google, they can forbid this option.
Thank you
D
I was facing a similar issue where the Streaming AB OTA update was failing with error 9 (DOWNLOAD_TRANSFER_ERROR) but on Android 10.
Here are the logs from my device
E/update_engine: [1003/030413.677875:ERROR:libcurl_http_fetcher.cc(436)] Unable to get http response code.
I/update_engine: [1003/030413.678370:INFO:libcurl_http_fetcher.cc(467)] Transfer resulted in an error (0), 46484 bytes downloaded
I/update_engine: [1003/030413.678435:INFO:libcurl_http_fetcher.cc(481)] No further proxies, indicating transfer complete
I/update_engine: [1003/030413.678483:INFO:multi_range_http_fetcher.cc(172)] Received transfer complete.
I/update_engine: [1003/030413.678528:INFO:multi_range_http_fetcher.cc(129)] TransferEnded w/ code 0
I/update_engine: [1003/030413.678572:INFO:multi_range_http_fetcher.cc(144)] Didn't get enough bytes. Ending w/ failure.
I/update_engine: [1003/030413.678675:INFO:action_processor.cc(116)] ActionProcessor: finished DownloadAction with code ErrorCode::kDownloadTransferError
I/update_engine: [1003/030413.678723:INFO:action_processor.cc(121)] ActionProcessor: Aborting processing due to failure.
I/update_engine: [1003/030413.678785:INFO:update_attempter_android.cc(454)] Processing Done.
I/update_engine: [1003/030413.678834:INFO:dynamic_partition_control_android.cc(151)] Destroying [] from device mapper
D/OTAManager: onStatusUpdate invoked, status=0, progress=0.00
D/OTAService: onProgressUpdate() called
D/OTAService: OTA Progress :0
I/OTAService: onEngineStatusUpdate - status=IDLE/0
D/OTAService: Sending Response to Client:- Msg:6 Data:0 Status:IDLE D/OTAManager: onPayloadApplicationComplete invoked, errorCode=9
D/OTAManager: setUpdaterState invoked newState=1
D/OTAService: onUpdaterStateChange state=ERROR/1
I/OTAService: onEnginePayloadApplicationComplete - errorCode=OS Update failed due to an error in fetching the payload/9 FAILURE
"libcurl_http_fetcher.cc: Unable to get HTTP response" => This is the culprit.
To know why this is happening I ran the following commands:
adb shell
curl -i https://myurl
To which the response was
curl: (60) SSL certificate problem: certificate has expired
More details here: https://curl.haxx.se/docs/sslcerts.html
curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.
I guess I need to update the SSL certificate on the server. However, your issue might not be exactly the same. But running the "curl" command from ADB shell might give you a clue.
Hope this helps.
i am using javamail's SMTPTransport.sendMessage method to send emails in my android app and everything works fine... but when i start sending a message and in the middle, i disable my wifi, it gets stuck. I have waited for more than 1hour now and it is still stuck; no exception is thrown... any idea how to handle this situation?
edit:
i have added a timeout
props.put("mail.smtp.connectiontimeout", "3000");
props.put("mail.smtp.timeout", "3000");
does not seem to work ... i have simulated a connection loss and it's already 5mins now and it is still in sending state and has not timed out
edit2:
timeout/error(not even sure if it is a timeout) occurred after 16mins
06-30 18:47:27.722: I/System.out(15906): javax.net.ssl.SSLException: Write error: ssl=0xdf8268: I/O error during system call, Invalid argument
edit 3:
it does not always throw an exception... i have simulated a connection loss and after 1hr, still no exception... it is in sending state..... and have not return yet :(
The current version of JavaMail only handles timeouts for reads, because that's all the JDK supports. For the next JavaMail release I've added support for write timeouts. You can experiment with it using the 1.5.1-SNAPSHOT release of JavaMail available in the maven.java.net repository. You'll need to set the "mail.smtp.writetimeout" property. Don't know if this will help you on Android since it's not really Java...
I have what appears to be a timing problem between a client (Galaxy Nexus) and a custom server since upgrading from Ice Cream Sandwich to Jelly Bean. Here is the general flow:
Client opens socket, issues HTTP get to server
Server accepts, starts new thread, responds with HTTP header and 200 OK.
Server writes (binary) file to socket.
Client reads data from socket and saves to a file.
After server thread writes all data, it closes the socket, and terminates
This has worked well over the past several months prior to the Jelly Bean update. Since the update the binary transfer succeeds about 70% of the time. The remaining 30% fails
when 'serverSocket.getInputStream().read' returns a -1 indicating the end of stream has been reached. No data has been read, no error exceptions raised, nothing in logcat.
The possibility of a timing problem arises when I change the server behavior in step #5. The thread was closing the socket after the write with the observed problems. If I remove the socket close, terminate the thread after the write, and let the OS eventually close the socket then it seems to work all the time.
I used tcpdump and WireShark to look at the packets in both the successful and failed cases. In the failed case a socket is closed in a few milli-seconds while in the successful case the socket is closed is a quarter or more of a second. The net of this is that any delay we cause in the socket closing improves our chances for success.
If anyone has any suggestions with what we may be doing to cause this problem or suggestions on how to narrow down the problem please feel free to respond. I can add code samples if required.
It looks like that when the server ask for the connection close, the socket is immediatly closed. Maybe the default ocket linger's time has changed between version ???
Try setting the socket linger's time using:
socket.setSoLinger(boolean on, int timeout);
to have the server waiting some time before close channel if some data still waiting to be sent.
If this doesn't solve, you can change your flow above to:
...
4.Client reads data from socket and saves to a file.
5.Client send confirmation to server.
6.Server close connection.
--EDITED--
A gracefull way to achive the above without additional TCP data packets traveling for the closing confirmation is:
when server finish writing to the socket calls:
socket.shutdownOutput();
when client socket.read() returns -1, client calls:
socket.close();
This ensures that client is informed that all data has been sent, and sender will wait for the socket closure protocol to complete.
I was Posting Data from Android Mobile to Server over HTTP connection. I was able to POST data to server and also get acknowledgement from Server. But sometime if my server communication thread waiting for acknowledgement from server after posting data that time i loss Internet Connectivity and thread unable to receive Ack from server and goes in infinite loop. I tried setReadTimeOut(180000) method.
Can it work for me? Can it gives SocketTimeOutException if no network Available/ No connection between server and mobile
Setting a timeout will most likely work. However, I would not recommend setting it to 180000 (= 180 seconds = 3 minutes!). 30 seconds is usually more than enough. You also might want to add a setConnectTimeout
Note that there are some situations where an HttpUrlConnection doesn't always work properly:
Android versions 2.2 or earlier, better use the Apache HTTP client for these versions (see also this post)
On the emulator (see also this post)
Having a problem with the android sipdemo timing out when making calls. The native sip client on the phone has no issues calling, works perfect. Its When i initiate the call within the sipdemo i get a timeout in the logcat. timeout is set to standard of 30 seconds.. a local asterisk box is what its connecting to. Registers fine.
I'm having the same problem.
I traced packages in wireshark and here's what I found:
I register to SIP server in SipDemo
I register to SIP server on Desktop (using Ekiga)
I place a call in SipDemo to Ekiga.
INVITE message gets sent to Ekiga
Trying is sent from Ekiga to the server
Ringing is sent from Ekiga to SipDemo
I answer the call on Ekiga client
OK (with session description) is sent from Ekiga to SipDemo. This happens 11 times before Ekiga just gives up
BYE is sent from Ekiga client to SipDemo
Please note that OK is being sent 11 times before Ekiga just gives up and ends the call. This is why the call lasts just 30 seconds.
If you take a look at the RFC here:
http://www.ietf.org/rfc/rfc3261.txt section 13.3.1.4
you can see that the reason Ekiga is giving up on SipDemo client is because it never gets ACK back from SipDemo.
I believe this is android bug, but I can't imagine they could have missed something this basic in their SIP implementation.
In the next few days, I'll try to dig up some answers in android source code...
I'll try see what happens when establishing calls between 2 SipDemo applications. If it works, that means android just ignores ACK all together.
EDIT:
I just tried a call between 2 SipDemo clients. It sends OK 5 times and gives up on the OK, but does not end the call. Interesting behavior :)
EDIT2:
I dug up androids SIP implementation, and I found that ACK should get sent... Even logcat logs this, but I still see nothing in Wireshark. I thought maybe it gets blocked or something, so I ran Shark (like Wireshark for android) on the device, pulled the dump to my laptop, opened it up in Wireshark, and I don't see ACK anywhere. I even looked trough all packets... No filters, just in case I might be filtering it out. Anyways... Here's what I found in android code:
http://hi-android.info/src/com/android/server/sip/SipSessionGroup.java.html
class: SipSessionImpl
method: private boolean outgoingCall(EventObject evt)
in case Response.OK:
you can see this call:
mSipHelper.sendInviteAck(event, mDialog);
In SipHelper, method sendInviteAck, you can see:
if (DEBUG) Log.d(TAG, "send ACK: " + ack);
dialog.sendAck(ack);
Dialog is nist javax.sip, so I don't think there's a need to go further...
I see this message "send ACK" in my logcat when running the application
EDIT3:
I noticed that this issue occurs only with some SIP servers. I now tried opensips, and it works fine. I guess the problem I was having had to do with the server responding to androids keep-alive OPTIONS messages with 404 Not Found. Then, android tried to not use the server as soon as possible. Because of that, as soon as android got the address of its peer client, it tried to send a direct message, and failed
Hard to tell just like that. Try capturing the packages with wireshark, filter for the SIP protocol and have a look at what is sent over the network. Also try it with the native client and compare it to the sipdemo.
Another starting point is the log of your asterisk instance (systemlog)
If you can't figure it out yourself, post the results here.