I know this question has been asked before, but I can't make it to work. Please help. I added the external storage permission, why is it still read-only?
public class MainActivity extends Activity {
public static final String LOGTAG="EXPLORECA";
public static final String USERNAME="pref_username";
public static final String VIEWIMAGE="pref_viewimages";
private SharedPreferences settings;
private OnSharedPreferenceChangeListener listener;
private File file;
private static final String FILENAME = "jasondata";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
settings = PreferenceManager.getDefaultSharedPreferences(this);
listener = new OnSharedPreferenceChangeListener() {
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
String key) {
MainActivity.this.refreshDisplay(null);
}
};
settings.registerOnSharedPreferenceChangeListener(listener);
File extDir = getExternalFilesDir(null);
String path = extDir.getAbsolutePath();
UIHelper.displayText(this, R.id.textView, path);
file = new File(extDir,FILENAME);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
public void setPreference(View v) {
Log.i(LOGTAG, "Clicked set");
Intent intent = new Intent(this, UIHelper.class);
startActivity(intent);
}
public void refreshDisplay(View v) {
Log.i(LOGTAG, "Clicked show");
String prefValue = settings.getString(USERNAME, "Not found");
UIHelper.displayText(this, R.id.textView, prefValue);
}
public void createFile(View v) throws IOException, JSONException {
if(!checkExternalStorage())
{
return;
}
JSONArray data = getNewJSONData();
String text = data.toString();
try{
FileOutputStream fos = new FileOutputStream("tours");
fos.write(text.getBytes());
fos.close();
UIHelper.displayText(this, R.id.textView, "File written to disk:\n" + data.toString());
}
catch (IOException e) {
e.printStackTrace();
UIHelper.displayText(this, R.id.textView, e.toString());
}
}
public void readFile(View v) throws IOException, JSONException {
FileInputStream fis = new FileInputStream("tours");
BufferedInputStream bis = new BufferedInputStream(fis);
StringBuffer b = new StringBuffer();
while (bis.available() != 0) {
char c = (char) bis.read();
b.append(c);
}
bis.close();
fis.close();
JSONArray data = new JSONArray(b.toString());
StringBuffer toursBuffer = new StringBuffer();
for (int i = 0; i < data.length(); i++) {
String tour = data.getJSONObject(i).getString("tours");
toursBuffer.append(tour + "\n");
}
UIHelper.displayText(this, R.id.textView, toursBuffer.toString());
}
private JSONArray getNewJSONData() throws JSONException {
JSONArray data = new JSONArray();
JSONObject tour;
tour = new JSONObject();
tour.put("tour", "Salton Sea");
tour.put("price", 900);
data.put(tour);
tour = new JSONObject();
tour.put("tour", "Death Valley");
tour.put("price", 600);
data.put(tour);
tour = new JSONObject();
tour.put("tour", "San Francisco");
tour.put("price", 1200);
data.put(tour);
return data;
}
public boolean checkExternalStorage()
{
String state = Environment.getExternalStorageState();
if (state.equals(Environment.MEDIA_MOUNTED))
{
return true;
}
else if (state.equals(Environment.MEDIA_MOUNTED_READ_ONLY))
{
UIHelper.displayText(this, R.id.textView,"read-only");
}
else
{
UIHelper.displayText(this, R.id.textView,"unavailable");
}
return false;
}
Main Activity XML
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/editText"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true" />
<Button
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Create File"
android:id="@+id/createFile"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginBottom="92dp"
android:onClick="createFile"/>
<Button
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Read File"
android:id="@+id/readFile"
android:layout_alignTop="@+id/createFile"
android:layout_centerHorizontal="true"
android:onClick="readFile"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Command"
android:textSize="10sp"
android:id="@+id/textView"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_below="@+id/readFile"
android:layout_alignRight="@+id/editText"
android:layout_alignEnd="@+id/editText" />
UIHelper Java class package claudiu.externalstorage;
import android.app.Activity;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.TextView;
public class UIHelper {
public static void displayText(Activity activity, int id, String text) {
TextView tv = (TextView) activity.findViewById(id);
tv.setText(text);
}
public static String getText(Activity activity, int id) {
EditText et = (EditText) activity.findViewById(id);
return et.getText().toString();
}
public static boolean getCBChecked(Activity activity, int id) {
CheckBox cb = (CheckBox) activity.findViewById(id);
return cb.isChecked();
}
public static void setCBChecked(Activity activity, int id, boolean value) {
CheckBox cb = (CheckBox) activity.findViewById(id);
cb.setChecked(value);
}
Manifest
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Logcat trace
9318-9318/? W/System.err﹕ at libcore.io.IoBridge.open(IoBridge.java:409)
9318-9318/? W/System.err﹕ java.io.FileNotFoundException: /tours: open failed: EROFS (Read-only file system)
9318-9318/? W/System.err﹕ at java.io.FileOutputStream.<init>(FileOutputStream.java:88)
9318-9318/? W/System.err﹕ at java.io.FileOutputStream.<init>(FileOutputStream.java:128)
9318-9318/? W/System.err﹕ at java.io.FileOutputStream.<init>(FileOutputStream.java:117)
9318-9318/? W/System.err﹕ at claudiu.externalstorage.MainActivity.createFile(MainActivity.java:93)
9318-9318/? W/System.err﹕ at java.lang.reflect.Method.invokeNative(Native Method)
9318-9318/? W/System.err﹕ at java.lang.reflect.Method.invoke(Method.java:515)
9318-9318/? W/System.err﹕ at android.view.View$1.onClick(View.java:3991)
9318-9318/? W/System.err﹕ at android.view.View.performClick(View.java:4748)
9318-9318/? W/System.err﹕ at android.view.View$PerformClick.run(View.java:19535)
9318-9318/? W/System.err﹕ at android.os.Handler.handleCallback(Handler.java:733)
9318-9318/? W/System.err﹕ at android.os.Handler.dispatchMessage(Handler.java:95)
9318-9318/? W/System.err﹕ at android.os.Looper.loop(Looper.java:146)
9318-9318/? W/System.err﹕ at android.app.ActivityThread.main(ActivityThread.java:5679)
9318-9318/? W/System.err﹕ at java.lang.reflect.Method.invokeNative(Native Method)
9318-9318/? W/System.err﹕ at java.lang.reflect.Method.invoke(Method.java:515)
9318-9318/? W/System.err﹕ at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1291)
9318-9318/? W/System.err﹕ at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1107)
9318-9318/? W/System.err﹕ at dalvik.system.NativeStart.main(Native Method)
9318-9318/? W/System.err﹕ Caused by: libcore.io.ErrnoException: open failed: EROFS (Read-only file system)
9318-9318/? W/System.err﹕ at libcore.io.Posix.open(Native Method)
9318-9318/? W/System.err﹕ at libcore.io.BlockGuardOs.open(BlockGuardOs.java:110)
9318-9318/? W/System.err﹕ at libcore.io.IoBridge.open(IoBridge.java:393)
9318-9318/? W/System.err﹕ ... 18 more
FileOutputStream fos = new FileOutputStream("tours");
This is not pointing anywhere that you can read or write. Always use a method to get at the base locations where you can read and write.
If you are looking to write to internal storage, change this to be something like:
FileOutputStream fos = new FileOutputStream(new File(getFilesDir(), "tours"));
If you are looking to write to external storage, change this to be something like:
FileOutputStream fos = new FileOutputStream(new File(getExternalFilesDir(null), "tours"));