How to read/write a string encoded with android.util.Base64 - android

I would like to store some strings in a simple .txt file and then read them, but when I want to encode them using Base64 it doesn't work anymore: it writes well but the reading doesn't work. ^^
The write method:
private void write() throws IOException {
String fileName = "/mnt/sdcard/test.txt";
File myFile = new File(fileName);
BufferedWriter bW = new BufferedWriter(new FileWriter(myFile, true));
// Write the string to the file
String test = "http://google.fr";
test = Base64.encodeToString(test.getBytes(), Base64.DEFAULT);
bW.write("here it comes");
bW.write(";");
bW.write(test);
bW.write(";");
bW.write("done");
bW.write("\r\n");
// save and close
bW.flush();
bW.close();
}
The read method :
private void read() throws IOException {
String fileName = "/mnt/sdcard/test.txt";
File myFile = new File(fileName);
FileInputStream fIn = new FileInputStream(myFile);
BufferedReader inBuff = new BufferedReader(new InputStreamReader(fIn));
String line = inBuff.readLine();
int i = 0;
ArrayList<List<String>> matrice_full = new ArrayList<List<String>>();
while (line != null) {
matrice_full.add(new ArrayList<String>());
String[] tokens = line.split(";");
String decode = tokens[1];
decode = new String(Base64.decode(decode, Base64.DEFAULT));
matrice_full.get(i).add(tokens[0]);
matrice_full.get(i).add(tokens[1]);
matrice_full.get(i).add(tokens[2]);
line = inBuff.readLine();
i++;
}
inBuff.close();
}
Any ideas why?

You have a couple of errors in your code.
First a couple of notes on your code:
When posting here, attaching a SSCCE helps others to debug your code. This is not a SSCEE because it doesn't compile. It lacks several defined variables, so one must guess what you really mean. Also you have pasted close-comment token in your code: */ but there is no one start-comment token.
Catching and just suppressing exceptions (like in catch-block in read method) is really bad idea unless you really know what you're doing. What it does most of the time is hide the potential problems from you. At least write the stacktrace of an exception is a catch block.
Why don't you just debug it, check what exactly outputs to the destination file? You should learn how to do that because that will speed up your development process, especially for larger projects with hard-to-catch problems.
Back to the solution:
Run the program. It throws an exception:
02-01 17:18:58.171: E/AndroidRuntime(24417): Caused by: java.lang.ArrayIndexOutOfBoundsException
caused by line here:
matrice_full.get(i).add(tokens[2]);
inspecting the variable tokens reveals that it has 2 elements, not 3.
So lets open the file generated by the write method. Doing that shows this output:
here it comes;aHR0cDovL2dvb2dsZS5mcg==
;done
here it comes;aHR0cDovL2dvb2dsZS5mcg==
;done
here it comes;aHR0cDovL2dvb2dsZS5mcg==
;done
Note line breaking here. This is because the Base64.encodeToString() appends additional newline at the end of the encoded string. To generate a one single line, without extra newlines, add Base64.NO_WRAP as the second parameter like this:
test = Base64.encodeToString(test.getBytes(), Base64.NO_WRAP);
Note here, you must delete file that was created earlier as it has improper line breaking.
Run the code again. It now creates a file with the proper contents:
here it comes;aHR0cDovL2dvb2dsZS5mcg==;done
here it comes;aHR0cDovL2dvb2dsZS5mcg==;done
Printing the output of matrice_full now gives:
[
[here it comes, aHR0cDovL2dvb2dsZS5mcg==, done],
[here it comes, aHR0cDovL2dvb2dsZS5mcg==, done]
]
Note that you're not doing anything with the value in decode variable in your code, hence the second element is the Base64 representation of that value which is read from the file.

Related

Load strings.xml from sd card to application android

Is it possible to load strings.xml from sd card instead of application res/values/... Search on the web but didn't find any tutorials. My thought is download the xml to sd card then save the strings element to an array.
public void stringsxml(){
File file = new File(Environment.getExternalStorageDirectory()
+ ".strings.xml");
StringBuilder contents = new StringBuilder();
try {
//use buffering, reading one line at a time
//FileReader always assumes default encoding is OK!
BufferedReader input = new BufferedReader(new FileReader(file));
try {
String line = null; //not declared within while loop
/*
* readLine is a bit quirky :
* it returns the content of a line MINUS the newline.
* it returns null only for the END of the stream.
* it returns an empty String if two newlines appear in a row.
*/
while (( line = input.readLine()) != null){
contents.append(line);
contents.append(System.getProperty("line.separator"));
}
}
finally {
input.close();
}
}
catch (IOException ex){
ex.printStackTrace();
}
String data= contents.toString();
}
Well, actually it is semi-possible, but you have to create a derivate LayoutInflater which will replace string codes with thus read strings.
I have documented my attempts and failings together with initial implementation here.
Summary: simple strings work, string arrays do not
No, this is not possible. Check Android decoumentation about resources:
The Android SDK tools compile your application's resources into the application binary at build time. To use a resource, you must install it correctly in the source tree (inside your project's res/ directory) and build your application.
Resources are built-in into the application binary and you can't read them from a file.

Command Line Jar on Android Device

I currently have a compiled jar file that I would like to use on an android device. The code outputs to the command line using System.out.println().
How would I create a wrapper to grab the stdout and put it in a text view on an android device? Would I need to make any changes to the jar (I do have all the source code) to allow the wrapper?
Thanks in advance.
I think you'll need to make some changes. You can set standart output by calling
System.setOut(PrintStream out)
// Reassigns the "standard" output stream.
Where out is your own class that will print data to text view. See swing solution. Just set appending to text view and you can use this code.
Or just create one method
void log(String message);
where you appending text to your view. Then change all println() calls to this.
First you should consider that Android has a specific Java VM called Dalvik and not any jar can be ran under it.
If there's one point in your jar where output occurs, the best option would be to create a usual application with a TextView, include your jar to it's build path and replace a call to println() with output to it:
public void print(String msg) {
mTextView.setText(msg);
}
If there're many sources of output you could run you jar using java.lang.Process and use it's getInputStream() method to read printed messages:
public static final String XBOOT_CLASS_PATH = "-Xbootclasspath:/system/framework/core.jar"
public static final String CLASS_PATH = "-classpath /path/to/your/file.jar com.your.package.name"
...
Process p = new ProcessBuilder("dalvikvm", XBOOT_CLASS_PATH, CLASS_PATH).start();
BufferedReader reader = new BufferedReader (new InputStreamReader(p.getInputStream()));
String msg = reader.readLine();
if (msg != null) {
mTextView.setText(msg);
}
// Cleanup omitted for simplicity
If it's an executable jar file here is a working example
Add this simple executable HelloWorld jar file to your Android Project's build path
If the jar file doesn't have a package, then you will have to use Reflection to invoke methods in it.Other wise you can just import the class files and invoke the main method directly.(This example jar has a package "psae")
eg:
TextView tv = (TextView)findViewById(R.id.textv);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintStream ps = new PrintStream(baos);
System.setOut(ps);
String[] params = {"Aneesh","Joseph"};
psae.HelloWorld.main(params);
String output = baos.toString();
tv.setText(output)
If the jar file just has a default package, then you won't be able to import class files from that jar, and hence you will have to use Reflection to invoke the method.
TextView tv = (TextView)findViewById(R.id.textv);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintStream ps = new PrintStream(baos);
System.setOut(ps);
try {
//pick the entry class from the jar Manifest
//Main-Class: psae.HelloWorld
Class myClass = Class.forName("psae.HelloWorld");
//since this has a package, there is no need of reflection.This is just an example
//If the jar file had just a default package, the it would have been something like the below line (and this is where it would be useful)
//Class myClass = Class.forName("Main");
Method myMethod = myClass.getMethod("main", String[].class);
//parameters to the main method
String[] params = {"Aneesh","Joseph"};
myMethod.invoke(null, (Object) params);
String output = baos.toString();
tv.setText(output);
}
catch(Exception d)
{
tv.setText(d.toString());
}

Android memory error

I cannot understand why this keeps crashing with a memory error:
server = new URL("http://-link cannot be supplied-");
BufferedReader reader2 = read(server);
line = reader2.readLine();
StringBuilder bigString = new StringBuilder("");
while(line!=null) {
bigString.append(line);
reader2.readLine();
}
the file is not -that- big 7000 odd lines # 240,031 bytes on disk.
Basically what i need to do is to tell wether the file contains a small string (a postcode) the file is basically a list of postcodes.
What is the best way to read this in? as obviously what i am doing is not working at all :D
Your while loop never ends!
while(line!=null) {
bigString.append(line);
line = reader2.readLine();
}
should work.

Problem finding/reading a file

I'm trying to develop a small application, where I was given a JSON file, and I have to extract data from it. As I understood a JSON object takes a string argument, thus I'm trying to access a file and write the data from it to a string.
I've placed that file in a "JSON file" folder, and when I try to read the file, it throws me a file not found exception.
I've tried several ways to find a path to that file, but every attempt was for vain.
It might be that I'm extracting the path wrong, or might be something else, please help me.
Thanks in advance.
here is the code of finding the path:
try
{
path = Environment.getRootDirectory().getCanonicalPath();
}
catch (IOException e)
{
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
File jFile = new File(path + /"JSON file/gallery.json");
here is the code for reading from a file :
String str ="";
try
{
BufferedReader in = new BufferedReader(new FileReader(jFile));
while ((str += in.readLine()) != null)
{
}
in.close();
}
catch (IOException e)
{
e.getMessage();
}
return str;
Here more specification:
I want to take the data from the file in order to do that : JSONObject(jString).
when I extract the path of json file I create a file with the path and pass it to the function that reads from the file, and there it throws me a file not found exception, when I try to read from it.
The file does exists in the folder (even visually - I've tried to attach an image but the site won't let me, because I'm new user)
I've tried to open the file through the windows address bar by typing the path like that:
C:\Users\Marat\IdeaProjects\MyTask\JSON file\gallery.json and it opens it.
if you store it in the assets folder you can access it by using
InputStream is = context.getResources().getAssets().open("sample.json");
You can then convert it to a String
public static String inputStreamAsString(InputStream stream)
throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(stream));
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = br.readLine()) != null) {
sb.append(line + "\n");
}
br.close();
return sb.toString();
}
EDIT
You need to put the file in the device, if it is on your computer, it is not accessible from your device. There are some ways to do that, and one of them is to put it in the res/ dir of your application. Please refer to the documentation to see how to do that.
Debug it. I'm pretty sure it will be very easy to find. To start with, look for the following:
Print the path before you create the file, e.g. Log.d("SomeTag", path + "/JSON file/gallery.json")
Observe the full exception details. Maybe there is another problem.
Explore the folders and see if the file exists (in eclipse: window -> show view -> other -> android -> file explorer.
You will probably observe the problem and be able to fix it. If not, post here a question with more details, including the results of those trials.
BTW, GetgetRootDirectory() returns the root directory of android, that's not what you want (you don't have RW permissions there) you probably want to get the applcation directory, you can see how to get it here, in the question I asked a few month ago. But since you didn't give us those details, it will be hard to help you more then that.

Why are foreign characters not read using inputStream?

I have a text file which contains data I need to preload into a SQLite database. I saved in in res/raw.
I read the whole file using readTxtFromRaw(), then I use the StringTokenizer class to process the file line by line.
However the String returned by readTxtFromRaw does not show foreign characters that are in the file. I need these as some of the text is Spanish or French. Am I missing something?
Code:
String fileCont = new String(readTxtFromRaw(R.raw.wordstext));
StringTokenizer myToken = new StringTokenizer(fileCont , "\t\n\r\f");
The readTxtFromRaw method is:
private String readTxtFromRaw(Integer rawResource) throws IOException
{
InputStream inputStream = mCtx.getResources().openRawResource(rawResource);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
int i = inputStream.read();
while (i != -1)
{
byteArrayOutputStream.write(i);
i = inputStream.read();
}
inputStream.close();
return byteArrayOutputStream.toString();
}
The file was created using Eclipse, and all characters appear fine in Eclipse.
Could this have something to do with Eclipse itself? I set a breakpoint and checked out myToken in the Watch window. I tried to manually replace the weird character for the correct one (for example í, or é), and it would not let me.
Have you checked the several encodings?
what's the encoding of your source file?
what's the encoding of your output stream?
the byteArrayOutputStream.toString() converts according to the platform's default character encoding. So I guess it will strip the foreign characters or convert them in a way that they are not displayed in your output.
Have you already tried to use byteArrayOutputStream.toString(String enc)? Try "UTF-8" or "iso-8859-1" or "UTF-16" for the encoding.

Categories

Resources