diff --git a/app/src/main/java/com/wbrawner/simplemarkdown/EditFragment.java b/app/src/main/java/com/wbrawner/simplemarkdown/EditFragment.java index 2240011..bed4f27 100644 --- a/app/src/main/java/com/wbrawner/simplemarkdown/EditFragment.java +++ b/app/src/main/java/com/wbrawner/simplemarkdown/EditFragment.java @@ -6,8 +6,10 @@ import android.content.Intent; import android.content.IntentFilter; import android.net.Uri; import android.os.Bundle; +import android.os.Environment; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentActivity; import android.support.v4.content.FileProvider; import android.support.v4.content.LocalBroadcastManager; import android.text.Editable; @@ -18,6 +20,7 @@ import android.view.View; import android.view.ViewGroup; import android.view.WindowManager; import android.widget.EditText; +import android.widget.Toast; import java.io.BufferedReader; import java.io.File; @@ -34,11 +37,12 @@ public class EditFragment extends Fragment { public static final String SAVE_ACTION = "com.wbrawner.simplemarkdown.ACTION_SAVE"; public static final String LOAD_ACTION = "com.wbrawner.simplemarkdown.ACTION_LOAD"; private static EditText mMarkdownEditor; + private FileUtils mFileUtils; @BindView(R.id.markdown_edit) EditText markdownEditor; - private Context mContext; + private FragmentActivity mContext; private File mTmpFile; private boolean loadTmpFile = true; @@ -58,6 +62,7 @@ public class EditFragment extends Fragment { filter ); mContext = getActivity(); + mFileUtils = new FileUtils(mContext); } @Override @@ -111,10 +116,16 @@ public class EditFragment extends Fragment { public void save(String data, String filePath) { // TODO: move this to AsyncTask - if (filePath == null) + if (!mFileUtils.isExternalStorageWriteable()) { + mFileUtils.requestWritePermissions(); + return; + } + if (filePath == null) { filePath = MainActivity.getFilePath() + MainActivity.getFileName(); + } FileOutputStream out = null; try { + Log.d(TAG, "File path: " + filePath); File tmpFile = new File(filePath); out = new FileOutputStream(tmpFile); out.write(data.getBytes()); @@ -122,8 +133,11 @@ public class EditFragment extends Fragment { Log.e(TAG, "Error saving temp file:", e); } finally { try { - if (out != null) + if (out != null) { out.close(); + Toast.makeText(mContext, getString(R.string.file_saved, filePath), Toast.LENGTH_SHORT) + .show(); + } } catch (IOException e) { Log.e(TAG, "Error closing write stream", e); } @@ -134,8 +148,8 @@ public class EditFragment extends Fragment { save(data, null); } - public void save(Editable data) { - save(data.toString(), null); + public void save() { + save(mMarkdownEditor.getText().toString(), null); } @Override @@ -157,6 +171,11 @@ public class EditFragment extends Fragment { case SAVE_ACTION: if (intent.hasExtra("fileName")) { String fileName = intent.getStringExtra("fileName"); + if (!fileName.contains("/")) { + fileName = MainActivity.getFilePath() + "/" + fileName; + } + if (!fileName.endsWith(".md")) + fileName += ".md"; save(mMarkdownEditor.getText().toString(), fileName); } break; diff --git a/app/src/main/java/com/wbrawner/simplemarkdown/FileUtils.java b/app/src/main/java/com/wbrawner/simplemarkdown/FileUtils.java new file mode 100644 index 0000000..c6ab284 --- /dev/null +++ b/app/src/main/java/com/wbrawner/simplemarkdown/FileUtils.java @@ -0,0 +1,64 @@ +package com.wbrawner.simplemarkdown; + +import android.Manifest; +import android.app.Activity; +import android.content.pm.PackageManager; +import android.os.Environment; +import android.support.v4.app.ActivityCompat; +import android.support.v4.content.ContextCompat; +import android.support.v7.app.AppCompatActivity; + +/** + * Created by billy on 7/27/2017. + */ + +public class FileUtils { + + public static final int WRITE_PERMISSION_REQUEST = 0; + + private Activity mContext; + + public FileUtils(Activity context) { + mContext = context; + } + + public boolean isExternalStorageWritable() { + String state = Environment.getExternalStorageState(); + if (Environment.MEDIA_MOUNTED.equals(state)) { + return true; + } + return false; + } + + public boolean isExternalStorageReadable() { + String state = Environment.getExternalStorageState(); + if (Environment.MEDIA_MOUNTED.equals(state) || + Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) { + return true; + } + return false; + } + + public boolean isExternalStorageWriteable() { + String state = Environment.getExternalStorageState(); + if (Environment.MEDIA_MOUNTED.equals(state) && checkWritePermission()) { + return true; + } + return false; + } + + public boolean checkWritePermission() { + return (ContextCompat.checkSelfPermission( + mContext, + Manifest.permission.WRITE_EXTERNAL_STORAGE + ) == PackageManager.PERMISSION_GRANTED); + } + + public void requestWritePermissions() { + ActivityCompat.requestPermissions( + mContext, + new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE}, + WRITE_PERMISSION_REQUEST + ); + } +} diff --git a/app/src/main/java/com/wbrawner/simplemarkdown/MainActivity.java b/app/src/main/java/com/wbrawner/simplemarkdown/MainActivity.java index c70a66e..29b1d6d 100644 --- a/app/src/main/java/com/wbrawner/simplemarkdown/MainActivity.java +++ b/app/src/main/java/com/wbrawner/simplemarkdown/MainActivity.java @@ -8,6 +8,8 @@ import android.content.DialogInterface; import android.content.Intent; import android.content.pm.PackageManager; import android.net.Uri; +import android.os.Environment; +import android.support.annotation.Nullable; import android.support.design.widget.TabLayout; import android.support.v4.app.ActivityCompat; import android.support.v4.app.Fragment; @@ -16,14 +18,17 @@ import android.support.v4.app.FragmentPagerAdapter; import android.support.v4.content.ContextCompat; import android.support.v4.content.FileProvider; import android.support.v4.content.LocalBroadcastManager; +import android.support.v4.os.EnvironmentCompat; import android.support.v4.view.ViewPager; import android.support.v7.app.AlertDialog; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; +import android.text.Editable; import android.text.InputType; import android.util.Log; import android.view.Menu; import android.view.MenuItem; +import android.view.SearchEvent; import android.webkit.MimeTypeMap; import android.widget.EditText; import android.widget.Toast; @@ -33,7 +38,8 @@ import java.io.File; import butterknife.BindView; import butterknife.ButterKnife; -public class MainActivity extends AppCompatActivity { +public class MainActivity extends AppCompatActivity +implements ActivityCompat.OnRequestPermissionsResultCallback { public static final String AUTHORITY = "com.wbrawner.simplemarkdown.fileprovider"; private static final int REQUEST_WRITE_STORAGE = 0; @@ -43,6 +49,7 @@ public class MainActivity extends AppCompatActivity { private static final String TAG = MainActivity.class.getSimpleName(); private static String fileName; + public static FileUtils mFileUtils; public static String getTempFileName() { return "tmp_" + getFileName(); @@ -62,7 +69,7 @@ public class MainActivity extends AppCompatActivity { } public static String getFilePath() { - return mFilesDir + "/saved_files/"; + return Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS) + "/"; } public static void setFileName(String fileName) { @@ -123,10 +130,7 @@ public class MainActivity extends AppCompatActivity { public void onClick(DialogInterface dialog, int which) { if (input.getText().length() > 0) { setFileName(input.getText().toString()); - Intent saveIntent = new Intent(EditFragment.SAVE_ACTION); - saveIntent.putExtra("fileName", input.getText()); - LocalBroadcastManager.getInstance(getApplicationContext()) - .sendBroadcast(saveIntent); + requestSave(input.getText().toString()); } } }); @@ -148,11 +152,8 @@ public class MainActivity extends AppCompatActivity { LocalBroadcastManager.getInstance(getApplicationContext()) .sendBroadcast(saveIntent); } - Log.d(TAG, "Temp file size: " + tmpFile.length()); Uri fileUri = FileProvider.getUriForFile(MainActivity.this, AUTHORITY, tmpFile); -// Uri fileUri = Uri.fromFile(tmpFile); if (fileUri != null) { - Log.d(TAG, "MIME type: " + getContentResolver().getType(fileUri)); try { Intent shareIntent = new Intent(Intent.ACTION_SEND); shareIntent.setDataAndType( @@ -177,33 +178,31 @@ public class MainActivity extends AppCompatActivity { } } break; -// case R.id.action_export: -// //TODO: Implement export functionality -// if (ContextCompat.checkSelfPermission(MainActivity.this, -// Manifest.permission.WRITE_EXTERNAL_STORAGE) -// != PackageManager.PERMISSION_GRANTED){ -// ActivityCompat.requestPermissions(MainActivity.this, -// new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, -// REQUEST_WRITE_STORAGE); -// break; -// } } return super.onOptionsItemSelected(item); } + private void requestSave(String text) { + Intent saveIntent = new Intent(EditFragment.SAVE_ACTION); + saveIntent.putExtra("fileName", text); + LocalBroadcastManager.getInstance(getApplicationContext()) + .sendBroadcast(saveIntent); + } + @Override public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { - //TODO: Implement export functionality switch (requestCode) { - case REQUEST_WRITE_STORAGE: { + case FileUtils.WRITE_PERMISSION_REQUEST: { // If request is cancelled, the result arrays are empty. if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // Permission granted, open file chooser dialog - + requestSave(getFileName()); } else { // Permission denied, do nothing + Toast.makeText(MainActivity.this, R.string.no_permissions, Toast.LENGTH_SHORT) + .show(); } return; } diff --git a/app/src/main/res/menu/menu_edit.xml b/app/src/main/res/menu/menu_edit.xml index a326d7e..e673dbe 100644 --- a/app/src/main/res/menu/menu_edit.xml +++ b/app/src/main/res/menu/menu_edit.xml @@ -11,16 +11,6 @@ android:id="@+id/action_share" android:icon="@android:drawable/ic_menu_share" app:showAsAction="always" /> - - - - - - - - - - diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 35ff05a..7d439cd 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -14,4 +14,6 @@ Export Unable to share file - no capable apps installed Share file to... + Unable to save file without permissions + File saved to %1$s