I'm trying to incorporate video and audio file attachment to forum posts in an app, and the playback isn't working on iOS. On Android it works fine. The code looks like this (for audio, and similar for video):
String localAudiofilePath = FileSystemStorage.getInstance().getAppHomePath() + (String) fileInfo.get("path");
InputStream is = null;
Media m = null;
try{
is = FileSystemStorage.getInstance().openInputStream(localAudiofilePath);
m = MediaManager.createMedia(is, "audio/" + extractFileExtension((String) fileInfo.get("path")));
}catch(Exception ex){
ex.printStackTrace();
}
m.play();
final Media mm = m;
Display.getInstance().scheduleBackgroundTask(new Runnable() {
#Override
public void run() {
while(mm.isPlaying()){
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
}
}
mm.cleanup();
}
});
I don't see any errors in the console, and when debugging I see the catch block is not entered. However, no sound comes out of the device when I try to play the audio, and the video player remains blank, giving me this message in the console:
2018-01-18 04:22:20.213822 MyApplication[24425:2262915] [Playback] ❗️Playback failed with error: Error Domain=AVFoundationErrorDomain Code=-11800 "The operation could not be completed" UserInfo={NSUnderlyingError=0x61000024c2d0 {Error Domain=NSOSStatusErrorDomain Code=-12893 "(null)"}, NSLocalizedFailureReason=An unknown error occurred (-12893), NSLocalizedDescription=The operation could not be completed}, not resolving (canResolve: YES, errorResolver: (null))
What am I missing?
You are using the audio recording mime type to playback a video. I guess Android ignores it which is fine. The iOS port sees an audio format for the stream data and assumes this is an audio file. You need to specify the mime file type of the video you are playing.
The problem was not at all media playback. The file wasn't actually present on the device, even though no exception was reported by iOS nor was the catch clause ever entered. My incorrect assumptions were 1. that I could use try/catch around the input stream instantiation as a means of checking if the file exists (it worked on Android but not iOS), and 2. that the operating system would necessarily throw an exception if the file wasn't present (not the same as 1., but tied into it).
My new, working code looks like this:
String localAudiofilePath = FileSystemStorage.getInstance().getAppHomePath() + MyApplication.DIRECTORY_APP_DOWNLOADS + "/" + (String) fileInfo.get("path");
if(!FileSystemStorage.getInstance().exists(localAudiofilePath)){
Cn1FileUtils.downloadRemoteFile("https://medonline.co.il/uploads/" + (String) fileInfo.get("path"), (String) fileInfo.get("path"), true);
}
InputStream is = null;
media = null;
try{
is = FileSystemStorage.getInstance().openInputStream(localAudiofilePath);
media = MediaManager.createMedia(is, "audio/" + Cn1FileUtils.extractFileExtension((String) fileInfo.get("path")));
}catch(Exception ex){
ex.printStackTrace();
ToastBar.showErrorMessage(MyApplication.getInstance().getString("error_loading_file"));
return;
}
media.play();
Related
I'm having trouble trying to consume the Response of an HTTP Endpoint which Streams real-time events continously. It's actually one of Docker's endpoints: https://docs.docker.com/engine/api/v1.40/#operation/SystemEvents
I am using Apache HTTP Client 4.5.5 and it just halts indefinitely when I try to consume the content InputStream:
HttpEntity entity = resp.getEntity();
EntityUtils.consume(entity);//it just hangs here.
//Even if I don't call this method, Apache calls it automatically
//after running all my ResponseHandlers
Apparently, it can be done by using JDK's raw URL: Stream a HTTP response in Java
But I cannot do that since local Docker communicates over a Unix Socket which I only managed to configure in Apache's HTTP Client with a 3rd party library for Unix Sockets in Java.
If there is a smarter HTTP Client library which I could switch to, that would also be an option.
Any ideas would be greatly appreciated. Thank you!
I managed to solve this issue by generating an infinite java.util.stream.Stream of JsonObject from the response InputStream (I know the json reading part is not the most elegant solution but there is no better way with that API and also, Docker doesn't send any separator between the jsons).
final InputStream content = response.getEntity().getContent();
final Stream<JsonObject> stream = Stream.generate(
() -> {
JsonObject read = null;
try {
final byte[] tmp = new byte[4096];
while (content.read(tmp) != -1) {
try {
final JsonReader reader = Json.createReader(
new ByteArrayInputStream(tmp)
);
read = reader.readObject();
break;
} catch (final Exception exception) {
//Couldn't parse byte[] to Json,
//try to read more bytes.
}
}
} catch (final IOException ex) {
throw new IllegalStateException(
"IOException when reading streamed JsonObjects!"
);
}
return read;
}
).onClose(
() -> {
try {
((CloseableHttpResponse) response).close();
} catch (final IOException ex) {
//There is a bug in Apache HTTPClient, when closing
//an infinite InputStream: IOException is thrown
//because the client still tries to read the remainder
// of the closed Stream. We should ignore this case.
}
}
);
return stream;
I want to store position coords (latitude, longitude) in a table in my MySQL DB querying a url in a way similar to this one: http://locationstore.com/postlocation.php?latitude=var1&longitude=var2 every ten seconds. PHP script works like a charm. Getting the coords in the device ain't no problem either. But making the request to the server is being a hard one. My code goes like this:
public class LocationHTTPSender extends Thread {
for (;;) {
try {
//fetch latest coordinates
coords = this.coords();
//reset url
this.url="http://locationstore.com/postlocation.php";
// create uri
uri = URI.create(this.url);
FireAndForgetDestination ffd = null;
ffd = (FireAndForgetDestination) DestinationFactory.getSenderDestination
("MyContext", uri);
if(ffd == null)
{
ffd = DestinationFactory.createFireAndForgetDestination
(new Context("MyContext"), uri);
}
ByteMessage myMsg = ffd.createByteMessage();
myMsg.setStringPayload("doesnt matter");
((HttpMessage) myMsg).setMethod(HttpMessage.POST);
((HttpMessage) myMsg).setQueryParam("latitude", coords[0]);
((HttpMessage) myMsg).setQueryParam("longitude", coords[1]);
((HttpMessage) myMsg).setQueryParam("user", "1");
int i = ffd.sendNoResponse(myMsg);
ffd.destroy();
System.out.println("Lets sleep for a while..");
Thread.sleep(10000);
System.out.println("woke up");
} catch (Exception e) {
// TODO Auto-generated catch block
System.out.println("Exception message: " + e.toString());
e.printStackTrace();
}
}
I haven't run this code to test it, but I would be suspicious of this call:
ffd.destroy();
According to the API docs:
Closes the destination. This method cancels all outstanding messages,
discards all responses to those messages (if any), suspends delivery
of all incoming messages, and blocks any future receipt of messages
for this Destination. This method also destroys any persistable
outbound and inbound queues. If Destination uses the Push API, this
method will unregister associated push subscriptions. This method
should be called only during the removal of an application.
So, if you're seeing the first request succeed (at least sometimes), and subsequent requests fail, I would try removing that call to destroy().
See the BlackBerry docs example for this here
Ok so I finally got it running cheerfully. The problem was with the transport selection; even though this example delivered WAP2 (among others) as an available transport in my device, running the network diagnostics tool showed only BIS as available. It also gave me the connection parameters that I needed to append at the end of the URL (;deviceside=false;ConnectionUID=GPMDSEU01;ConnectionType=mds-public). The code ended up like this:
for (;;) {
try {
coords.refreshCoordinates();
this.defaultUrl();
this.setUrl(stringFuncs.replaceAll(this.getUrl(), "%latitude%", coords.getLatitude() + ""));
this.setUrl(stringFuncs.replaceAll(this.getUrl(), "%longitude%", coords.getLongitude() + ""));
cd = cf.getConnection(this.getUrl());
if (cd != null) {
try {
HttpConnection hc = (HttpConnection)cd.getConnection();
final int i = hc.getResponseCode();
hc.close();
} catch (Exception e) {
}
}
//dormir
Thread.sleep(15000);
} catch (Exception e) {
} finally {
//cerrar conexiones
//poner objetos a null
}
Thanks for your help #Nate, it's been very much appreciated.
Can any one please tell me the process through which I can open a photo gallery in the blackberry application to choose a photo to upload, is there any file uploading control in the blackeberry 5.0 and also tell me the process to save the photo from the blackberry application to the remote server using HttpWebRequest.
Thanks
Their is nice way which i have done. Just get selected image from the phone through file browser or file io method than convert it to a byte array than just encode it to base64 String and send this string to the server by http request.
and at server side just do opposite.
final byte[] chunk;
chunk = new byte[actualSize];
try {
int bytesRead = in.read(chunk);
fconn.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try
{
String encodedStr = Base64OutputStream.encodeAsString(chunk, 0, chunk.length,false,false);
}
is there any way out that we can make the data in text file persistent? everytime a user finishes playing a game, in my program his name and respective score is written to a text file. When the next player comes the previous one gets overwritten. since am writing in write mode, I am not sure whether append mode is supported to save scores of this sort in blackberry...any suggestions are welcome
You should really use the PersistentStore to store this type of information - it's much easier to use and probably more reliable than trying to write files.
However, if you insist on writing files, here's the general code to open a file for appending:
private OutputStream openFileForWriting(String filePath) {
try {
FileConnection fconn = (FileConnection) Connector.open(filePath);
// If no exception is thrown, then the URI is valid, but the file may or may not exist.
if (!fconn.exists()) {
fconn.create(); // create the file if it doesn't exist
}
return fconn.openOutputStream(fconn.fileSize());
} catch (IOException ioe) {
System.out.println("Could not open " + filePath + " for writing");
}
return null;
}
I have coded to get the info from the user and send an email of clicking a button. The program is getting executed for a while and then the simulator is crashing showing error
"DE427"-Message queue full... Here's the code that i have done...
if(field==SendMail)
{
Message m = new Message();
Address a = null;
try {
a = new Address("user#xyz.com", "Rahul");
} catch (AddressException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Address[] addresses = {a};
try {
m.addRecipients(net.rim.blackberry.api.mail.Message.RecipientType.TO, addresses);
m.setContent("Name:"+Name.getText().toString()+"\n"+ "Phone :"+Phone.getText().toString()+
"\n"+ "Date & Time:"+DateShow.getText().toString()+"\n"+"Make:"+Make.getText().toString()+
"\n"+"Model:"+Model.getText().toString()+"\n"+"Miles:"+Miles.getText().toString()+"\n");
m.setSubject("Appointment Request (Via Blackberry app)");
} catch (MessagingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Invoke.invokeApplication(Invoke.APP_TYPE_MESSAGES, new MessageArguments(m));
}
Can anyone tell me what the error is and how to rectify the problem....Plz...
It seems there is an issue with certain versions of Windows XP and the Blackberry simulator version. Check this link http://supportforums.blackberry.com/t5/Testing-and-Deployment/Simulator-quot-device-Error-DE427-quot/m-p/556321
If you clean up the simulator (delete .dmp files from simulator directory) and restart the simulator it works fine