saving a string array to a file error - android

How to format directory in android project folder as jvm can't see datass.txt or sometimes logcat says read only file...(i am putting datass.txt in main project root)
i am passing an array of strings and want to save it to a file datass.txt so i can retrieve data when internet is not connected
public void FileWrite(String[] temp) throws IOException{
File m = new File("datass.txt");
final String[] descs = temp ;
DataOutputStream out = new DataOutputStream(new
BufferedOutputStream(
new FileOutputStream(m)));
for (int i = 0; i < 31; i ++) {
out.writeUTF(descs[i]);
}
}

You need to add File Writing Permission in your AndroidManiFest.xml file.
android.permission.WRITE_EXTERNAL_STORAGE
Please visit this link for various other permission set.

it seems that you could a Index out of bound exception i am not sure but to guard your self change the for loop header to this
for(int i =0; i < descs.length ; ++i)

Related

jsPDF within Cordova / Phonegap - Impossible to add images

I have a problem,
I'm trying to add images in my pdf with jsPDF. b64Tab is an array containing the base64 data of my jpg images that i want to add.
After the
doc.output();
The different pages are created with the text added, but the images are not displayed. I test this on a 4.2.2 Android phone.
Here is a piece of code :
for (var j = 0; j < b64Tab.length; j++) {
doc.addPage();
doc.setFontSize(22);
doc.text(130, 65, descriptions[j]);
doc.addImage(b64Tab[j], 'JPEG', 40, 100, 500, 500);
}
I'm using the latest jsPDF's build.
Any help would be welcomed.
Thanks.
If you are not using File plugin then replace pdf output with doc.output("blob");
If you are using File plugin then create a buffer to write on the file eg.
var data = getPDFFile();
var buffer = new ArrayBuffer(data.length);
var array = new Uint8Array(buffer);
for (var i = 0; i < data.length; i++) {
array[i] = data.charCodeAt(i);
}
writer.write(buffer); // here you write on file using File plugin

Encoding issue on Kit Kat / Android when saving and reading a webview

I have noticed that for Android 4.4 handsets, saving a webview with:
webview.saveWebArchive(name);
and reading it after with WebArchiveReader WebArchiveReader (see code below) throws an Encoding Exception:
11-08 15:10:31.976: W/System.err(2240): org.xml.sax.SAXParseException: Unexpected end of document
11-08 15:10:31.976: W/System.err(2240): at org.apache.harmony.xml.parsers.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:125)
The method used to read the stored XML file worked perfectly fine until 4.3 and it is (NOTE: I tried to parse it in two different ways):
public boolean readWebArchive(InputStream is) {
DocumentBuilderFactory builderFactory =
DocumentBuilderFactory.newInstance();
DocumentBuilder builder = null;
myDoc = null;
try {
builder = builderFactory.newDocumentBuilder();
} catch (ParserConfigurationException e) {
e.printStackTrace();
}
try {
//New attempt
InputSource input = new InputSource(is);
input.setEncoding("UTF-8");
myDoc = builder.parse(input);
//This used to be the way it used to work for
//Android 4.3 and below without trouble
//myDoc = builder.parse(is);
NodeList nl = myDoc.getElementsByTagName("url");
for (int i = 0; i < nl.getLength(); i++) {
Node nd = nl.item(i);
if(nd instanceof Element) {
Element el = (Element) nd;
// siblings of el (url) are: mimeType, textEncoding, frameName, data
NodeList nodes = el.getChildNodes();
for (int j = 0; j < nodes.getLength(); j++) {
Node node = nodes.item(j);
if (node instanceof Text) {
String dt = ((Text)node).getData();
byte[] b = Base64.decode(dt, Base64.DEFAULT);
dt = new String(b);
urlList.add(dt);
urlNodes.add((Element) el.getParentNode());
}
}
}
}
} catch (SAXParseException se){
//Some problems parsing the saved XML file
se.printStackTrace();
myDoc = null;
} catch (Exception e) {
e.printStackTrace();
myDoc = null;
}
return myDoc != null;
}
I've played a bit with the way the buider is invoked. Instead of giving it a FileInputStream, I first create an InputSource as you can see to force a given encoding. However, I had no success. By not including the InputSource, the exception was instead:
org.xml.SAXParseException: Unexpected token
I've read in previous posts that this may be an encoding issue (e.g. android-utf-8-file-parsing) but none of the proposed solutions worked for me.
Does anyone else have the same issue or does anyone know what has changed on Kit Kat, and if so, how could it be avoided?
Many thanks in advance
My WebArchiveReader code is not needed under Android 4.4 KitKat and newer to read back a saved web archive. If you save your page with webview.saveWebArchive(name); method on KitKat, you get an MHTML formatted file, as "#Dragon warrior" indicates above. To read this file back into webview, just use:
webView.loadUrl("file:///my_folder/mySavedPage.mht");
Just make sure to give your file the .mht or .mhtml extension, so that WebView recognizes its contents. Otherwise it may just display the MHTML code in text format.
Greg
I have the exactly same problem as you do.
Apparently, Android 4.4 WebView saves web archives as MHTML. Therefore, you can't use WebArchiveReader anymore.
You might want to parse MHTML files with some other 3rd party lib. Good luck!

Get External SDCard Location in Android

I have an app with huge data pre-stored in the SD Card.
We are supporting all tablets ICS onwards. I am not able to find a way to access the SDCard location correctly on ALL devices.
I looked at various solutions given here on SO but they do not seem to work in all cases. Looking for a generic solution.
Even if anyone can tell me all the possible mount points of SDCard.
I am targeting android tablets only if that can narrow down the solution.
Unfortunately this is a common problem due to the fact that Android devices are highly fragmented. Environment.getExternalStorageDirectory() refers to whatever the device manufacturer considers to be "external storage". On some devices, this is removable media, like an SD card. On some devices, this is a portion of on-device flash.(http://developer.android.com/reference/android/os/Environment.html#getExternalStorageDirectory()) Here, "external storage" means "the drive accessible via USB Mass Storage mode when mounted on a host machine".
If a device manufacturer has elected to have external storage be on-board flash and also has an SD card, you will need to contact that manufacturer to determine whether or not you can use the SD card. For most conforming android devices(known ones from google compliance list) the Environment.getExternalStorageDirectory() should work. Or you could write a custom storage class that looks at the mount points and gives you the right path to the mounted SDCard. This is something I've implemented and it has worked so far.
public class StorageOptions {
private static ArrayList<String> mMounts = new ArrayList<String>();
private static ArrayList<String> mVold = new ArrayList<String>();
public static String[] labels;
public static String[] paths;
public static int count = 0;
private static final String TAG = StorageOptions.class.getSimpleName();
public static void determineStorageOptions() {
readMountsFile();
readVoldFile();
compareMountsWithVold();
testAndCleanMountsList();
setProperties();
}
private static void readMountsFile() {
/*
* Scan the /proc/mounts file and look for lines like this:
* /dev/block/vold/179:1 /mnt/sdcard vfat
* rw,dirsync,nosuid,nodev,noexec,
* relatime,uid=1000,gid=1015,fmask=0602,dmask
* =0602,allow_utime=0020,codepage
* =cp437,iocharset=iso8859-1,shortname=mixed,utf8,errors=remount-ro 0 0
*
* When one is found, split it into its elements and then pull out the
* path to the that mount point and add it to the arraylist
*/
// some mount files don't list the default
// path first, so we add it here to
// ensure that it is first in our list
mMounts.add("/mnt/sdcard");
try {
Scanner scanner = new Scanner(new File("/proc/mounts"));
while (scanner.hasNext()) {
String line = scanner.nextLine();
if (line.startsWith("/dev/block/vold/")) {
String[] lineElements = line.split(" ");
String element = lineElements[1];
// don't add the default mount path
// it's already in the list.
if (!element.equals("/mnt/sdcard"))
mMounts.add(element);
}
}
} catch (Exception e) {
// Auto-generated catch block
e.printStackTrace();
}
}
private static void readVoldFile() {
/*
* Scan the /system/etc/vold.fstab file and look for lines like this:
* dev_mount sdcard /mnt/sdcard 1
* /devices/platform/s3c-sdhci.0/mmc_host/mmc0
*
* When one is found, split it into its elements and then pull out the
* path to the that mount point and add it to the arraylist
*/
// some devices are missing the vold file entirely
// so we add a path here to make sure the list always
// includes the path to the first sdcard, whether real
// or emulated.
mVold.add("/mnt/sdcard");
try {
Scanner scanner = new Scanner(new File("/system/etc/vold.fstab"));
while (scanner.hasNext()) {
String line = scanner.nextLine();
if (line.startsWith("dev_mount")) {
String[] lineElements = line.split(" ");
String element = lineElements[2];
if (element.contains(":"))
element = element.substring(0, element.indexOf(":"));
// don't add the default vold path
// it's already in the list.
if (!element.equals("/mnt/sdcard"))
mVold.add(element);
}
}
} catch (Exception e) {
// Auto-generated catch block
e.printStackTrace();
}
}
private static void compareMountsWithVold() {
/*
* Sometimes the two lists of mount points will be different. We only
* want those mount points that are in both list.
*
* Compare the two lists together and remove items that are not in both
* lists.
*/
for (int i = 0; i < mMounts.size(); i++) {
String mount = mMounts.get(i);
if (!mVold.contains(mount))
mMounts.remove(i--);
}
// don't need this anymore, clear the vold list to reduce memory
// use and to prepare it for the next time it's needed.
mVold.clear();
}
private static void testAndCleanMountsList() {
/*
* Now that we have a cleaned list of mount paths Test each one to make
* sure it's a valid and available path. If it is not, remove it from
* the list.
*/
for (int i = 0; i < mMounts.size(); i++) {
String mount = mMounts.get(i);
File root = new File(mount);
if (!root.exists() || !root.isDirectory() || !root.canWrite())
mMounts.remove(i--);
}
}
#SuppressWarnings("unchecked")
private static void setProperties() {
/*
* At this point all the paths in the list should be valid. Build the
* public properties.
*/
Constants.mMounts = new ArrayList<String>();
ArrayList<String> mLabels = new ArrayList<String>();
int j = 0;
if (mMounts.size() > 0) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.GINGERBREAD)
mLabels.add("Auto");
else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
if (Environment.isExternalStorageRemovable()) {
mLabels.add("External SD Card 1");
j = 1;
} else
mLabels.add("Internal Storage");
} else {
if (!Environment.isExternalStorageRemovable()
|| Environment.isExternalStorageEmulated())
mLabels.add("Internal Storage");
else {
mLabels.add("External SD Card 1");
j = 1;
}
}
if (mMounts.size() > 1) {
for (int i = 1; i < mMounts.size(); i++) {
mLabels.add("External SD Card " + (i + j));
}
}
}
labels = new String[mLabels.size()];
mLabels.toArray(labels);
paths = new String[mMounts.size()];
mMounts.toArray(paths);
Constants.mMounts = (ArrayList<String>) mMounts.clone();
Constants.mLabels = (ArrayList<String>) mLabels.clone();
count = Math.min(labels.length, paths.length);
// don't need this anymore, clear the mounts list to reduce memory
// use and to prepare it for the next time it's needed.
mMounts.clear();
}
}
I found this off of a similar question from SO, that I dont have the link to unfortunately, but it s there on probably Sony's Android developer site(no links there either unfortunately). Wagic - a C++ game engine library implements the same and their code is here: http://wagic.googlecode.com/svn-history/r4300/trunk/projects/mtg/Android/src/net/wagic/utils/StorageOptions.java
so you could look at the implementation. I wish someone from Google can answer this question and provide a single way that reads the SDcard mount point from all Android devices
Its not simple as you are thinking,
String f = Environment.getExternalStorageDirectory().getAbsolutePath();
Log.v("TAG",f);//to print the path of sdcard
It returns device storage path not an external sdcard path.
If you are trying to get the path to the SD card use this code
String baseDir = Environment.getExternalStorageDirectory().getAbsolutePath();
Then use this to get the path of the specific folder/file
String path = baseDir + "/your folder(s)/" + fileName;
Its simple.
String f = Environment.getExternalStorageDirectory().getAbsolutePath();
Log.v("TAG",f);//to print the path of sdcard
if you want to access a file then.
String f = Environment.getExternalStorageDirectory()+"/file.ext";
Log.v("TAG",f);//to print the path of file in Logcat.

java.io.IOException: Un-terminated quoted field at end of CSV line

I have a CSV file(written in german language) and I m parsing it in my code.
CSVParser newLineParser = new CSVParser('\n');
try {
String[] points = newLineParser.parseLine(csv);
CSVParser commaParser = new CSVParser();
int pointsLength = points.length;
for (int i = 1; i < pointsLength; i++) {
String[] pointComponents = commaParser.parseLine(points[i]);
}
}
catch (Exception e) {
Log.e("Exception", e.getMessage());
}
I am getting error in the parseLine method as:
java.io.IOException: Un-terminated quoted field at end of CSV line
what may be the reason for this error?
What I get from this is that in your CSV file a quote is opened but isn't closed.
malformed csv file
do some printouts in your loop, to see what happens before the program blows up.
If you are using OpenCSV API then this could be the problem:
Issue: One or more value in the csv file have multiple lines.
Fix: Use commaParser.parseLineMulti(points[i]) instead.
Source: Http://opencsv.sourceforge.net/apidocs/com/opencsv/CSVParser.html#parseLineMulti(java.lang.String)

Using DOM parser in Android

I'm using the DOM parser to retrive information from a XML file that looks like this:
<data>
<metData>
<wantedInformation>
</metData>
<metData>
<Information>
</metData>
<metData>
<Information>
</metData>
<data>
The problem is because I don't know how to parse only the first part of <metData>. I don't need the second and the third part, but the parser displays them anyway.
The xml file is from a weather forcast site:
http://www.meteo.si/uploads/probase/www/fproduct/text/sl/fcast_SLOVENIA_MIDDLE_latest.xml
and I need just the following line: <nn_shortText>oblačno</nn_shortText>
Pls take care whether your XML file is well formed or not,
You have to the notice three methods which i had shown below, they are
1. getElementsByTagName - Mention the tag which you want to parse
2.getChildNodes - retervies the child node
3.getNodeValue()- with the help of this method you can access the
value of particular tag
Step 1: Create a Method to parse _Information_Value ,inorder to parse the data of Information tag
String[] infoId=null;
public void parse_Information_Value() throws UnknownHostException{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
try {
DocumentBuilder builder = factory.newDocumentBuilder();
Document dom = builder.parse(this.getInputStream());
org.w3c.dom.Element root = dom.getDocumentElement();
NodeList items = root.getElementsByTagName("metData");
int a=items.getLength();
int k=0;
for (int i = 0; i < items.getLength(); i++) {
Message_category message = new Message_category();
Node item = items.item(i);
NodeList properties = item.getChildNodes();
for (int j = 0; j < properties.getLength(); j++) {
Node property = properties.item(j);
String name = property.getNodeName();
if (name.equalsIgnoreCase("wantedInformation")) {
message.setId(property.getFirstChild()
.getNodeValue());
infoId[k]=property.getFirstChild().getNodeValue();
k++;
}
}
}
} catch (Exception e) { }
}
Depending on the size of your document, you may also want to use at a streaming oriented parser like SAX or Stax, which does not pull the whole document into memory and thus needs less memory than DOM.
Good thing is that SAX is already built into Android, so you can use it right away.
See this link for a usage example.

Categories

Resources