Save files to external storage

This commit is contained in:
William Brawner 2017-07-27 18:21:26 -05:00
parent 9a493fb536
commit 74a6f930a5
5 changed files with 111 additions and 37 deletions

View file

@ -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;

View file

@ -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
);
}
}

View file

@ -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;
}

View file

@ -11,16 +11,6 @@
android:id="@+id/action_share"
android:icon="@android:drawable/ic_menu_share"
app:showAsAction="always" />
<!--<item-->
<!--android:id="@+id/action_export"-->
<!--android:orderInCategory="100"-->
<!--android:title="@string/action_export"-->
<!--app:showAsAction="never" />-->
<!--<item-->
<!--android:id="@+id/action_settings"-->
<!--android:orderInCategory="100"-->
<!--android:title="@string/action_settings"-->
<!--app:showAsAction="never" />-->
<!--<item-->
<!--android:id="@+id/action_help"-->
<!--android:orderInCategory="100"-->

View file

@ -14,4 +14,6 @@
<string name="action_export">Export</string>
<string name="no_shareable_apps">Unable to share file - no capable apps installed</string>
<string name="share_file">Share file to...</string>
<string name="no_permissions">Unable to save file without permissions</string>
<string name="file_saved">File saved to %1$s</string>
</resources>