Finished save functionality and started load functionality

This commit is contained in:
William Brawner 2017-07-26 07:02:59 -05:00
parent 028006196b
commit 7a39fd947c
8 changed files with 232 additions and 49 deletions

View file

@ -2,6 +2,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.wbrawner.simplemarkdown"> package="com.wbrawner.simplemarkdown">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application <application
android:allowBackup="true" android:allowBackup="true"
android:icon="@mipmap/ic_launcher" android:icon="@mipmap/ic_launcher"
@ -13,6 +14,17 @@
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN"></action> <action android:name="android.intent.action.MAIN"></action>
<category android:name="android.intent.category.LAUNCHER"></category> <category android:name="android.intent.category.LAUNCHER"></category>
<action android:name="android.intent.action.EDIT" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="file" />
<data android:scheme="content" />
<data android:mimeType="text/plain" />
<data android:mimeType="text/markdown" />
<data android:pathPattern=".*\\.md" />
<data android:mimeType="application/octet-stream" />
<data android:host="*" />
</intent-filter> </intent-filter>
</activity> </activity>
<provider <provider

View file

@ -1,9 +1,11 @@
package com.wbrawner.simplemarkdown; package com.wbrawner.simplemarkdown;
import android.app.Activity;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
@ -33,7 +35,11 @@ import static android.content.ContentValues.TAG;
public class EditFragment extends Fragment { public class EditFragment extends Fragment {
public static final String SAVE_ACTION = "com.wbrawner.simplemarkdown.ACTION_SAVE"; public static final String SAVE_ACTION = "com.wbrawner.simplemarkdown.ACTION_SAVE";
@BindView(R.id.markdown_edit) EditText markdownEditor; public static final String LOAD_ACTION = "com.wbrawner.simplemarkdown.ACTION_LOAD";
@BindView(R.id.markdown_edit)
EditText markdownEditor;
private Activity mContext;
private File mTmpFile; private File mTmpFile;
@ -46,10 +52,12 @@ public class EditFragment extends Fragment {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
IntentFilter filter = new IntentFilter(); IntentFilter filter = new IntentFilter();
filter.addAction(SAVE_ACTION); filter.addAction(SAVE_ACTION);
filter.addAction(LOAD_ACTION);
LocalBroadcastManager.getInstance(getContext()).registerReceiver( LocalBroadcastManager.getInstance(getContext()).registerReceiver(
new EditFragment.MarkdownBroadcastSaveReceiver(), new EditFragment.MarkdownBroadcastSaveReceiver(),
filter filter
); );
mContext = getActivity();
} }
@Override @Override
@ -60,7 +68,8 @@ public class EditFragment extends Fragment {
ButterKnife.bind(this, view); ButterKnife.bind(this, view);
if (markdownEditor.requestFocus()) { if (markdownEditor.requestFocus()) {
getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE); getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
}; }
;
markdownEditor.addTextChangedListener(new TextWatcher() { markdownEditor.addTextChangedListener(new TextWatcher() {
@Override @Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
@ -82,12 +91,10 @@ public class EditFragment extends Fragment {
@Override @Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState); super.onViewCreated(view, savedInstanceState);
Log.d(TAG, "Markdown from beginning: " + markdownEditor.getText().toString());
BufferedReader reader = null; BufferedReader reader = null;
try { try {
File tmpFile = new File(getActivity().getFilesDir() + MainActivity.getTempFileName()); File tmpFile = new File(getActivity().getFilesDir() + MainActivity.getTempFileName());
if (tmpFile.exists()) { if (tmpFile.exists()) {
Log.d(TAG, "Temp file size: " + tmpFile.length());
InputStream in = new FileInputStream(tmpFile); InputStream in = new FileInputStream(tmpFile);
reader = new BufferedReader(new InputStreamReader(in)); reader = new BufferedReader(new InputStreamReader(in));
String line; String line;
@ -106,16 +113,10 @@ public class EditFragment extends Fragment {
} }
} }
} }
if (markdownEditor.getText().length() > 0) {
Log.d(TAG, "We have text");
} else {
Log.d(TAG, "Blank slate");
}
updatePreview(markdownEditor.getText()); updatePreview(markdownEditor.getText());
} }
private void updatePreview(Editable data) { private void updatePreview(Editable data) {
Log.d(TAG, "Data to send: " + data.toString());
Intent broadcastIntent = new Intent(PreviewFragment.PREVIEW_ACTION); Intent broadcastIntent = new Intent(PreviewFragment.PREVIEW_ACTION);
broadcastIntent.putExtra("markdownData", data.toString()); broadcastIntent.putExtra("markdownData", data.toString());
LocalBroadcastManager manager = LocalBroadcastManager.getInstance(getContext()); LocalBroadcastManager manager = LocalBroadcastManager.getInstance(getContext());
@ -161,11 +162,25 @@ public class EditFragment extends Fragment {
private class MarkdownBroadcastSaveReceiver extends BroadcastReceiver { private class MarkdownBroadcastSaveReceiver extends BroadcastReceiver {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
Log.d(TAG, "Intent received: " + intent.getAction());
switch (intent.getAction()) {
case SAVE_ACTION:
if (intent.hasExtra("fileName")) { if (intent.hasExtra("fileName")) {
String fileName = intent.getStringExtra("fileName"); String fileName = intent.getStringExtra("fileName");
Log.d(TAG, "File: " + fileName);
save(markdownEditor.getText().toString(), fileName); save(markdownEditor.getText().toString(), fileName);
} }
break;
case LOAD_ACTION:
if (intent.hasExtra("fileUri")) {
load(Uri.parse(intent.getStringExtra("fileUri")));
} }
break;
}
}
}
private void load(Uri fileUri) {
FileLoadTask loadTask = new FileLoadTask(mContext, markdownEditor);
loadTask.execute(fileUri);
} }
} }

View file

@ -0,0 +1,64 @@
package com.wbrawner.simplemarkdown;
import android.content.Context;
import android.net.Uri;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.EditText;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import static android.content.ContentValues.TAG;
/**
* Created by billy on 7/25/17.
*/
public class FileLoadTask extends AsyncTask<Uri, Void, String> {
private Context mContext;
private EditText mMarkdownEditor;
public FileLoadTask(Context context, EditText markdownEditor) {
mContext = context;
mMarkdownEditor = markdownEditor;
}
@Override
protected String doInBackground(Uri... uris) {
if (mContext == null) {
Log.d(TAG, "No context, abort");
return null;
}
Log.d(TAG, "Begin loading file");
BufferedReader reader = null;
StringBuilder sb = new StringBuilder();
try {
InputStream in = mContext.getContentResolver().openInputStream(uris[0]);
reader = new BufferedReader(new InputStreamReader(in));
String line;
while ((line = reader.readLine()) != null) {
sb.append(line);
sb.append("\r\n");
}
} catch (Exception e) {
Log.e(TAG, "Error opening file:", e);
} finally {
if (reader != null) {
try {
reader.close();
} catch (Exception e) {
}
}
}
return sb.toString();
}
@Override
protected void onPostExecute(String s) {
mMarkdownEditor.setText(s);
super.onPostExecute(s);
}
}

View file

@ -1,12 +1,18 @@
package com.wbrawner.simplemarkdown; package com.wbrawner.simplemarkdown;
import android.Manifest;
import android.content.ActivityNotFoundException;
import android.content.ClipData;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri; import android.net.Uri;
import android.support.design.widget.TabLayout; import android.support.design.widget.TabLayout;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter; import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.FileProvider; import android.support.v4.content.FileProvider;
import android.support.v4.content.LocalBroadcastManager; import android.support.v4.content.LocalBroadcastManager;
import android.support.v4.view.ViewPager; import android.support.v4.view.ViewPager;
@ -17,7 +23,9 @@ import android.text.InputType;
import android.util.Log; import android.util.Log;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.webkit.MimeTypeMap;
import android.widget.EditText; import android.widget.EditText;
import android.widget.Toast;
import java.io.File; import java.io.File;
@ -27,6 +35,7 @@ import butterknife.ButterKnife;
public class MainActivity extends AppCompatActivity { public class MainActivity extends AppCompatActivity {
private static final String AUTHORITY = "com.wbrawner.simplemarkdown.fileprovider"; private static final String AUTHORITY = "com.wbrawner.simplemarkdown.fileprovider";
private static final int REQUEST_WRITE_STORAGE = 0;
private static File mFilesDir; private static File mFilesDir;
@BindView(R.id.pager) ViewPager pager; @BindView(R.id.pager) ViewPager pager;
@BindView(R.id.layout_tab) TabLayout tabLayout; @BindView(R.id.layout_tab) TabLayout tabLayout;
@ -35,22 +44,24 @@ public class MainActivity extends AppCompatActivity {
private static String fileName; private static String fileName;
public static String getTempFileName() { public static String getTempFileName() {
return "com_wbrawner_simplemarkdown_tmp.md"; return "tmp_" + getFileName();
} }
public static String getFileName() { public static String getFileName() {
if (fileName == null) { if (fileName == null) {
return getTempFileName(); return "untitled.md";
} }
if (!fileName.endsWith(".md"))
return fileName + ".md";
return fileName; return fileName;
} }
public static String getTempFilePath() { public static String getTempFilePath() {
return mFilesDir + File.pathSeparator + "tmp" + File.pathSeparator; return mFilesDir + "/tmp/";
} }
public static String getFilePath() { public static String getFilePath() {
return mFilesDir + File.pathSeparator + "saved_files" + File.pathSeparator; return mFilesDir + "/saved_files/";
} }
public static void setFileName(String fileName) { public static void setFileName(String fileName) {
@ -64,13 +75,33 @@ public class MainActivity extends AppCompatActivity {
ButterKnife.bind(this); ButterKnife.bind(this);
pager.setAdapter(new EditPagerAdapter(getSupportFragmentManager())); pager.setAdapter(new EditPagerAdapter(getSupportFragmentManager()));
mFilesDir = getFilesDir(); mFilesDir = getFilesDir();
checkDirectories();
Intent intent = getIntent();
if (intent != null && intent.getData() != null) {
Intent loadIntent = new Intent(EditFragment.LOAD_ACTION);
loadIntent.putExtra("fileUri", intent.getData().toString());
LocalBroadcastManager.getInstance(getApplicationContext())
.sendBroadcast(loadIntent);
}
} }
// @Override private void checkDirectories() {
// public boolean onCreateOptionsMenu(Menu menu) { File tmpDir = new File(getTempFilePath());
// getMenuInflater().inflate(R.menu.menu_edit, menu); if (!tmpDir.exists()) {
// return true; tmpDir.mkdir();
// } }
File outDir = new File(getFilePath());
if (!outDir.exists()) {
outDir.mkdir();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_edit, menu);
return true;
}
@Override @Override
public boolean onOptionsItemSelected(MenuItem item) { public boolean onOptionsItemSelected(MenuItem item) {
@ -83,16 +114,20 @@ public class MainActivity extends AppCompatActivity {
final EditText input = new EditText(this); final EditText input = new EditText(this);
input.setInputType(InputType.TYPE_CLASS_TEXT); input.setInputType(InputType.TYPE_CLASS_TEXT);
input.setHint(R.string.hint_filename); input.setHint(R.string.hint_filename);
input.setText(getFileName());
builder.setView(input); builder.setView(input);
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() { builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override @Override
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
if (input.getText().length() > 0) {
setFileName(input.getText().toString());
Intent saveIntent = new Intent(EditFragment.SAVE_ACTION); Intent saveIntent = new Intent(EditFragment.SAVE_ACTION);
saveIntent.putExtra("fileName", input.getText()); saveIntent.putExtra("fileName", input.getText());
LocalBroadcastManager.getInstance(getApplicationContext()) LocalBroadcastManager.getInstance(getApplicationContext())
.sendBroadcast(saveIntent); .sendBroadcast(saveIntent);
} }
}
}); });
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override @Override
@ -105,22 +140,75 @@ public class MainActivity extends AppCompatActivity {
break; break;
case R.id.action_share: case R.id.action_share:
//TODO: Fix this //TODO: Fix this
File tmpFile = new File(getFilesDir() + getTempFileName()); File tmpFile = new File(getTempFilePath() + getFileName());
if (tmpFile.exists()) { if (!tmpFile.exists()) {
Intent saveIntent = new Intent(EditFragment.SAVE_ACTION);
saveIntent.putExtra("fileName", getTempFilePath() + getFileName());
LocalBroadcastManager.getInstance(getApplicationContext())
.sendBroadcast(saveIntent);
}
Log.d(TAG, "Temp file size: " + tmpFile.length()); Log.d(TAG, "Temp file size: " + tmpFile.length());
Uri fileUri = FileProvider.getUriForFile(MainActivity.this, AUTHORITY, tmpFile); Uri fileUri = FileProvider.getUriForFile(MainActivity.this, AUTHORITY, tmpFile);
// Uri fileUri = Uri.fromFile(tmpFile);
if (fileUri != null) { if (fileUri != null) {
Log.d(TAG, "MIME type: " + getContentResolver().getType(fileUri));
try {
Intent shareIntent = new Intent(Intent.ACTION_SEND); Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setDataAndType(
fileUri,
getContentResolver().getType(fileUri)
);
shareIntent.putExtra(Intent.EXTRA_STREAM, fileUri); shareIntent.putExtra(Intent.EXTRA_STREAM, fileUri);
shareIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); shareIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(shareIntent); startActivity(
Intent.createChooser(
shareIntent,
getString(R.string.share_file)
)
);
} catch (ActivityNotFoundException e) {
Log.e(TAG, "Error sharing file", e);
Toast.makeText(
MainActivity.this,
R.string.no_shareable_apps,
Toast.LENGTH_SHORT
).show();
} }
} }
break; 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); return super.onOptionsItemSelected(item);
} }
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
//TODO: Implement export functionality
switch (requestCode) {
case REQUEST_WRITE_STORAGE: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Permission granted, open file chooser dialog
} else {
// Permission denied, do nothing
}
return;
}
}
}
public class EditPagerAdapter extends FragmentPagerAdapter { public class EditPagerAdapter extends FragmentPagerAdapter {
private static final int FRAGMENT_EDIT = 0; private static final int FRAGMENT_EDIT = 0;
private static final int FRAGMENT_PREVIEW = 1; private static final int FRAGMENT_PREVIEW = 1;

View file

@ -11,4 +11,19 @@
android:id="@+id/action_share" android:id="@+id/action_share"
android:icon="@android:drawable/ic_menu_share" android:icon="@android:drawable/ic_menu_share"
app:showAsAction="always" /> 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"-->
<!--android:title="@string/action_help"-->
<!--app:showAsAction="never" />-->
</menu> </menu>

View file

@ -1,15 +0,0 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context="com.wbrawner.simplemarkdown.MainActivity">
<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"
android:title="@string/action_help"
app:showAsAction="never" />
</menu>

View file

@ -11,4 +11,7 @@
<string name="action_save">Save</string> <string name="action_save">Save</string>
<string name="action_share">Share</string> <string name="action_share">Share</string>
<string name="hint_filename">File name</string> <string name="hint_filename">File name</string>
<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>
</resources> </resources>

View file

@ -1,4 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android"> <paths xmlns:android="http://schemas.android.com/apk/res/android">
<files-path name="markdown_files" path="/"/> <files-path name="saved_files" path="saved_files/"/>
<files-path name="tmp" path="tmp/"/>
</paths> </paths>