Merge pull request #1305 from kiwix/hotfix/1302

Hotfix: Add "no zim open" check for Add Note Dialog in case of fresh install
This commit is contained in:
Seán Mac Gillicuddy 2019-07-24 09:51:45 +01:00 committed by GitHub
commit 249c00ec03
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 132 additions and 123 deletions

View File

@ -39,7 +39,6 @@ import java.io.File;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import butterknife.BindView; import butterknife.BindView;
import butterknife.ButterKnife; import butterknife.ButterKnife;
import butterknife.Unbinder; import butterknife.Unbinder;
@ -49,13 +48,14 @@ import static org.kiwix.kiwixmobile.utils.Constants.NOTES_DIRECTORY;
/** /**
* Created by @author Aditya-Sood (21/05/19) as a part of GSoC 2019 * Created by @author Aditya-Sood (21/05/19) as a part of GSoC 2019
* *
* AddNoteDialog extends DialogFragment and is used to display the note corresponding to a particular * AddNoteDialog extends DialogFragment and is used to display the note corresponding to a
* article (of a particular zim file/wiki/book) as a full-screen dialog fragment. * particular article (of a particular zim file/wiki/book) as a full-screen dialog fragment.
* *
* Notes are saved as text files at location: "{External Storage}/Kiwix/Notes/ZimFileName/ArticleUrl.txt" * Notes are saved as text files at location: "{External Storage}/Kiwix/Notes/ZimFileName/ArticleUrl.txt"
* */ */
public class AddNoteDialog extends DialogFragment implements ConfirmationAlertDialogFragment.UserClickListener { public class AddNoteDialog extends DialogFragment
implements ConfirmationAlertDialogFragment.UserClickListener {
public static final String TAG = "AddNoteDialog"; public static final String TAG = "AddNoteDialog";
@ -70,36 +70,51 @@ public class AddNoteDialog extends DialogFragment implements ConfirmationAlertDi
private Unbinder unbinder; private Unbinder unbinder;
private String zimFileName;
private String zimFileTitle; private String zimFileTitle;
private String articleTitle; private String articleTitle;
private String zimNoteDirectoryName; // Corresponds to "ZimFileName" of "{External Storage}/Kiwix/Notes/ZimFileName/ArticleUrl.txt" // Corresponds to "ZimFileName" of "{External Storage}/Kiwix/Notes/ZimFileName/ArticleUrl.txt"
private String articleNotefileName; // Corresponds to "ArticleUrl" of "{External Storage}/Kiwix/Notes/ZimFileName/ArticleUrl.txt" private String zimNoteDirectoryName;
// Corresponds to "ArticleUrl" of "{External Storage}/Kiwix/Notes/ZimFileName/ArticleUrl.txt"
private String articleNotefileName;
private boolean noteFileExists = false; private boolean noteFileExists = false;
private boolean noteEdited = false; // Keeps track of state of the note (whether edited since last save) boolean noteEdited = false; // Keeps track of state of the note (whether edited since last save)
private String ZIM_NOTES_DIRECTORY; // Stores path to directory for the currently open zim's notes private String ZIM_NOTES_DIRECTORY; // Stores path to directory for the currently open zim's notes
public AddNoteDialog(SharedPreferenceUtil sharedPreferenceUtil) { public AddNoteDialog(@NonNull SharedPreferenceUtil sharedPreferenceUtil) {
this.sharedPreferenceUtil = sharedPreferenceUtil; this.sharedPreferenceUtil = sharedPreferenceUtil;
} }
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setStyle(DialogFragment.STYLE_NORMAL, sharedPreferenceUtil.nightMode() ? R.style.AddNoteDialogStyle_Night : R.style.AddNoteDialogStyle); setStyle(DialogFragment.STYLE_NORMAL,
sharedPreferenceUtil.nightMode() ? R.style.AddNoteDialogStyle_Night
: R.style.AddNoteDialogStyle);
zimFileTitle = ZimContentProvider.getZimFileTitle(); // Returns name of the form ".../Kiwix/granbluefantasy_en_all_all_nopic_2018-10.zim"
articleTitle = ((MainActivity)getActivity()).getCurrentWebView().getTitle(); zimFileName = ZimContentProvider.getZimFile();
zimNoteDirectoryName = getZimNoteDirectoryName(); if (zimFileName != null) { // No zim file currently opened
articleNotefileName = getArticleNotefileName(); zimFileTitle = ZimContentProvider.getZimFileTitle();
articleTitle = ((MainActivity) getActivity()).getCurrentWebView().getTitle();
ZIM_NOTES_DIRECTORY = NOTES_DIRECTORY + zimNoteDirectoryName + "/"; zimNoteDirectoryName = getZimNoteDirectoryName();
articleNotefileName = getArticleNotefileName();
ZIM_NOTES_DIRECTORY = NOTES_DIRECTORY + zimNoteDirectoryName + "/";
} else {
showToast(R.string.error_filenotfound, Toast.LENGTH_LONG);
closeKeyboard();
getFragmentManager().beginTransaction().remove(AddNoteDialog.this).commit();
}
} }
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { public @NonNull View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState); super.onCreateView(inflater, container, savedInstanceState);
View view = inflater.inflate(R.layout.dialog_add_note, container, false); View view = inflater.inflate(R.layout.dialog_add_note, container, false);
unbinder = ButterKnife.bind(this, view); unbinder = ButterKnife.bind(this, view);
@ -142,7 +157,8 @@ public class AddNoteDialog extends DialogFragment implements ConfirmationAlertDi
addNoteEditText.addTextChangedListener(new TextWatcher() { addNoteEditText.addTextChangedListener(new TextWatcher() {
@Override @Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {} public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override @Override
public void onTextChanged(CharSequence s, int start, int before, int count) { public void onTextChanged(CharSequence s, int start, int before, int count) {
@ -152,26 +168,26 @@ public class AddNoteDialog extends DialogFragment implements ConfirmationAlertDi
} }
@Override @Override
public void afterTextChanged(Editable s) {} public void afterTextChanged(Editable s) {
}
}); });
return view; return view;
} }
private @NonNull String getZimNoteDirectoryName() { private @NonNull String getZimNoteDirectoryName() {
String zimFileName = ZimContentProvider.getZimFile(); // Returns name of the form ".../Kiwix/granbluefantasy_en_all_all_nopic_2018-10.zim"
String noteDirectoryName = getTextAfterLastSlashWithoutExtension(zimFileName); String noteDirectoryName = getTextAfterLastSlashWithoutExtension(zimFileName);
return (!noteDirectoryName.isEmpty()) ? noteDirectoryName : zimFileTitle; // Incase the required ZIM file name couldn't be extracted return (!noteDirectoryName.isEmpty()) ? noteDirectoryName : zimFileTitle;
} }
private @NonNull String getArticleNotefileName() { private @NonNull String getArticleNotefileName() {
String articleUrl = ((MainActivity) getActivity()).getCurrentWebView().getUrl(); // Returns url of the form: "content://org.kiwix.kiwixmobile.zim.base/A/Main_Page.html" // Returns url of the form: "content://org.kiwix.kiwixmobile.zim.base/A/Main_Page.html"
String articleUrl = ((MainActivity) getActivity()).getCurrentWebView().getUrl();
String notefileName = getTextAfterLastSlashWithoutExtension(articleUrl); String notefileName = getTextAfterLastSlashWithoutExtension(articleUrl);
return (!notefileName.isEmpty()) ? notefileName : articleTitle; // Incase the required html file name couldn't be extracted return (!notefileName.isEmpty()) ? notefileName : articleTitle;
} }
private @NonNull String getTextAfterLastSlashWithoutExtension(@NonNull String path) { private @NonNull String getTextAfterLastSlashWithoutExtension(@NonNull String path) {
@ -185,8 +201,8 @@ public class AddNoteDialog extends DialogFragment implements ConfirmationAlertDi
int rightmostSlash = path.lastIndexOf('/'); int rightmostSlash = path.lastIndexOf('/');
int rightmostDot = path.lastIndexOf('.'); int rightmostDot = path.lastIndexOf('.');
if(rightmostSlash > -1 && rightmostDot > -1) { if (rightmostSlash > -1 && rightmostDot > -1) {
return (path.substring(rightmostSlash+1, rightmostDot)); return (path.substring(rightmostSlash + 1, rightmostDot));
} }
return ""; // If couldn't find the dot and/or slash return ""; // If couldn't find the dot and/or slash
@ -204,16 +220,18 @@ public class AddNoteDialog extends DialogFragment implements ConfirmationAlertDi
}; };
} }
private void exitAddNoteDialog() { void exitAddNoteDialog() {
if(noteEdited) { if (noteEdited) {
Fragment previousInstance = getActivity().getSupportFragmentManager().findFragmentByTag(ConfirmationAlertDialogFragment.TAG); Fragment previousInstance = getActivity().getSupportFragmentManager()
.findFragmentByTag(ConfirmationAlertDialogFragment.TAG);
if(previousInstance == null) { if (previousInstance == null) {
// Custom AlertDialog for taking user confirmation before closing note dialog in case of unsaved changes // Custom AlertDialog for taking user confirmation before closing note dialog in case of unsaved changes
DialogFragment newFragment = new ConfirmationAlertDialogFragment(sharedPreferenceUtil, TAG, R.string.confirmation_alert_dialog_message); DialogFragment newFragment = new ConfirmationAlertDialogFragment(sharedPreferenceUtil, TAG,
newFragment.show(getActivity().getSupportFragmentManager(), ConfirmationAlertDialogFragment.TAG); R.string.confirmation_alert_dialog_message);
newFragment.show(getActivity().getSupportFragmentManager(),
ConfirmationAlertDialogFragment.TAG);
} }
} else { } else {
// Closing unedited note dialog straightaway // Closing unedited note dialog straightaway
dismissAddNoteDialog(); dismissAddNoteDialog();
@ -221,36 +239,33 @@ public class AddNoteDialog extends DialogFragment implements ConfirmationAlertDi
} }
private void disableMenuItems() { private void disableMenuItems() {
if(toolbar.getMenu() != null) { if (toolbar.getMenu() != null) {
MenuItem saveItem = toolbar.getMenu().findItem(R.id.save_note); MenuItem saveItem = toolbar.getMenu().findItem(R.id.save_note);
MenuItem shareItem = toolbar.getMenu().findItem(R.id.share_note); MenuItem shareItem = toolbar.getMenu().findItem(R.id.share_note);
saveItem.setEnabled(false); saveItem.setEnabled(false);
shareItem.setEnabled(false); shareItem.setEnabled(false);
saveItem.getIcon().setAlpha(130); saveItem.getIcon().setAlpha(130);
shareItem.getIcon().setAlpha(130); shareItem.getIcon().setAlpha(130);
} else { } else {
Log.d(TAG, "Toolbar without inflated menu"); Log.d(TAG, "Toolbar without inflated menu");
} }
} }
private void enableSaveNoteMenuItem() { void enableSaveNoteMenuItem() {
if(toolbar.getMenu() != null) { if (toolbar.getMenu() != null) {
MenuItem saveItem = toolbar.getMenu().findItem(R.id.save_note); MenuItem saveItem = toolbar.getMenu().findItem(R.id.save_note);
saveItem.setEnabled(true); saveItem.setEnabled(true);
saveItem.getIcon().setAlpha(255); saveItem.getIcon().setAlpha(255);
} else { } else {
Log.d(TAG, "Toolbar without inflated menu"); Log.d(TAG, "Toolbar without inflated menu");
} }
} }
private void enableShareNoteMenuItem() { void enableShareNoteMenuItem() {
if(toolbar.getMenu() != null) { if (toolbar.getMenu() != null) {
MenuItem shareItem = toolbar.getMenu().findItem(R.id.share_note); MenuItem shareItem = toolbar.getMenu().findItem(R.id.share_note);
shareItem.setEnabled(true); shareItem.setEnabled(true);
shareItem.getIcon().setAlpha(255); shareItem.getIcon().setAlpha(255);
} else { } else {
Log.d(TAG, "Toolbar without inflated menu"); Log.d(TAG, "Toolbar without inflated menu");
} }
@ -260,32 +275,35 @@ public class AddNoteDialog extends DialogFragment implements ConfirmationAlertDi
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState); super.onViewCreated(view, savedInstanceState);
if(!noteFileExists) { if (!noteFileExists) {
// Prepare for input in case of empty/new note // Prepare for input in case of empty/new note
addNoteEditText.requestFocus(); addNoteEditText.requestFocus();
showKeyboard(); showKeyboard();
} }
} }
public void showKeyboard(){ private void showKeyboard() {
InputMethodManager inputMethodManager = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE); InputMethodManager inputMethodManager =
(InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
inputMethodManager.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); inputMethodManager.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
} }
public void closeKeyboard(){ void closeKeyboard() {
InputMethodManager inputMethodManager = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE); InputMethodManager inputMethodManager =
(InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
inputMethodManager.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0); inputMethodManager.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0);
} }
private void saveNote(String noteText) { void saveNote(String noteText) {
/* String content of the EditText, given by noteText, is saved into the text file given by: /* String content of the EditText, given by noteText, is saved into the text file given by:
* "{External Storage}/Kiwix/Notes/ZimFileTitle/ArticleTitle.txt" * "{External Storage}/Kiwix/Notes/ZimFileTitle/ArticleTitle.txt"
* */ * */
if(isExternalStorageWritable()) { if (isExternalStorageWritable()) {
if(ContextCompat.checkSelfPermission(getContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { if (ContextCompat.checkSelfPermission(getContext(),
Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
Log.d(TAG, "WRITE_EXTERNAL_STORAGE permission not granted"); Log.d(TAG, "WRITE_EXTERNAL_STORAGE permission not granted");
showToast(R.string.note_save_unsuccessful, Toast.LENGTH_LONG); showToast(R.string.note_save_unsuccessful, Toast.LENGTH_LONG);
return; return;
@ -294,12 +312,12 @@ public class AddNoteDialog extends DialogFragment implements ConfirmationAlertDi
File notesFolder = new File(ZIM_NOTES_DIRECTORY); File notesFolder = new File(ZIM_NOTES_DIRECTORY);
boolean folderExists = true; boolean folderExists = true;
if(!notesFolder.exists()) { if (!notesFolder.exists()) {
// Try creating folder if it doesn't exist // Try creating folder if it doesn't exist
folderExists = notesFolder.mkdirs(); folderExists = notesFolder.mkdirs();
} }
if(folderExists) { if (folderExists) {
File noteFile = new File(notesFolder.getAbsolutePath(), articleNotefileName + ".txt"); File noteFile = new File(notesFolder.getAbsolutePath(), articleNotefileName + ".txt");
// Save note text-file code: // Save note text-file code:
@ -309,21 +327,17 @@ public class AddNoteDialog extends DialogFragment implements ConfirmationAlertDi
fileOutputStream.close(); fileOutputStream.close();
showToast(R.string.note_save_successful, Toast.LENGTH_SHORT); showToast(R.string.note_save_successful, Toast.LENGTH_SHORT);
noteEdited = false; // As no unsaved changes remain noteEdited = false; // As no unsaved changes remain
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
showToast(R.string.note_save_unsuccessful, Toast.LENGTH_LONG); showToast(R.string.note_save_unsuccessful, Toast.LENGTH_LONG);
} }
} else { } else {
showToast(R.string.note_save_unsuccessful, Toast.LENGTH_LONG); showToast(R.string.note_save_unsuccessful, Toast.LENGTH_LONG);
Log.d(TAG, "Required folder doesn't exist"); Log.d(TAG, "Required folder doesn't exist");
} }
} } else {
else {
showToast(R.string.note_save_error_storage_not_writable, Toast.LENGTH_LONG); showToast(R.string.note_save_error_storage_not_writable, Toast.LENGTH_LONG);
} }
} }
private void displayNote() { private void displayNote() {
@ -335,30 +349,20 @@ public class AddNoteDialog extends DialogFragment implements ConfirmationAlertDi
File noteFile = new File(ZIM_NOTES_DIRECTORY + articleNotefileName + ".txt"); File noteFile = new File(ZIM_NOTES_DIRECTORY + articleNotefileName + ".txt");
if(noteFile.exists()) { if (noteFile.exists()) {
noteFileExists = true; noteFileExists = true;
StringBuilder contents = new StringBuilder(); StringBuilder contents = new StringBuilder();
try { try (BufferedReader input = new BufferedReader(new java.io.FileReader(noteFile))) {
String line = null;
BufferedReader input = new BufferedReader(new java.io.FileReader(noteFile)); while ((line = input.readLine()) != null) {
try { contents.append(line);
String line = null; contents.append(System.getProperty("line.separator"));
while((line = input.readLine()) != null) {
contents.append(line);
contents.append(System.getProperty("line.separator"));
}
} catch (IOException e) {
e.printStackTrace();
Log.d(TAG, "Error reading line with BufferedReader");
} finally {
input.close();
} }
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
Log.d(TAG, "Error closing BufferedReader"); Log.d(TAG, "Error reading line with BufferedReader");
} }
addNoteEditText.setText(contents.toString()); // Display the note content addNoteEditText.setText(contents.toString()); // Display the note content
@ -369,49 +373,51 @@ public class AddNoteDialog extends DialogFragment implements ConfirmationAlertDi
// No action in case the note file for the currently open article doesn't exist // No action in case the note file for the currently open article doesn't exist
} }
private void shareNote() { void shareNote() {
/* The note text file corresponding to the currently open article, given at: /* The note text file corresponding to the currently open article, given at:
* "{External Storage}/Kiwix/Notes/ZimFileTitle/ArticleTitle.txt" * "{External Storage}/Kiwix/Notes/ZimFileTitle/ArticleTitle.txt"
* is shared via an app-chooser intent * is shared via an app-chooser intent
* */ * */
if(noteEdited) { if (noteEdited) {
saveNote(addNoteEditText.getText().toString()); // Save edited note before sharing the text file saveNote(
addNoteEditText.getText().toString()); // Save edited note before sharing the text file
} }
File noteFile = new File(ZIM_NOTES_DIRECTORY + articleNotefileName + ".txt"); File noteFile = new File(ZIM_NOTES_DIRECTORY + articleNotefileName + ".txt");
Uri noteFileUri = null; Uri noteFileUri = null;
if(noteFile.exists()) { if (noteFile.exists()) {
if (Build.VERSION.SDK_INT >= 24) { if (Build.VERSION.SDK_INT >= 24) {
// From Nougat 7 (API 24) access to files is shared temporarily with other apps // From Nougat 7 (API 24) access to files is shared temporarily with other apps
// Need to use FileProvider for the same // Need to use FileProvider for the same
noteFileUri = FileProvider.getUriForFile(getContext(), BuildConfig.APPLICATION_ID+".fileprovider", noteFile); noteFileUri =
FileProvider.getUriForFile(getContext(), BuildConfig.APPLICATION_ID + ".fileprovider",
noteFile);
} else { } else {
noteFileUri = Uri.fromFile(noteFile); noteFileUri = Uri.fromFile(noteFile);
} }
} else { } else {
showToast(R.string.note_share_error_file_missing, Toast.LENGTH_SHORT); showToast(R.string.note_share_error_file_missing, Toast.LENGTH_SHORT);
} }
if(noteFileUri != null) { if (noteFileUri != null) {
Intent noteFileShareIntent = new Intent(Intent.ACTION_SEND); Intent noteFileShareIntent = new Intent(Intent.ACTION_SEND);
noteFileShareIntent.setType("application/octet-stream"); noteFileShareIntent.setType("application/octet-stream");
noteFileShareIntent.putExtra(Intent.EXTRA_STREAM, noteFileUri); noteFileShareIntent.putExtra(Intent.EXTRA_STREAM, noteFileUri);
noteFileShareIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); noteFileShareIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
Intent shareChooser = Intent.createChooser(noteFileShareIntent, getString(R.string.note_share_app_chooser_title)); Intent shareChooser = Intent.createChooser(noteFileShareIntent,
getString(R.string.note_share_app_chooser_title));
if(noteFileShareIntent.resolveActivity(getActivity().getPackageManager()) != null) { if (noteFileShareIntent.resolveActivity(getActivity().getPackageManager()) != null) {
startActivity(shareChooser); startActivity(shareChooser);
} }
} }
} }
public static boolean isExternalStorageWritable() { static boolean isExternalStorageWritable() {
return Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()); return Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState());
} }
@ -440,7 +446,7 @@ public class AddNoteDialog extends DialogFragment implements ConfirmationAlertDi
super.onStart(); super.onStart();
Dialog dialog = getDialog(); Dialog dialog = getDialog();
if(dialog != null) { if (dialog != null) {
int width = ViewGroup.LayoutParams.MATCH_PARENT; int width = ViewGroup.LayoutParams.MATCH_PARENT;
int height = ViewGroup.LayoutParams.MATCH_PARENT; int height = ViewGroup.LayoutParams.MATCH_PARENT;
dialog.getWindow().setLayout(width, height); dialog.getWindow().setLayout(width, height);
@ -454,5 +460,4 @@ public class AddNoteDialog extends DialogFragment implements ConfirmationAlertDi
unbinder.unbind(); unbinder.unbind();
} }
} }
} }

View File

@ -154,7 +154,7 @@ import static org.kiwix.kiwixmobile.utils.StyleUtils.dialogStyle;
import static org.kiwix.kiwixmobile.utils.UpdateUtils.reformatProviderUrl; import static org.kiwix.kiwixmobile.utils.UpdateUtils.reformatProviderUrl;
public class MainActivity extends BaseActivity implements WebViewCallback, public class MainActivity extends BaseActivity implements WebViewCallback,
MainContract.View{ MainContract.View {
private static final String NEW_TAB = "NEW_TAB"; private static final String NEW_TAB = "NEW_TAB";
private static final String HOME_URL = "file:///android_asset/home.html"; private static final String HOME_URL = "file:///android_asset/home.html";
@ -276,7 +276,6 @@ public class MainActivity extends BaseActivity implements WebViewCallback,
} }
}; };
private static void updateWidgets(Context context) { private static void updateWidgets(Context context) {
Intent intent = new Intent(context.getApplicationContext(), KiwixSearchWidget.class); Intent intent = new Intent(context.getApplicationContext(), KiwixSearchWidget.class);
intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE); intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
@ -359,13 +358,13 @@ public class MainActivity extends BaseActivity implements WebViewCallback,
wasHideToolbar = isHideToolbar; wasHideToolbar = isHideToolbar;
booksAdapter = new BooksOnDiskAdapter( booksAdapter = new BooksOnDiskAdapter(
new BookOnDiskDelegate.BookDelegate(sharedPreferenceUtil, new BookOnDiskDelegate.BookDelegate(sharedPreferenceUtil,
bookOnDiskItem -> { bookOnDiskItem -> {
open(bookOnDiskItem); open(bookOnDiskItem);
return Unit.INSTANCE; return Unit.INSTANCE;
}, },
null, null,
null), null),
BookOnDiskDelegate.LanguageDelegate.INSTANCE BookOnDiskDelegate.LanguageDelegate.INSTANCE
); );
@ -846,14 +845,14 @@ public class MainActivity extends BaseActivity implements WebViewCallback,
break; break;
case R.id.menu_add_note: case R.id.menu_add_note:
if(requestExternalStorageWritePermissionForNotes()) { if (requestExternalStorageWritePermissionForNotes()) {
// Check permission since notes are stored in the public-external storage // Check permission since notes are stored in the public-external storage
showAddNoteDialog(); showAddNoteDialog();
} }
break; break;
case R.id.menu_clear_notes: case R.id.menu_clear_notes:
if(requestExternalStorageWritePermissionForNotes()) { // Check permission since notes are stored in the public-external storage if (requestExternalStorageWritePermissionForNotes()) { // Check permission since notes are stored in the public-external storage
showClearAllNotesDialog(); showClearAllNotesDialog();
} }
break; break;
@ -939,12 +938,13 @@ public class MainActivity extends BaseActivity implements WebViewCallback,
} }
/** Method to delete all user notes */ /** Method to delete all user notes */
private void clearAllNotes() { void clearAllNotes() {
boolean result = true; // Result of all delete() calls is &&-ed to this variable boolean result = true; // Result of all delete() calls is &&-ed to this variable
if(AddNoteDialog.isExternalStorageWritable()) { if (AddNoteDialog.isExternalStorageWritable()) {
if(ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
Log.d("MainActivity", "WRITE_EXTERNAL_STORAGE permission not granted"); Log.d("MainActivity", "WRITE_EXTERNAL_STORAGE permission not granted");
showToast(R.string.ext_storage_permission_not_granted, Toast.LENGTH_LONG); showToast(R.string.ext_storage_permission_not_granted, Toast.LENGTH_LONG);
return; return;
@ -955,17 +955,17 @@ public class MainActivity extends BaseActivity implements WebViewCallback,
File notesDirectory = new File(NOTES_DIRECTORY); File notesDirectory = new File(NOTES_DIRECTORY);
File[] filesInNotesDirectory = notesDirectory.listFiles(); File[] filesInNotesDirectory = notesDirectory.listFiles();
if(filesInNotesDirectory == null) { // Notes folder doesn't exist if (filesInNotesDirectory == null) { // Notes folder doesn't exist
showToast(R.string.notes_deletion_none_found, Toast.LENGTH_LONG); showToast(R.string.notes_deletion_none_found, Toast.LENGTH_LONG);
return; return;
} }
for(File wikiFileDirectory : filesInNotesDirectory) { for (File wikiFileDirectory : filesInNotesDirectory) {
if(wikiFileDirectory.isDirectory()) { if (wikiFileDirectory.isDirectory()) {
File[] filesInWikiDirectory = wikiFileDirectory.listFiles(); File[] filesInWikiDirectory = wikiFileDirectory.listFiles();
for(File noteFile : filesInWikiDirectory) { for (File noteFile : filesInWikiDirectory) {
if(noteFile.isFile()) { if (noteFile.isFile()) {
result = result && noteFile.delete(); result = result && noteFile.delete();
} }
} }
@ -974,10 +974,11 @@ public class MainActivity extends BaseActivity implements WebViewCallback,
result = result && wikiFileDirectory.delete(); // Wiki specific notes directory deleted result = result && wikiFileDirectory.delete(); // Wiki specific notes directory deleted
} }
result = result && notesDirectory.delete(); // "{External Storage}/Kiwix/Notes" directory deleted result =
result && notesDirectory.delete(); // "{External Storage}/Kiwix/Notes" directory deleted
} }
if(result) { if (result) {
showToast(R.string.notes_deletion_successful, Toast.LENGTH_SHORT); showToast(R.string.notes_deletion_successful, Toast.LENGTH_SHORT);
} else { } else {
showToast(R.string.notes_deletion_unsuccessful, Toast.LENGTH_SHORT); showToast(R.string.notes_deletion_unsuccessful, Toast.LENGTH_SHORT);
@ -990,23 +991,24 @@ public class MainActivity extends BaseActivity implements WebViewCallback,
Fragment previousInstance = getSupportFragmentManager().findFragmentByTag(AddNoteDialog.TAG); Fragment previousInstance = getSupportFragmentManager().findFragmentByTag(AddNoteDialog.TAG);
// To prevent multiple instances of the DialogFragment // To prevent multiple instances of the DialogFragment
if(previousInstance == null) { if (previousInstance == null) {
/* Since the DialogFragment is never added to the back-stack, so findFragmentByTag() /* Since the DialogFragment is never added to the back-stack, so findFragmentByTag()
* returning null means that the AddNoteDialog is currently not on display (as doesn't exist) * returning null means that the AddNoteDialog is currently not on display (as doesn't exist)
**/ **/
AddNoteDialog dialogFragment = new AddNoteDialog(sharedPreferenceUtil); AddNoteDialog dialogFragment = new AddNoteDialog(sharedPreferenceUtil);
dialogFragment.show(fragmentTransaction, AddNoteDialog.TAG); // For DialogFragments, show() handles the fragment commit and display dialogFragment.show(fragmentTransaction, AddNoteDialog.TAG);
// For DialogFragments, show() handles the fragment commit and display
} }
} }
private boolean requestExternalStorageWritePermissionForNotes() { private boolean requestExternalStorageWritePermissionForNotes() {
if(Build.VERSION.SDK_INT >= 23) { // For Marshmallow & higher API levels if (Build.VERSION.SDK_INT >= 23) { // For Marshmallow & higher API levels
if(checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) { if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED) {
return true; return true;
} else { } else {
if(shouldShowRequestPermissionRationale(Manifest.permission.WRITE_EXTERNAL_STORAGE)) { if (shouldShowRequestPermissionRationale(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
/* shouldShowRequestPermissionRationale() returns false when: /* shouldShowRequestPermissionRationale() returns false when:
* 1) User has previously checked on "Don't ask me again", and/or * 1) User has previously checked on "Don't ask me again", and/or
* 2) Permission has been disabled on device * 2) Permission has been disabled on device
@ -1014,9 +1016,9 @@ public class MainActivity extends BaseActivity implements WebViewCallback,
showToast(R.string.ext_storage_permission_rationale_add_note, Toast.LENGTH_LONG); showToast(R.string.ext_storage_permission_rationale_add_note, Toast.LENGTH_LONG);
} }
requestPermissions(new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_WRITE_STORAGE_PERMISSION_ADD_NOTE); requestPermissions(new String[] { Manifest.permission.WRITE_EXTERNAL_STORAGE },
REQUEST_WRITE_STORAGE_PERMISSION_ADD_NOTE);
} }
} else { // For Android versions below Marshmallow 6.0 (API 23) } else { // For Android versions below Marshmallow 6.0 (API 23)
return true; // As already requested at install time return true; // As already requested at install time
} }
@ -1202,12 +1204,12 @@ public class MainActivity extends BaseActivity implements WebViewCallback,
case REQUEST_WRITE_STORAGE_PERMISSION_ADD_NOTE: { case REQUEST_WRITE_STORAGE_PERMISSION_ADD_NOTE: {
if(grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Successfully granted permission, so opening the note keeper // Successfully granted permission, so opening the note keeper
showAddNoteDialog(); showAddNoteDialog();
} else { } else {
Toast.makeText(getApplicationContext(), getString(R.string.ext_storage_write_permission_denied_add_note), Toast.LENGTH_LONG); Toast.makeText(getApplicationContext(),
getString(R.string.ext_storage_write_permission_denied_add_note), Toast.LENGTH_LONG);
} }
break; break;
@ -1327,7 +1329,8 @@ public class MainActivity extends BaseActivity implements WebViewCallback,
//Check maybe need refresh //Check maybe need refresh
String articleUrl = getCurrentWebView().getUrl(); String articleUrl = getCurrentWebView().getUrl();
boolean isBookmark = false; boolean isBookmark = false;
BookmarkItem bookmark = BookmarkItem.fromZimContentProvider(getCurrentWebView().getTitle(),articleUrl); BookmarkItem bookmark =
BookmarkItem.fromZimContentProvider(getCurrentWebView().getTitle(), articleUrl);
if (articleUrl != null && !bookmarks.contains(articleUrl)) { if (articleUrl != null && !bookmarks.contains(articleUrl)) {
if (ZimContentProvider.getId() != null) { if (ZimContentProvider.getId() != null) {
presenter.saveBookmark(bookmark); presenter.saveBookmark(bookmark);
@ -1978,7 +1981,8 @@ public class MainActivity extends BaseActivity implements WebViewCallback,
String url = getCurrentWebView().getUrl(); String url = getCurrentWebView().getUrl();
if (url != null && !url.equals(HOME_URL)) { if (url != null && !url.equals(HOME_URL)) {
final long timeStamp = System.currentTimeMillis(); final long timeStamp = System.currentTimeMillis();
SimpleDateFormat sdf = new SimpleDateFormat("d MMM yyyy", LanguageUtils.getCurrentLocale(this)); SimpleDateFormat sdf =
new SimpleDateFormat("d MMM yyyy", LanguageUtils.getCurrentLocale(this));
HistoryListItem.HistoryItem history = new HistoryListItem.HistoryItem( HistoryListItem.HistoryItem history = new HistoryListItem.HistoryItem(
0L, 0L,
ZimContentProvider.getId(), ZimContentProvider.getId(),