File sent by Nearby not opening - google-nearby

I'm starting to work with Nearby, and sending a file over the stream. I see on the sender's side that the file is sent, and on the receiver's side I see both the onPayloadReceived event and 2 onPayloadTransferUpdate events, the second with a status of 1. Once I get that event with status 1, I run the following code:
Payload payload = payloads.remove(id);
try {
Payload.File payloadFile = payload.asFile();
Reader reader;
File file = payloadFile.asJavaFile();
if (file==null)
reader = new FileReader(payloadFile.asParcelFileDescriptor().getFileDescriptor());
else
reader = new FileReader(file);
StringBuilder builder = new StringBuilder();
char[] buff = new char[1024];
do
{
int count = reader.read(buff);
if (count<=0)
break;
builder.append(buff, 0, count);
}while(true);
receivedData.setText(builder);
}
catch (Exception exn){Log.d(TAG, "Exception thrown while receiving",exn);}
The result is that file is null, and the read command throws an IOException with the message read failed: EBADF (Bad file number). How do I fix this?

Could you show the code that corresponds to you "sending a file over the stream"?
I ask because STREAM and FILE are 2 different Payload types, so if you send as a STREAM (regardless of whether the contents of the STREAM came from a file), you will receive as a STREAM.

Related

BizTalk custom pipeline parsing POP3 PDF attachment error

I have a BizTalk custom pipeline component where I'm parsing a PDF attachment using itexsharp into a custom model. The pipeline is bound to a POP3 receiving port.
In the new created message if I return the attachment stream (outputMessage.GetPart("Body").Data = ms), then this is looking good in the BizTalk administration console. I have been able to save the message from here manually and this was parsed correctly using the same parsing method as in the pipeline.
When parsing the PDF directly in the pipeline, then I'm getting the following error: Rebuild failed: trailer not found.; Original message: xref subsection not found at file pointer 1620729
If I remove the default XMLDisassembler component from pipeline, then the parsing error disappeared, but in the console the message Body is empty, although the AttachmentSizeInBytes=1788
public IBaseMessage Execute(IPipelineContext pContext, IBaseMessage pInMsg)
{
return ExtractMessagePartToMessage(pContext, pInMsg);
}
private IBaseMessage ExtractMessagePartToMessage(IPipelineContext pContext, IBaseMessage pInMsg)
{
if (pInMsg.PartCount <= 1)
{
throw new InvalidOperationException("The email had no attachment, apparently.");
}
string partName;
IBaseMessagePart attachmentPart = pInMsg.GetPartByIndex(1, out partName);
Stream attachmentPartStream = attachmentPart.GetOriginalDataStream();
IBaseMessage outputMessage;
outputMessage = pContext.GetMessageFactory().CreateMessage();
outputMessage.AddPart("Body", pContext.GetMessageFactory().CreateMessagePart(), true);
outputMessage.Context = pInMsg.Context;
var ms = new MemoryStream();
attachmentPartStream.CopyTo(ms);
ms.Seek(0L, SeekOrigin.Begin);
Stream orderStream = PdfFormParser.Parse(ms);
outputMessage.GetPart("Body").Data = orderStream;
outputMessage.Context.Write("AttachmentName", "http://schemas.microsoft.com/BizTalk/2003/file-properties", partName);
outputMessage.Context.Write("AttachmentSizeInBytes", "http://schemas.microsoft.com/BizTalk/2003/file-properties", orderStream.Length.ToString());
pContext.ResourceTracker.AddResource(ms);
pContext.ResourceTracker.AddResource(orderStream);
return outputMessage;
}
public static Stream Parse(Stream pdfDocument)
{
using (var reader = new PdfReader(pdfDocument))
{
var outputStream = new MemoryStream();
var pdfForm = ParseInternal(reader);
var xmlDocument = new XmlDocument();
xmlDocument.LoadXml(pdfForm.Serialize());
xmlDocument.Save(outputStream);
return outputStream;
}
In pipelines when you read or write a Stream, you have to rewind the stream back to the beginning if something else is going to use it (especially the final message that you expect BizTalk to process).

How to know if it is safe to keep reading from a socket inputStream (avoid read blocks)

I'll give you a little bit of context first:
I have a class that is supposed to write in a socket some querys and then read the answers.
Here it is the code that is supposed to read from the inputStream:
private String getDataFromInputStream() throws IOException
{
StringBuilder sb = new StringBuilder();
InputStream stream = this.socket.getInputStream();
byte[] buff = new byte[1024];
int bytesRead = 0;
while(bytesRead >= 0)
{
bytesRead = stream.read(buff);
if (bytesRead > 0) sb.append(new String(buff, 0, bytesRead));
}
return sb.toString();
}
If the returned result is OK, this method works great, but if, for some reason, the InputStream.read keeps waiting for input it, of course, blocks.
So I changed that code to this one:
private String getDataFromInputStream() throws IOException
{
StringBuilder sb = new StringBuilder();
InputStream stream = this.socket.getInputStream();
byte[] buff = new byte[1024];
int bytesRead = 0;
while(stream.available() > 0)
{
bytesRead = stream.read(buff);
if (bytesRead > 0) sb.append(new String(buff, 0, bytesRead));
}
return sb.toString();
}
But here's the new problem: The second piece of code doesn't read the whole response. It just returns a fragment of the full response.
I know that the available() method returns 0 because the stream doesn't have more data to be read inside the buffer but there is more data to be read from the socket.
So how can I make a method flexible enought to read the whole thing even if it takes some time to the Stream to buffer the response and, also doesn't block when expecting input?
I need to get the whole response if the query succeeded and to close the input so it won't block, if the command failed and the socket is expecting any input.
Since you're using a socket, you'll need the source to tell you how much data it wants to send. That may be present in the first few bytes that is sent (in which case you wait for that specific number of bytes first) otherwise you'll have to modify the source to provide that information. This is what TCP and UDP packets do as well, where the header to the packets include the length of the data so that the client knows how many bytes to wait for.

Email Fails to send with sms details

The following code listens for an incoming sms, takes all the spaces out of the sms then emails the edited sms. Everything works fine, except that the app fails to send an email. Can anyone see what I am doing wrong and help me?
new Thread() {
public void run() {
try {
DatagramConnection _dc =
(DatagramConnection)Connector.open("sms://");
for(;;) { //'For-Loop' used to listen continously for incoming sms's
Datagram d = _dc.newDatagram(_dc.getMaximumLength());
_dc.receive(d); //The sms is received
byte[] bytes = d.getData();
String address = d.getAddress(); //The address of the sms is put on a string.
String msg = new String(bytes); //The body of the sms is put on a string.
String msg2 = (replaceAll(msg, " ","")) ; //
Store store = Session.getDefaultInstance().getStore();
Folder[] folders = store.list(Folder.SENT);
Folder sentfolder = folders[0]; //Retrieve the sent folder
Message in = new Message(sentfolder);
Address recipients[] = new Address[1];
recipients[0]= new Address("me#yahoo.com", "user");
in.addRecipients(Message.RecipientType.TO, recipients);
in.setSubject("Incoming SMS"); //The subject of the message is added
in.setContent("You have just received an SMS from: " + address + "/n" + "Message: " + msg2); //Here the body of the message is formed
in.setPriority(Message.Priority.HIGH); //The priority of the message is set.
Transport.send(in); //The message is sent
in.setFlag(Message.Flag.OPENED, true);
Folder folder = in.getFolder(); //The message is deleted from the sent folder
folder.deleteMessage(in);
}
}catch (Exception me) { //All Exceptions are caught
}
}
};
public static String replaceAll(String front, String pattern, String back) {
if (front == null)
return "";
StringBuffer sb = new StringBuffer(); //A StringBufffer is created
int idx = -1;
int patIdx = 0;
while ((idx = front.indexOf(pattern, patIdx)) != -1) {
sb.append(front.substring(patIdx, idx));
sb.append(back);
patIdx = idx + pattern.length();
}
sb.append(front.substring(patIdx));
return sb.toString();
}
Thanks
This isn't really an answer to the problem, just an elaboration on my comment above, that might help.
Make sure do something in your exception catch block, so that problems in the code don't go unnoticed. It's possible that your code is not encountering any exceptions, but in order for us to help, we need to try to eliminate potential problems, and since you say the code isn't working, but you have an empty exception handler, that's an easy area to fix first.
the simplest handler is just:
try {
// try sending sms here
} catch (Exception e) {
e.printStackTrace();
}
If you can run this in the debugger (which I highly suggest), then you can now put a breakpoint on the e.printStackTrace() line, and see if it ever gets hit. If it does, inspect the value of e and tell us what it is.
Normally, in my programs, I don't actually use e.printStackTrace() in catch handlers, but I have a logging class that takes strings, and maybe a log level (e.g. info, warning, error, verbose), and writes to a log file. The log file can be attached to emails the users send to tech support, or can be disabled for production if you only want to use the feature while developing.
Anyway, start with a simple printStackTrace() and see if it ever gets hit. Then, report back.
Edit: from the symptoms you describe in the comments after your question, it seems like it's a possibility that
String msg2 = (replaceAll(msg, " ","")) ; //
is throwing an exception, and therefore never letting you get to where you'd send the email. I can't see anything wrong with your implementation of replaceAll() upon initial inspection, but that might be a place to look. Has that implementation been thoroughly unit-tested?
Also, I think you have a "/n" in your code where you probably want a "\n", right?

Android InputStream

I am learning android but I can't get past the InputStream.read().
This is just a socket test - the server sends back two bytes when it receives a connection and I know that this working fine. All I want to do is read these values. The b = data.read reads both values in turn but then hangs, it never returns the -1 value which is what expect it to. Also it does not throw an exception.
Any ideas?
Thanks.
protected void startLongRunningOperation() {
// Fire off a thread to do some work that we shouldn't do directly in the UI thread
Thread t = new Thread() {
public void run() {
try {
Log.d("Socket", "try connect ");
Socket sock = new Socket("192.168.0.12", 5001);
Log.d("socket", "connected");
InputStream data = sock.getInputStream();
int b = 0;
while (b != -1) {
b = data.read();
}
data.close();
} catch (Exception e) {
Log.d("Socket", e.toString());
}
}
};
t.start();
}
Reaching the end of the stream is a special state. It doesn't happen just because there is nothing left to read. If the stream is still open, but there's nothing to be read, it will "hang" (or block) as you've noticed until a byte comes across.
To do what you want, the server either needs to close/end the stream, or you need to use:
while (data.available() > 0) {
..
When the number of available bytes is zero, there's nothing sitting in the stream buffer to be read.
On the other hand, if you know that there should only ever be two bytes to read, and that's the end of your data, then just read the two bytes and move on (i.e. don't use a while loop). The reason to use a while loop here would only be if you weren't sure how many total bytes to expect.

Using java.lang.ProcessBuilder

From a java application I run a bat file which starts another java application:
ProcessBuilder processBuilder = new ProcessBuilder("path to bat file");
Process process = processBuilder.start();
But the process never starts and no errors gets printed. But if I add the line:
String resultString = convertStreamToString(process.getInputStream());
after : Process process = processBuilder.start();
where:
public String convertStreamToString(InputStream is) throws IOException {
/*
* To convert the InputStream to String we use the Reader.read(char[]
* buffer) method. We iterate until the Reader return -1 which means there's
* no more data to read. We use the StringWriter class to produce the
* string.
*/
if (is != null) {
Writer writer = new StringWriter();
char[] buffer = new char[1024];
try {
Reader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
int n;
while ((n = reader.read(buffer)) != -1) {
writer.write(buffer, 0, n);
}
} finally {
is.close();
}
return writer.toString();
} else {
return "";
} }
it runs fine! Any ideas?
If it's really a batch file, you should run the command line interpreter as process (e.g. cmd.exe) with that file as parameter.
Solved here:
Starting a process with inherited stdin/stdout/stderr in Java 6
But, FYI, the deal is that sub-processes have a limited output buffer so if you don't read from it they hang waiting to write more IO. Your example in the original post correctly resolves this by continuing to read from the process's output stream so it doesn't hang.
The linked-to article demonstrates one method of reading from the streams. Key take-away concept though is you've got to keep reading output/error from the subprocess to keep it from hanging due to I/O blocking.