read lines of text file to string array - inputstream

I need to write lines of text into a file and then read them line by line.
therefore I used these codes to write into a file:
String string = "Hello world55555555555!" + "\r\n";
FileOutputStream outputStream;
try {
outputStream = getActivity().openFileOutput(filename, Context.MODE_PRIVATE);
outputStream.write(string.getBytes());
outputStream.flush();
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
return true;
which it seems work properly. but when I am reading it get error! I am trying to read it by these codes:
FileInputStream inputStream = null;
BufferedReader reader;
String[] text = new String[0];
List < String > words = new ArrayList < String > ();
String line;
try {
inputStream = getActivity().openFileInput(filename);
reader = new BufferedReader(new InputStreamReader(inputStream));
while ((line = reader.readLine()) != null) {
words.add(line);
}
text = new String[words.size()];
text = words.toArray(text);
} catch (IOException e) {
//You'll need to add proper error handling here
}
tv.setText(text[0]);
Toast.makeText(getActivity(), text[1],
Toast.LENGTH_SHORT).show();
}
any comments! Please!

Thanks for your considerations, I update my read codes to:
FileInputStream inputStream = null;
BufferedReader reader;
StringBuilder[] total = new StringBuilder[]{};
String line;
try{
inputStream = new FileInputStream(filename);
reader = new BufferedReader(new InputStreamReader(inputStream));
int j =0;
while ((line = reader.readLine()) != null) {
total[j].append(line);
j++;
}
}
catch(IOException e){
//You'll need to add proper error handling here
}
tv.setText(total[0]);
Toast.makeText(getActivity(),total[1],
Toast.LENGTH_SHORT).show();
}
But I get errors yet and app shutdown:
10-18 10:36:50.700 3087-3087/? D/AndroidRuntime﹕ Shutting down VM
10-18 10:36:50.700 3087-3087/? E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: ir.siavashon.sunshine, PID: 3087
java.lang.ArrayIndexOutOfBoundsException: length=0; index=0
at ir.siavashon.sunshine.MainActivityFragment.onClick(MainActivityFragment.java:140)
at android.view.View.performClick(View.java:5198)
at android.view.View$PerformClick.run(View.java:21147)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
10-18 10:36:50.700 1342-2903/? W/ActivityManager﹕ Force finishing activity ir.siavashon.sunshine/.MainActivity
10-18 10:36:50.710 993-993/? D/gralloc﹕ Registering a buffer in the process that created it. This may cause memory ordering problems.
10-18 10:36:50.710 993-993/? E/libEGL﹕ called unimplemented OpenGL ES API
10-18 10:36:50.710 993-993/? E/SurfaceFlinger﹕ glCheckFramebufferStatusOES error -906983389
10-18 10:36:50.710 993-993/? E/SurfaceFlinger﹕ got GL_FRAMEBUFFER_COMPLETE_OES error while taking screenshot
10-18 10:36:50.730 1342-3103/? W/DropBoxManagerService﹕ Dropping: data_app_crash (848 > 0 bytes)
10-18 10:36:51.220 1342-1356/? W/ActivityManager﹕ Activity pause timeout for ActivityRecord{a21f483 u0 ir.siavashon.sunshine/.MainActivity t897 f}
10-18 10:36:52.190 1656-1656/? I/Choreographer﹕ Skipped 55 frames! The application may be doing too much work on its main thread.
10-18 10:36:53.330 3087-3087/? I/Process﹕ Sending signal. PID: 3087 SIG: 9
10-18 10:36:53.430 1342-1372/? W/InputDispatcher﹕ channel 'cb217a9 ir.siavashon.sunshine/ir.siavashon.sunshine.MainActivity (server)' ~ Consumer closed input channel or an error occurred. events=0x9
10-18 10:36:53.430 1342-1372/? E/InputDispatcher﹕ channel 'cb217a9 ir.siavashon.sunshine/ir.siavashon.sunshine.MainActivity (server)' ~ Channel is unrecoverably broken and will be disposed!
10-18 10:36:53.430 1342-2903/? I/ActivityManager﹕ Process ir.siavashon.sunshine (pid 3087) has died
10-18 10:36:53.590 1342-1361/? W/AppOps﹕ Finishing op nesting under-run: uid 1000 pkg android code 24 time=0 duration=0 nesting=0
10-18 10:36:53.600 1342-1490/? I/WindowState﹕ WIN DEATH: Window{cb217a9 u0 ir.siavashon.sunshine/ir.siavashon.sunshine.MainActivity}
10-18 10:36:53.600 1342-1490/? W/InputDispatcher﹕ Attempted to unregister already unregistered input channel 'cb217a9 ir.siavashon.sunshine/ir.siavashon.sunshine.MainActivity (server)'

Related

How do I handle AX timeouts where the operation continues on? Abort not working?

I have a custom AX service operation that can take 5+ minutes to complete and I'm trying to figure out how to abort it from my .NET application, but aborting the client doesn't seem to do anything?
The problem is if I call the operation and the service times out, the AX operation continues on until completion, so I lose visibility to the results (success/failure). An example being a long-running posting operation where I don't know if it posted successfully or not.
I've created a simple demo app where I can't seem to get the operation to abort. In the below code I just create a transaction (ttsbegin/ttscommit), insert into a table at start, sleep, insert into table at end.
Sample AX X++ Service Code:
[SysEntryPointAttribute(true)]
public str callAXTimeDelay(int _sleepSeconds)
{
Table1 table1;
ttsBegin;
table1.clear();
table1.SleepData = strFmt("STARTED: %1", DateTimeUtil::utcNow());
table1.insert();
ttsCommit;
sleep(_sleepSeconds * 1000);
ttsBegin;
table1.clear();
table1.SleepData = strFmt("COMPLETED: %1", DateTimeUtil::utcNow());
table1.insert();
ttsCommit;
return strFmt("COMPLETED: %1", DateTimeUtil::utcNow());
}
Then when I call it from .NET, the abort doesn't seem to work? Start/Complete records are still inserted into table1 even though the abort is called before the 15 seconds have completed?
Sample .NET code:
internal class Program
{
static void Main(string[] args)
{
new Program().Run();
Console.WriteLine("Ended, press any key to exit...");
Console.ReadKey();
}
public void Run()
{
AXServicesClient axClient15Sec = new AXServicesClient();
AXServicesClient axClient5sec = new AXServicesClient();
var job15sec = DoLongRunningCall(axClient15Sec, 15);
var job5sec = DoLongRunningCall(axClient5sec, 5);
try
{
var result = Task.Run(() => Task.WhenAny(job15sec, job5sec)).GetAwaiter().GetResult();
if (result == job15sec)
{
Console.WriteLine("job15sec finished first, aborting job5sec");
axClient5sec.Abort();
}
else if (result == job5sec)
{
// This code gets executed because the 5 second job completed and
// it tries to cancel the 15-sec job, but the table ends up with data!
Console.WriteLine("job5sec finished first, aborting job15sec");
axClient15Sec.Abort();
}
}
catch (Exception e)
{
Console.WriteLine("Exception: " + e.Message);
axClient15Sec.Abort();
axClient5sec.Abort();
}
axClient15Sec.Close();
axClient5sec.Close();
}
public async Task<string> DoLongRunningCall(AXServicesClient client, int seconds)
{
var result = await client.callAXTimeDelay(new CallContext
{
Company = "ABCD",
Language = "en-us"
}, seconds);
return result.response;
}
}

display activity from other application on my own application

I would like to start an application (example Calculator) on a fragment for example on my application.
I try this code but i get an error (line Fragment):
String packageName = "com.android.calculator2";
Context ctx = getApplicationContext().createPackageContext(packageName, Context.CONTEXT_INCLUDE_CODE |
Context.CONTEXT_IGNORE_SECURITY);
ClassLoader cl = ctx.getClassLoader();
Class<?> c = cl.loadClass("com.android.calculator2.Calculator");
Fragment fragObj = (Fragment)c.newInstance();
i get this error:
Process: fr.jm.managercamera, PID: 14006
java.lang.RuntimeException: Unable to start activity ComponentInfo{fr.jm.managercamera/fr.jm.managercamera.MainActivity}: java.lang.ClassCastException: com.android.calculator2.Calculator cannot be cast to android.app.Fragment
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2325)
I try this code, i get other problem:
Class requiredClass = null;
final String apkPath = getPackageManager().getApplicationInfo("com.android.calculator2",0).sourceDir;
final File dexTemp = getDir("temp_folder", 0);
final String fullName = "com.android.calculator2.Calculator";
boolean isLoaded = true;
// Check if class loaded
try {
requiredClass = Class.forName(fullName);
} catch(ClassNotFoundException e) {
isLoaded = false;
}
if (!isLoaded) {
System.out.println("apkPath: " + apkPath);
System.out.println("dexTemp.getAbsolutePath(): " + dexTemp.getAbsolutePath());
final DexClassLoader classLoader = new DexClassLoader(apkPath,
dexTemp.getAbsolutePath(),
null,
getClass().getClassLoader());
/* DexClassLoader classLoader = new DexClassLoader(apkPath,"/tmp", null,
getClass().getClassLoader());*/
requiredClass = classLoader.loadClass(fullName);
}
I get this error (line loadClass):
10-03 17:50:22.776 14133-14133/? W/System.err: java.lang.ClassNotFoundException: Didn't find class "com.android.calculator2.Calculator" on path: DexPathList[[zip file "/system/app/Calculator/Calculator.apk"],nativeLibraryDirectories=[/vendor/lib64, /system/lib64]]
10-03 17:50:22.776 14133-14133/? W/System.err: at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
10-03 17:50:22.776 14133-14133/? W/System.err: at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
10-03 17:50:22.776 14133-14133/? W/System.err: at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
You can't do that. You can launch the calculator as an Activity, but you cannot load foreign code into your own OS process. That would be a security violation.
The calculator app's code is only allowed to run in the calculator app's OS Process, not in any other OS Process. The Android security model doesn't allow that.

Serial Connection (Arduino --> Java)

this will be my first post and I will do my best to be clear and concise. I've checked some of the other posts on this forum but was unable to find a satisfactory answer.
My question pertains to the use of JavaFX and the jSSC(java simple serial connection) library. I've designed a very simple GUI application that will host four different charts. Two of the charts will display readings from temperature and solar sensors for the past hour, while the other two display that data over an extended period -- a 14-hour period. Eventually I would like to make that more flexible and set the application to "sleep" when the readings become roughly zero (night).
How can I stream data to display this data in real time?
After referencing several sources online and from "JavaFX 8 Intro. by Example", I've been able to construct most of the serial connection class. I'm having trouble processing the data readings, so that it can be displayed on the chart.
public class SerialComm implements SerialPortEventListener {
Date time = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("mm");
boolean connected;
StringBuilder sb;
private SerialPort serialPort;
final StringProperty line = new SimpleStringProperty("");
//Not sure this is necessary
private static final String [] PORT_NAMES = {
"/dev/tty.usbmodem1411", // Mac OS X
"COM11", // Windows
};
//Baud rate of communication transfer with serial device
public static final int DATA_RATE = 9600;
//Create a connection with the serial device
public boolean connect() {
String [] ports = SerialPortList.getPortNames();
//First, Find an instance of serial port as set in PORT_NAMES.
for (String port : ports) {
System.out.print("Ports: " + port);
serialPort = new SerialPort(port);
}
if (serialPort == null) {
System.out.println("Could not find device.");
return false;
}
//Operation to perform is port is found
try {
// open serial port
if(serialPort.openPort()) {
System.out.println("Connected");
// set port parameters
serialPort.setParams(DATA_RATE,
SerialPort.DATABITS_8,
SerialPort.STOPBITS_1,
SerialPort.PARITY_NONE);
serialPort.setEventsMask(SerialPort.MASK_RXCHAR);
serialPort.addEventListener(event -> {
if(event.isRXCHAR()) {
try {
sb.append(serialPort.readString(event.getEventValue()));
String str = sb.toString();
if(str.endsWith("\r\n")) {
line.set(Long.toString(time.getTime()).concat(":").concat(
str.substring(0, str.indexOf("\r\n"))));
System.out.println("line" + line);
sb = new StringBuilder();
}
} catch (SerialPortException ex) {
Logger.getLogger(SerialComm.class.getName()).log(Level.SEVERE, null, ex); }
}
});
}
} catch (Exception e) {
System.out.println("ErrOr");
e.printStackTrace();
System.err.println(e.toString());
}
return serialPort != null;
}
#Override
public void serialEvent(SerialPortEvent spe) {
throw new UnsupportedOperationException("Not supported yet.");
}
public StringProperty getLine() {
return line;
}
}
Within the try block, I understand the port parameters, but the eventListener is where I am having difficulty. The significance of the stringbuilder is to append data the new data as it is read from the device.
How will I account for the two sensor readings? Would I do that by creating separate data rates to differentiate between the incoming data from each sensor??
I hope that this is clear and that I've provided enough information but not too much. Thank you for any assistance.
-------------------------------UPDATE--------------------------
Since your reply Jose, I've started to make the additions to my code. Adding the listener within the JavaFX class, I'm running into some issues. I keep getting a NullPointerException, which I believe is the String[]data not being initialized by any data from the SerialCommunication class.
serialPort.addEventListener(event -> {
if(event.isRXCHAR()) {
try {
sb.append(serialPort.readString(event.getEventValue()));
String str = sb.toString();
if(str.endsWith("\r\n")) {
line.set(Long.toString(time.getTime()).concat(":").concat(
str.substring(0, str.indexOf("\r\n"))));
System.out.println("line" + line);
sb = new StringBuilder();
}
} catch (SerialPortException ex) {
Logger.getLogger(SerialComm.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
}
} catch (Exception e) {
System.err.println(e.toString());
}
I'm adding the time to the data being read. As Jose mentioned below, I've added tags to the data variables within the arduino code, I'm using: Serial.print("Solar:"); Serial.println(solarData);
Rough code of the JavaFx listener:
serialPort.getLine().addListener((ov, t, t1) -> {
Platform.runLater(()-> {
String [] data = t1.split(":");
try {
//data[0] is the timestamp
//data[1] will contain the label printed by arduino "Solar: data"
switch (data[1]) {
case "Solar":
data[0].replace("Solar:" , "");
solarSeries.getData().add(new XYChart.Data(data[0], data[1]));
break;
case "Temperature":
temperatureSeries.getData().add(new XYChart.Data(data[0], data[1]));
break;
}
Is the reason this code has NullPointerException a result of the String [] data array being uninitialized?
Exception Error
Ports: /dev/tty.usbmodem1411Connected
Exception in thread "EventThread /dev/tty.usbmodem1411" java.lang.NullPointerException
at SerialComm.lambda$connect$0(SerialComm.java:61)
at SerialComm$$Lambda$1/1661773475.serialEvent(Unknown Source)
at jssc.SerialPort$LinuxEventThread.run(SerialPort.java:1299)
The SerialPortEventListener defined in the jssc library allows listening for serial port events. One of those events is the RXCHAR event, that occurs when the Arduino board is sending some data and some bytes are on the input buffer.
event.getEventValue() returns an int with the byte count, and serialPort.readString(event.getEventValue()) get the String format from those bytes.
Note that this method does not return a full line, so you need to listen to carriage return and line feed characters. Once you find "\r\n", you can get the line, and reset the StringBuilder for the next one:
sb.append(serialPort.readString(event.getEventValue()));
String str=sb.toString();
if(str.endsWith("\r\n")){
line.set(str.substring(0,str.indexOf("\r\n")));
sb=new StringBuilder();
}
where line is an observable String:
final StringProperty line=new SimpleStringProperty("");
On the Arduino side, if you want to send values from different sensors at different rates, I suggest you define on the Arduino sketch some identification string for each sensor, and you print for each value the id of its sensor.
For instance, these will be the readings you will get with the serial event listener:
ID1,val1
ID1,val2
ID2,val3
ID1,val4
ID3,val5
...
Finally, on the JavaFX thread, define a listener to changes in line and process the String to get the sensor and the value. Something like this:
serial.getLine().addListener(
(ObservableValue<? extends String> observable, String oldValue, String newValue) -> {
Platform.runLater(()->{
String[] data=newValue.split("\\,");
if(data[0].equals("ID1"){
// add to chart from sensor 1, value data[1];
} else if(data[0].equals("ID2"){
// add to chart from sensor 2, value data[1];
} else if(data[0].equals("ID3"){
// add to chart from sensor 3, value data[1];
}
});
});
Note you need to add Platform.runLater(), since the thread that gets the data from serial port and updates line is not on the JavaFX thread.
From my experience, on the Arduino side, add a comma or something to separate the different values when you print and when you receive that string in Java simply split that string by commas.
String[] stringSeparate = str.split(",");

Getting IOException with HttpURLConnection.setChunkedStreamingMode()

I've written HttpUrlConnection wrapper. It supports file uploading, so I'm using HttpUrlConnection.setChunkedStreamingMode() to prevent OutOfMemoryException.
But after writing all data to OutputStream I getting IOException. Without this method everything works fine.
Here the code:
HttpURLConnection connection = getConnection();
if(!isSent) {
OutputStream output;
if(!files.isEmpty()) {
connection.setRequestProperty(HEADER_CONTENT_TYPE, CONTENT_TYPE_MULTIPART);
// Tried to add this line, but still not working
connection.setRequestProperty("Transfer-Encoding","chunked");
connection.setChunkedStreamingMode(chunkSize);
output = new BufferedOutputStream(connection.getOutputStream());
writeParamsMultipart(output);
writeFilesMultipart(output);
output.write((PREFIX + BOUNDARY + PREFIX + LINEND).getBytes());
} else {
connection.setRequestProperty(HEADER_CONTENT_TYPE, CONTENT_TYPE_FORM);
output = new BufferedOutputStream(connection.getOutputStream());
output.write(paramsToUrlencoded(post).getBytes());
}
output.flush();
output.close();
isSent = true;
}
// Getting exception on this line
InputStream input = new BufferedInputStream(connection.getInputStream());
if(ENCODING_GZIP.equalsIgnoreCase(connection.getHeaderField(HEADER_CONTENT_ENCODING))) {
input = new GZIPInputStream(input);
}
return input;
chunkSize by default 1024 bytes. What's the problem?
It's FileNotFoundException
That means that the URL is incorrect. It's the equivalent of HTTP 403.
Nothing to do with chunked transfer mode.

Trimming 0x00 in received DatagramPacket

In my Java app I receive DatagramPacket(s) through DatagramSocket. I know the maximum number of bytes which packet could contain, but actually every packet length varies (not exceeding max length).
Let's assume that MAX_PACKET_LENGTH = 1024 (bytes). So every time DatagramPacket is received it is 1024 bytes long, but not always all bytes contains information. It may happen that packet has 10 bytes of useful data, and the rest of 1014 bytes is filled with 0x00.
I am wondering if there is any elegant way to trim this 0x00 (unused) bytes in order to pass to the other layer only useful data? (maybe some java native methods? going in a loop and analysing what packet contains is not desired solution :))
Thanks for all hints.
Piotr
You can call getLength on the DatagramPacket to return the ACTUAL length of the packet, which may be less than MAX_PACKET_LENGTH.
This is too late for the question but, could be useful for person like me.
private int bufferSize = 1024;
/**
* Sending the reply.
*/
public void sendReply() {
DatagramPacket qPacket = null;
DatagramPacket reply = null;
int port = 8002;
try {
// Send reply.
if (qPacket != null) {
byte[] tmpBuffer = new byte[bufferSize];
System.arraycopy(buffer, 0, tmpBuffer, 0, bufferSize);
reply = new DatagramPacket(tmpBuffer, tmpBuffer.length,
qPacket.getAddress(), port);
socket.send(reply);
}
} catch (Exception e) {
logger.error(" Could not able to recieve packet."
+ e.fillInStackTrace());
}
}
/**
* Receives the UDP ping request.
*/
public void recievePacket() {
DatagramPacket dPacket = null;
byte[] buf = new byte[bufferSize];
try {
while (true) {
dPacket = new DatagramPacket(buf, buf.length);
socket.receive(dPacket);
// This is a global variable.
bufferSize = dPacket.getLength();
sendReply();
}
} catch (Exception e) {
logger.error(" Could not able to recieve packet." + e.fillInStackTrace());
} finally {
if (socket != null)
socket.close();
}
}

Resources