0

I am read & write username & password to android device using my application to internal storage. I am successful writing to the device, but while reading I get error. On start of the aplication I read that file and I get "The applicaton (...) has stopped unexpectedly. Please try again." with "Force Close" button and the app closes. I tried different ways to read, but all showed same results. I write my data as username + "\n" + passwrd + "\n". This is the code for reading data :

    private static String ReadFromFile(String fileName) {
    String text = "";
    FileInputStream fis = null;
    byte[] fileData;
    try {
        StringBuffer sb = new StringBuffer();
        int c = 0;
        fis = AppContext.openFileInput(fileName);
        if (fis.available() != 0) {
            fileData = new byte[fis.available()];
            c = fis.read(fileData);
            Log.i(TAG, "Read Byes = " + c );
            java.util.StringTokenizer stk = new java.util.StringTokenizer(new String(fileData), "\n");
            text = stk.toString();
        } else 
            throw new IOException("fis.available() <= 0");          /*
        c = (char)fis.read();
        while (c != -1){
            if (c != -1)
                sb.append(c);
            c = (char)fis.read();
        }
        text = sb.toString();
        */
        fis.close();            
    } catch (FileNotFoundException e) {
        text = "null " +  e.getMessage();
    } catch (IOException e) {
        text = "null " + e.getMessage();
    } finally {
        fis = null;
    }   
    return text;
}

    /*
    try {
        StringBuffer sb = new StringBuffer();
        RandomAccessFile raf = new RandomAccessFile(ENC_LOGIN_FILE, "r");
        while ((str1 = raf.readLine()) != null){
            sb.append(str1);
        }
        str1 = sb.toString();
    } catch (FileNotFoundException e) {
        errorMessage = "File Not Found: " + e.getMessage();
        //e.printStackTrace();
    } catch (IOException ioe) {
        errorMessage = "IOExcp: " + ioe.getMessage();
        //e.printStackTrace();
    }*/

No path is used and the filename directly is given to write & read file. I checked out Problem facing in reading file from Internal memory of android from where I tried StringTokenizer.

Can anyone help me know where am I going wrong. The following permission are set :

    <uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS"></uses-permission>
<uses-permission android:name="android.permission.WRITE_SETTINGS"></uses-permission>
<uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS"></uses-permission>
<uses-permission android:name="android.permission.READ_SYNC_SETTINGS"></uses-permission>    
<uses-permission android:name="android.permission.READ_SYNC_STATS"></uses-permission>
<uses-permission android:name="android.permission.READ_LOGS"></uses-permission>

Also how do I debug the application. How to check the data written in Log. If I use SOP, where does it dispaly - it doesn't display in Console window ? Please help me, I am n newbie in android development. One more thing to clarify : My motto is to store username and password in such a way that user must not be able to read them directly. I have already used MODE_PRIMITIVE. Is their a need to use JSONObject to save this data. I had a look at JSON in couple of sites & API but couldn't make out why and where it should be used. Using MODE_PRIMITIVE I believe even the user can't read the file. Only my application can read it. Then I don't think I should use JSON. Please correct me if I am wrong.

Any help is highly appreciated.

Thanks.

Community
  • 1
  • 1
Tvd
  • 4,463
  • 18
  • 79
  • 125

2 Answers2

1

A suggestion:

If you are only saving username and password then use SharedPreferences instead of saving the data in a file. It is a much secure way and plus very hassle free.

Use this blog article on How to use Shared Preferences:

http://saigeethamn.blogspot.com/2009/10/shared-preferences-android-developer.html

mudit
  • 25,306
  • 32
  • 90
  • 132
  • Thanks for this info. But by using SharedPreferences, my data or atleast application name (if I use MODE_PRIMITIVE) will be seen in whole device ? Like in a demo, where I see Corporate, will I see my application name also ? Or no one will be able to see the name also. – Tvd Apr 04 '11 at 10:24
  • I tried to open "Google LoginSErvice" from "DEv Tools" and I get the same exception as for my application. Is there any problem with reading from file from emulator ? Google Login alos might be using the same logic like I am for reading data from file. I use SDK 2.3.3 API 10 emulator. Any idea with this ? – Tvd Apr 04 '11 at 10:33
  • Only your app name will be visible like other apps. Plus rather then using MODE_PRIMITIVE you can use MODE_PRIVATE. sharedPreferences = getPreferences(MODE_PRIVATE); – mudit Apr 04 '11 at 10:40
  • Ok. If I want to add more key/pair values later in my app, I can do it or not? Like later will have to add 4-5 more values. I guess I will be able to add more data in any other part of the application? Y/N ? – Tvd Apr 04 '11 at 10:55
  • Yes, you can always add more key value pairs but with a unique key. – mudit Apr 04 '11 at 11:07
  • Thanks mudit for your guidance. – Tvd Apr 04 '11 at 11:13
  • How I edit the values once set ? Like, SharedPreferences.Editor prefsEditor = myPrefs.edit(); prefsEditor.putString("Login", ""); prefsEditor.putString("UserName", ld.getUserName()); prefsEditor.putString("Password", ld.getPassword()); I have set username & Password. I can retrieve it using getString("UserName"); BUT how do I edit it - I want to change the value of password on Change Password. Do i have to work the same way i.e. call myPrefs.edit & use putString("Password", newValue) ???? – Tvd Apr 04 '11 at 11:35
  • Yes. you can use same method. – mudit Apr 04 '11 at 11:37
  • Thanks alot mudit. Is it safe to add approx 10-15 keys. And can I delete it when I uninstall the app or when I want to ? – Tvd Apr 04 '11 at 11:45
  • It will get deleted when you uninstall the app, and you can store any number of pairs. But you should store only imp ones. – mudit Apr 04 '11 at 11:50
  • For others I need to save in file only and there where I am stuck. Thanks a lot for this. – Tvd Apr 04 '11 at 12:19
  • there is no such limit that you can only store 5 or 10 pairs in the sharedprefs. you can always store any number of pairs. – mudit Apr 04 '11 at 12:24
0
fis = AppContext.openFileInput(fileName);
fileData = new byte[fis.available()];
java.util.StringTokenizer stk =
    new java.util.StringTokenizer(new String(fileData), "\n");

It appears to me that you're trying to create a new String using an uninitialized array as input. You've asked for the array to be a specific size, but you haven't done anything to read data into the array. (Note that available() only asks for the size of the data that can be read without blocking; it doesn't actually read the data. For that you need the read() method.)

Try this:

fis = AppContext.openFileInput(fileName);
fileData = new byte[fis.available()];
fis.read(fileData);
java.util.StringTokenizer stk =
    new java.util.StringTokenizer(new String(fileData), "\n");

You should check the return value of fis.read(), but give this a try to see if it lets you progress further.

sarnold
  • 102,305
  • 22
  • 181
  • 238
  • Thanks. Such a silly mistake. But that also failed. I changed, inside if(fis.availalbe() != 0), I added c = fis.read(fileData); Initialized stringTokenizer with fileData and text = stk.toString(). In the else part of is(fis.available...) I throw an exception. Either exception should be caught or message should have something or null, but same error message on start of app "App has stopped unexpectedly" & "Force Close" button. How di I check the logs "Log.i" or SOP tok now where & what is going wrong? – Tvd Apr 04 '11 at 09:25
  • @user455979, I suggest editing the post to include my suggestions, maybe someone else will know the rest. Good luck. :) – sarnold Apr 04 '11 at 09:32