Merge branch 'android-filechooser-orig'

Conflicts:
	src/java/android-filechooser/code/project.properties
	src/java/android-filechooser/code/res/drawable-hdpi/afc_ic_menu_bookmarks.png
	src/java/android-filechooser/code/res/drawable-hdpi/afc_ic_menu_bookmarks_dark.png
	src/java/android-filechooser/code/res/drawable-hdpi/afc_ic_menu_bookmarks_light.png
	src/java/android-filechooser/code/res/drawable-mdpi/afc_ic_menu_bookmarks.png
	src/java/android-filechooser/code/res/drawable-mdpi/afc_ic_menu_bookmarks_dark.png
	src/java/android-filechooser/code/res/drawable-mdpi/afc_ic_menu_bookmarks_light.png
	src/java/android-filechooser/code/res/drawable-xhdpi/afc_ic_menu_bookmarks.png
	src/java/android-filechooser/code/res/drawable-xhdpi/afc_ic_menu_bookmarks_dark.png
	src/java/android-filechooser/code/res/drawable-xhdpi/afc_ic_menu_bookmarks_light.png
	src/java/android-filechooser/code/res/drawable-xxhdpi/afc_ic_menu_bookmarks_dark.png
	src/java/android-filechooser/code/res/drawable-xxhdpi/afc_ic_menu_bookmarks_light.png
	src/java/android-filechooser/code/res/values-v11/themes_light.xml
	src/java/android-filechooser/code/res/values-v7/themes_light.xml
	src/java/android-filechooser/code/res/values/env.xml
	src/java/android-filechooser/code/src/group/pals/android/lib/ui/filechooser/FragmentFiles.java
	src/java/android-filechooser/code/src/group/pals/android/lib/ui/filechooser/providers/BaseFileProviderUtils.java
	src/java/android-filechooser/code/src/group/pals/android/lib/ui/filechooser/providers/bookmark/BookmarkContract.java
	src/java/android-filechooser/code/src/group/pals/android/lib/ui/filechooser/providers/bookmark/BookmarkHelper.java
	src/java/android-filechooser/code/src/group/pals/android/lib/ui/filechooser/providers/bookmark/BookmarkProvider.java
	src/java/android-filechooser/code/src/group/pals/android/lib/ui/filechooser/utils/Sys.java
	src/java/android-filechooser/code/src/group/pals/android/lib/ui/filechooser/utils/Utils.java
	src/java/android-filechooser/code/src/group/pals/android/lib/ui/filechooser/utils/ui/LoadingDialog.java
	src/java/android-filechooser/code/src/group/pals/android/lib/ui/filechooser/utils/ui/bookmark/BookmarkCursorAdapter.java
	src/java/android-filechooser/code/src/group/pals/android/lib/ui/filechooser/utils/ui/bookmark/BookmarkFragment.java
	src/java/android-filechooser/code/src/group/pals/android/lib/ui/filechooser/utils/ui/history/HistoryCursorAdapter.java
	src/java/android-filechooser/code/src/group/pals/android/lib/ui/filechooser/utils/ui/history/HistoryFragment.java
This commit is contained in:
Philipp Crocoll 2013-10-25 04:45:52 +02:00
commit 55da547141
47 changed files with 883 additions and 758 deletions

View File

@ -1,6 +1,6 @@
# android-filechooser # android-filechooser
* Version: 5.4 * Version: 5.4.4 beta
Feel free to contact us at: Feel free to contact us at:
@ -18,11 +18,31 @@ project. We hope this project will be always useful for everyone.
* C * C
* Simon McCorkindale * Simon McCorkindale
+ [Website](http://www.aroha.mobi/) + [Website](http://www.aroha.mobi/)
* Philipp Crocoll
+ Author of open source project [Keepass2Android](https://keepass2android.codeplex.com/)
* And others. * And others.
# HISTORY # HISTORY
* Version 5.4.4 beta:
+ *Initialize:* October 23, 2013
* Version 5.4.3:
+ *Release:* October 23, 2013
* Version 5.4.3 beta:
+ *Initialize:* September 30, 2013
* Version 5.4.2
+ *Release:* September 27, 2013
+ Fix light themes with dark action bar.
* Version 5.4.1
+ *Release:* September 26, 2013
+ Fix light themes: now they use light action bar.
+ Add light themes with dark action bar.
* Version 5.4 * Version 5.4
+ *Release:* August 02, 2013 + *Release:* August 02, 2013
+ Integrate library `android-support-v7-appcompat` for action bar in APIs + Integrate library `android-support-v7-appcompat` for action bar in APIs

View File

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<classpath> <classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="gen"/>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/> <classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/> <classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/> <classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="gen"/>
<classpathentry kind="output" path="bin/classes"/> <classpathentry kind="output" path="bin/classes"/>
</classpath> </classpath>

View File

@ -7,12 +7,10 @@
--> -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="group.pals.android.lib.ui.filechooser" package="group.pals.android.lib.ui.filechooser" >
android:versionCode="@integer/afc_lib_version_code"
android:versionName="@string/afc_lib_version_name" >
<uses-sdk <uses-sdk
android:minSdkVersion="4" android:minSdkVersion="4"
android:targetSdkVersion="17" /> android:targetSdkVersion="18" />
</manifest> </manifest>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 884 B

After

Width:  |  Height:  |  Size: 885 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 764 B

After

Width:  |  Height:  |  Size: 780 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 569 B

After

Width:  |  Height:  |  Size: 643 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 474 B

After

Width:  |  Height:  |  Size: 522 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 926 B

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -265,4 +265,5 @@ public class FileChooserActivity extends FragmentActivity {
return super.onKeyDown(keyCode, event); return super.onKeyDown(keyCode, event);
}// onKeyDown() }// onKeyDown()
} }

View File

@ -219,7 +219,7 @@ public class FragmentFiles extends Fragment implements
private View mBtnGoHome; private View mBtnGoHome;
private HorizontalScrollView mViewLocationsContainer; private HorizontalScrollView mViewLocationsContainer;
private ViewGroup mViewLocations; private ViewGroup mViewAddressBar;
private View mViewGroupFiles; private View mViewGroupFiles;
private ViewGroup mViewFilesContainer; private ViewGroup mViewFilesContainer;
private TextView mTxtFullDirName; private TextView mTxtFullDirName;
@ -304,7 +304,7 @@ public class FragmentFiles extends Fragment implements
.findViewById(R.id.afc_button_go_back); .findViewById(R.id.afc_button_go_back);
mViewGoForward = (ImageView) rootView mViewGoForward = (ImageView) rootView
.findViewById(R.id.afc_button_go_forward); .findViewById(R.id.afc_button_go_forward);
mViewLocations = (ViewGroup) rootView mViewAddressBar = (ViewGroup) rootView
.findViewById(R.id.afc_view_locations); .findViewById(R.id.afc_view_locations);
mViewLocationsContainer = (HorizontalScrollView) rootView mViewLocationsContainer = (HorizontalScrollView) rootView
.findViewById(R.id.afc_view_locations_container); .findViewById(R.id.afc_view_locations_container);
@ -412,7 +412,7 @@ public class FragmentFiles extends Fragment implements
if (item.getItemId() == R.id.afc_menuitem_sort) if (item.getItemId() == R.id.afc_menuitem_sort)
resortViewFiles(); resortViewFiles();
else if (item.getItemId() == R.id.afc_menuitem_new_folder) else if (item.getItemId() == R.id.afc_menuitem_new_folder)
createNewDir(); checkConditionsThenConfirmUserToCreateNewDir();
else if (item.getItemId() == R.id.afc_menuitem_switch_viewmode) else if (item.getItemId() == R.id.afc_menuitem_switch_viewmode)
switchViewType(); switchViewType();
else if (item.getItemId() == R.id.afc_menuitem_home) else if (item.getItemId() == R.id.afc_menuitem_home)
@ -466,8 +466,8 @@ public class FragmentFiles extends Fragment implements
getActivity().supportInvalidateOptionsMenu(); getActivity().supportInvalidateOptionsMenu();
Uri path = ((Uri) args.getParcelable(PATH)); final Uri path = ((Uri) args.getParcelable(PATH));
createLocationButtons(path); buildAddressBar(path);
String positiveRegex = getArguments().getString( String positiveRegex = getArguments().getString(
FileChooserActivity.EXTRA_POSITIVE_REGEX_FILTER); FileChooserActivity.EXTRA_POSITIVE_REGEX_FILTER);
@ -543,10 +543,28 @@ public class FragmentFiles extends Fragment implements
* Footer. * Footer.
*/ */
if (selectedFile != null && mIsSaveDialog if (selectedFile != null && mIsSaveDialog) {
&& BaseFileProviderUtils.isFile(getActivity(), selectedFile)) new LoadingDialog<Void, Void, String>(getActivity(), false) {
mTxtSaveas.setText(BaseFileProviderUtils.getFileName(getActivity(),
selectedFile)); @Override
protected String doInBackground(Void... params) {
if (BaseFileProviderUtils.isFile(getActivity(),
selectedFile))
return BaseFileProviderUtils.getFileName(getActivity(),
selectedFile);
return null;
}// doInBackground()
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
if (!TextUtils.isEmpty(result))
mTxtSaveas.setText(result);
}// onPostExecute()
}.execute();
}// if
boolean hasMoreFiles = ProviderUtils.getBooleanQueryParam(uriInfo, boolean hasMoreFiles = ProviderUtils.getBooleanQueryParam(uriInfo,
BaseFile.PARAM_HAS_MORE_FILES); BaseFile.PARAM_HAS_MORE_FILES);
@ -944,6 +962,17 @@ public class FragmentFiles extends Fragment implements
* 4. Last location. * 4. Last location.
*/ */
new LoadingDialog<Void, Uri, Bundle>(getActivity(), false) {
/**
* In onPostExecute(), if result is null then check this value. If
* this is not null, show a toast and finish. If this is null, call
* showCannotConnectToServiceAndWaitForTheUserToFinish().
*/
String errMsg = null;
@Override
protected Bundle doInBackground(Void... params) {
/* /*
* Current location * Current location
*/ */
@ -957,64 +986,85 @@ public class FragmentFiles extends Fragment implements
path = (Uri) getArguments().getParcelable( path = (Uri) getArguments().getParcelable(
FileChooserActivity.EXTRA_SELECT_FILE); FileChooserActivity.EXTRA_SELECT_FILE);
if (path != null if (path != null
&& BaseFileProviderUtils.fileExists(getActivity(), path)) && BaseFileProviderUtils.fileExists(getActivity(),
path = BaseFileProviderUtils.getParentFile(getActivity(), path); path))
path = BaseFileProviderUtils.getParentFile(
getActivity(), path);
} }
/* /*
* Rootpath * Rootpath
*/ */
if (path == null if (path == null
|| !BaseFileProviderUtils.isDirectory(getActivity(), path)) { || !BaseFileProviderUtils.isDirectory(getActivity(),
path)) {
path = mRoot; path = mRoot;
} }
/* /*
* Last location * Last location
*/ */
if (path == null && DisplayPrefs.isRememberLastLocation(getActivity())) { if (path == null
String lastLocation = DisplayPrefs.getLastLocation(getActivity()); && DisplayPrefs.isRememberLastLocation(getActivity())) {
String lastLocation = DisplayPrefs
.getLastLocation(getActivity());
if (lastLocation != null) if (lastLocation != null)
path = Uri.parse(lastLocation); path = Uri.parse(lastLocation);
} }
if (path == null if (path == null
|| !BaseFileProviderUtils.isDirectory(getActivity(), path)) || !BaseFileProviderUtils.isDirectory(getActivity(),
{ path))
Log.d(CLASSNAME, "load default path"); path = BaseFileProviderUtils.getDefaultPath(
path = BaseFileProviderUtils
.getDefaultPath(
getActivity(), getActivity(),
path == null ? mFileProviderAuthority : path path == null ? mFileProviderAuthority : path
.getAuthority()); .getAuthority());
}
if (path == null) { if (path == null)
showCannotConnectToServiceAndFinish(); return null;
return;
}
if (BuildConfig.DEBUG) if (BuildConfig.DEBUG)
Log.d(CLASSNAME, "loadInitialPath() >> " + path); Log.d(CLASSNAME, "loadInitialPath() >> " + path);
setCurrentLocation(path); publishProgress(path);
if (BaseFileProviderUtils.fileCanRead(getActivity(), path)) { if (BaseFileProviderUtils.fileCanRead(getActivity(), path)) {
/* Bundle result = new Bundle();
* Prepare the loader. Either re-connect with an existing one, or result.putParcelable(PATH, path);
* start a new one. return result;
*/
Bundle args = new Bundle();
args.putParcelable(PATH, path);
getLoaderManager().initLoader(mIdLoaderData, args, this);
} else { } else {
Dlg.toast( errMsg = getString(R.string.afc_pmsg_cannot_access_dir,
getActivity(),
getString(R.string.afc_pmsg_cannot_access_dir,
BaseFileProviderUtils.getFileName(getActivity(), BaseFileProviderUtils.getFileName(getActivity(),
path)), Dlg.LENGTH_SHORT); path));
getActivity().finish();
} }
return null;
}// doInBackground()
@Override
protected void onProgressUpdate(Uri... progress) {
setCurrentLocation(progress[0]);
}// onProgressUpdate()
@Override
protected void onPostExecute(Bundle result) {
super.onPostExecute(result);
if (result != null) {
/*
* Prepare the loader. Either re-connect with an existing
* one, or start a new one.
*/
getLoaderManager().initLoader(mIdLoaderData, result,
FragmentFiles.this);
} else if (errMsg != null) {
Dlg.toast(getActivity(), errMsg, Dlg.LENGTH_SHORT);
getActivity().finish();
} else
showCannotConnectToServiceAndWaitForTheUserToFinish();
}// onPostExecute()
}.execute();
}// loadInitialPath() }// loadInitialPath()
/** /**
@ -1044,7 +1094,7 @@ public class FragmentFiles extends Fragment implements
/** /**
* As the name means... * As the name means...
*/ */
private void showCannotConnectToServiceAndFinish() { private void showCannotConnectToServiceAndWaitForTheUserToFinish() {
Dlg.showError(getActivity(), Dlg.showError(getActivity(),
R.string.afc_msg_cannot_connect_to_file_provider_service, R.string.afc_msg_cannot_connect_to_file_provider_service,
new DialogInterface.OnCancelListener() { new DialogInterface.OnCancelListener() {
@ -1055,7 +1105,7 @@ public class FragmentFiles extends Fragment implements
getActivity().finish(); getActivity().finish();
}// onCancel() }// onCancel()
}); });
}// showCannotConnectToServiceAndFinish() }// showCannotConnectToServiceAndWaitForTheUserToFinish()
/** /**
* Gets last location. * Gets last location.
@ -1211,9 +1261,10 @@ public class FragmentFiles extends Fragment implements
}// switchViewType() }// switchViewType()
/** /**
* Confirms user to create new directory. * Checks current conditions to see if we can create new directory. Then
* confirms user to do so.
*/ */
private void createNewDir() { private void checkConditionsThenConfirmUserToCreateNewDir() {
if (LocalFileContract.getAuthority(getActivity()).equals( if (LocalFileContract.getAuthority(getActivity()).equals(
mFileProviderAuthority) mFileProviderAuthority)
&& !Utils.hasPermissions(getActivity(), && !Utils.hasPermissions(getActivity(),
@ -1225,15 +1276,34 @@ public class FragmentFiles extends Fragment implements
return; return;
} }
if (getCurrentLocation() == null new LoadingDialog<Void, Void, Boolean>(getActivity(), false) {
|| !BaseFileProviderUtils.fileCanWrite(getActivity(),
getCurrentLocation())) { @Override
protected Boolean doInBackground(Void... params) {
return getCurrentLocation() != null
&& BaseFileProviderUtils.fileCanWrite(getActivity(),
getCurrentLocation());
}// doInBackground()
@Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
if (result)
showNewDirectoryCreationDialog();
else
Dlg.toast(getActivity(), Dlg.toast(getActivity(),
R.string.afc_msg_cannot_create_new_folder_here, R.string.afc_msg_cannot_create_new_folder_here,
Dlg.LENGTH_SHORT); Dlg.LENGTH_SHORT);
return; }// onProgressUpdate()
}
}.execute();
}// checkConditionsThenConfirmUserToCreateNewDir()
/**
* Confirms user to create new directory.
*/
private void showNewDirectoryCreationDialog() {
final AlertDialog dialog = Dlg.newAlertDlg(getActivity()); final AlertDialog dialog = Dlg.newAlertDlg(getActivity());
View view = getLayoutInflater(null).inflate( View view = getLayoutInflater(null).inflate(
@ -1264,7 +1334,8 @@ public class FragmentFiles extends Fragment implements
@Override @Override
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
String name = textFile.getText().toString().trim(); final String name = textFile.getText().toString()
.trim();
if (!FileUtils.isFilenameValid(name)) { if (!FileUtils.isFilenameValid(name)) {
Dlg.toast( Dlg.toast(
getActivity(), getActivity(),
@ -1274,10 +1345,14 @@ public class FragmentFiles extends Fragment implements
return; return;
} }
if (BaseFileProviderUtils new LoadingDialog<Void, Void, Uri>(getActivity(), false) {
.insertInBackground(
getActivity(), @Override
BaseFile.genContentUriBase( protected Uri doInBackground(Void... params) {
return getActivity()
.getContentResolver()
.insert(BaseFile
.genContentUriBase(
getCurrentLocation() getCurrentLocation()
.getAuthority()) .getAuthority())
.buildUpon() .buildUpon()
@ -1290,7 +1365,14 @@ public class FragmentFiles extends Fragment implements
.appendQueryParameter( .appendQueryParameter(
BaseFile.PARAM_FILE_TYPE, BaseFile.PARAM_FILE_TYPE,
Integer.toString(BaseFile.FILE_TYPE_DIRECTORY)) Integer.toString(BaseFile.FILE_TYPE_DIRECTORY))
.build(), null) != null) { .build(), null);
}// doInBackground()
@Override
protected void onPostExecute(Uri result) {
super.onPostExecute(result);
if (result != null) {
Dlg.toast(getActivity(), Dlg.toast(getActivity(),
getString(R.string.afc_msg_done), getString(R.string.afc_msg_done),
Dlg.LENGTH_SHORT); Dlg.LENGTH_SHORT);
@ -1300,6 +1382,9 @@ public class FragmentFiles extends Fragment implements
getString( getString(
R.string.afc_pmsg_cannot_create_folder, R.string.afc_pmsg_cannot_create_folder,
name), Dlg.LENGTH_SHORT); name), Dlg.LENGTH_SHORT);
}// onPostExecute()
}.execute();
}// onClick() }// onClick()
}); });
dialog.show(); dialog.show();
@ -1314,22 +1399,26 @@ public class FragmentFiles extends Fragment implements
@Override @Override
public void onTextChanged(CharSequence s, int start, int before, public void onTextChanged(CharSequence s, int start, int before,
int count) { int count) {
// do nothing /*
} * Do nothing.
*/
}// onTextChanged()
@Override @Override
public void beforeTextChanged(CharSequence s, int start, int count, public void beforeTextChanged(CharSequence s, int start, int count,
int after) { int after) {
// do nothing /*
} * Do nothing.
*/
}// beforeTextChanged()
@Override @Override
public void afterTextChanged(Editable s) { public void afterTextChanged(Editable s) {
buttonOk.setEnabled(FileUtils.isFilenameValid(s.toString() buttonOk.setEnabled(FileUtils.isFilenameValid(s.toString()
.trim())); .trim()));
} }// afterTextChanged()
}); });
}// createNewDir() }// showNewDirectoryCreationDialog()
/** /**
* Deletes a file. * Deletes a file.
@ -1386,7 +1475,7 @@ public class FragmentFiles extends Fragment implements
@Override @Override
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
new LoadingDialog<Void, Void, Void>( new LoadingDialog<Void, Void, Boolean>(
getActivity(), getActivity(),
getString( getString(
R.string.afc_pmsg_deleting_file, R.string.afc_pmsg_deleting_file,
@ -1397,19 +1486,6 @@ public class FragmentFiles extends Fragment implements
final int taskId = EnvUtils.genId(); final int taskId = EnvUtils.genId();
private void notifyFileDeleted() { private void notifyFileDeleted() {
mHistory.removeAll(new HistoryFilter<Uri>() {
@Override
public boolean accept(Uri item) {
return !BaseFileProviderUtils
.isDirectory(getActivity(),
item);
}// accept()
});
/*
* TODO remove all duplicate items?
*/
Dlg.toast( Dlg.toast(
getActivity(), getActivity(),
getString( getString(
@ -1420,17 +1496,18 @@ public class FragmentFiles extends Fragment implements
}// notifyFileDeleted() }// notifyFileDeleted()
@Override @Override
protected Void doInBackground(Void... params) { protected Boolean doInBackground(Void... params) {
BaseFileProviderUtils getActivity()
.deleteInBackground( .getContentResolver()
getActivity(), .delete(uri
uri.buildUpon() .buildUpon()
.appendQueryParameter( .appendQueryParameter(
BaseFile.PARAM_TASK_ID, BaseFile.PARAM_TASK_ID,
Integer.toString(taskId)) Integer.toString(taskId))
.build(), null, null); .build(), null, null);
return null; return !BaseFileProviderUtils.fileExists(
getActivity(), uri);
}// doInBackground() }// doInBackground()
@Override @Override
@ -1440,24 +1517,42 @@ public class FragmentFiles extends Fragment implements
getActivity(), getCurrentLocation() getActivity(), getCurrentLocation()
.getAuthority(), taskId); .getAuthority(), taskId);
if (BaseFileProviderUtils.fileExists( new LoadingDialog<Void, Void, Boolean>(
getActivity(), uri)) { getActivity(), false) {
mFileAdapter.markItemAsDeleted(id, false);
@Override
protected Boolean doInBackground(
Void... params) {
return BaseFileProviderUtils
.fileExists(getActivity(), uri);
}// doInBackground()
@Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
if (result) {
mFileAdapter.markItemAsDeleted(id,
false);
Dlg.toast(getActivity(), Dlg.toast(getActivity(),
R.string.afc_msg_cancelled, R.string.afc_msg_cancelled,
Dlg.LENGTH_SHORT); Dlg.LENGTH_SHORT);
} else } else
notifyFileDeleted(); notifyFileDeleted();
}// onPostExecute()
}.execute();
super.onCancelled(); super.onCancelled();
}// onCancelled() }// onCancelled()
@Override @Override
protected void onPostExecute(Void result) { protected void onPostExecute(Boolean result) {
super.onPostExecute(result); super.onPostExecute(result);
if (BaseFileProviderUtils.fileExists( if (result) {
getActivity(), uri)) { notifyFileDeleted();
} else {
mFileAdapter.markItemAsDeleted(id, false); mFileAdapter.markItemAsDeleted(id, false);
Dlg.toast( Dlg.toast(
getActivity(), getActivity(),
@ -1466,9 +1561,9 @@ public class FragmentFiles extends Fragment implements
isFile ? getString(R.string.afc_file) isFile ? getString(R.string.afc_file)
: getString(R.string.afc_folder), : getString(R.string.afc_folder),
filename), Dlg.LENGTH_SHORT); filename), Dlg.LENGTH_SHORT);
} else }
notifyFileDeleted();
}// onPostExecute() }// onPostExecute()
}.execute();// LoadingDialog }.execute();// LoadingDialog
}// onClick() }// onClick()
}, new DialogInterface.OnCancelListener() { }, new DialogInterface.OnCancelListener() {
@ -1484,72 +1579,99 @@ public class FragmentFiles extends Fragment implements
* As the name means. * As the name means.
* *
* @param filename * @param filename
* @since v1.91 * the file name.
*/ */
private void checkSaveasFilenameAndFinish(String filename) { private void checkSaveasFilenameAndFinish(final String filename) {
new LoadingDialog<Void, String, Uri>(getActivity(), false) {
int fileType;
@Override
protected Uri doInBackground(Void... params) {
if (!BaseFileProviderUtils.fileCanWrite(getActivity(), if (!BaseFileProviderUtils.fileCanWrite(getActivity(),
getCurrentLocation())) { getCurrentLocation())) {
Dlg.toast(getActivity(), publishProgress(getString(R.string.afc_msg_cannot_save_a_file_here));
getString(R.string.afc_msg_cannot_save_a_file_here), return null;
Dlg.LENGTH_SHORT);
return;
} }
if (TextUtils.isEmpty(filename) || !FileUtils.isFilenameValid(filename)) { if (TextUtils.isEmpty(filename)
Dlg.toast(getActivity(), || !FileUtils.isFilenameValid(filename)) {
getString(R.string.afc_pmsg_filename_is_invalid, filename), publishProgress(getString(
Dlg.LENGTH_SHORT); R.string.afc_pmsg_filename_is_invalid, filename));
return; return null;
} }
final Cursor cursor = BaseFileProviderUtils.queryInBackground( final Cursor cursor = getActivity().getContentResolver().query(
getActivity(),
getCurrentLocation() getCurrentLocation()
.buildUpon() .buildUpon()
.appendQueryParameter(BaseFile.PARAM_APPEND_NAME, .appendQueryParameter(
filename).build(), null, null, null, null); BaseFile.PARAM_APPEND_NAME, filename)
if (cursor != null) { .build(), null, null, null, null);
try { try {
if (cursor.moveToFirst()) { if (cursor == null || !cursor.moveToFirst())
final Uri uri = BaseFileProviderUtils.getUri(cursor); return null;
switch (cursor.getInt(cursor
.getColumnIndex(BaseFile.COLUMN_TYPE))) { fileType = cursor.getInt(cursor
case BaseFile.FILE_TYPE_DIRECTORY: .getColumnIndex(BaseFile.COLUMN_TYPE));
return BaseFileProviderUtils.getUri(cursor);
} finally {
if (cursor != null)
cursor.close();
}
}// doInBackground()
@Override
protected void onProgressUpdate(String... progress) {
Dlg.toast(getActivity(), progress[0], Dlg.LENGTH_SHORT);
}// onProgressUpdate()
@Override
protected void onPostExecute(final Uri result) {
super.onPostExecute(result);
if (result == null) {
/*
* TODO ?
*/
return;
}
switch (fileType) {
case BaseFile.FILE_TYPE_DIRECTORY: {
Dlg.toast( Dlg.toast(
getActivity(), getActivity(),
getString( getString(R.string.afc_pmsg_filename_is_directory,
R.string.afc_pmsg_filename_is_directory,
filename), Dlg.LENGTH_SHORT); filename), Dlg.LENGTH_SHORT);
break;// FILE_TYPE_DIRECTORY break;
}// FILE_TYPE_DIRECTORY
case BaseFile.FILE_TYPE_FILE: case BaseFile.FILE_TYPE_FILE: {
Dlg.confirmYesno( Dlg.confirmYesno(
getActivity(), getActivity(),
getString( getString(R.string.afc_pmsg_confirm_replace_file,
R.string.afc_pmsg_confirm_replace_file,
filename), filename),
new DialogInterface.OnClickListener() { new DialogInterface.OnClickListener() {
@Override @Override
public void onClick(DialogInterface dialog, public void onClick(DialogInterface dialog,
int which) { int which) {
finish(uri); finish(result);
}// onClick() }// onClick()
}); });
break;// FILE_TYPE_FILE break;
}// FILE_TYPE_FILE
case BaseFile.FILE_TYPE_NOT_EXISTED: case BaseFile.FILE_TYPE_NOT_EXISTED: {
/* /*
* TODO file type unknown? * TODO file type unknown?
*/ */
finish(uri); finish(result);
break;// FILE_TYPE_NOT_EXISTED break;
} }// FILE_TYPE_NOT_EXISTED
}
} finally {
cursor.close();
}
} }
}// onPostExecute()
}.execute();
}// checkSaveasFilenameAndFinish() }// checkSaveasFilenameAndFinish()
/** /**
@ -1557,47 +1679,68 @@ public class FragmentFiles extends Fragment implements
* *
* @param dir * @param dir
* a directory, of course. * a directory, of course.
* @return {@code true} if {@code dir} <b><i>can</i></b> be browsed to.
* @since v4.3 beta * @since v4.3 beta
*/ */
private boolean goTo(Uri dir) { private void goTo(Uri dir) {
if (dir == null) new LoadingDialog<Uri, String, Bundle>(getActivity(), false) {
dir = BaseFileProviderUtils.getDefaultPath(getActivity(),
mFileProviderAuthority); /**
if (dir == null) { * In onPostExecute(), if result is null then check this value. If
showCannotConnectToServiceAndFinish(); * this is not null, show a toast. If this is null, call
return false; * showCannotConnectToServiceAndWaitForTheUserToFinish().
} */
String errMsg = null;
@Override
protected Bundle doInBackground(Uri... params) {
if (params[0] == null)
params[0] = BaseFileProviderUtils.getDefaultPath(
getActivity(), mFileProviderAuthority);
if (params[0] == null)
return null;
/* /*
* Check if the path of `dir` is same as current location, then set * Check if the path of `params[0]` is same as current location,
* `dir` to current location. This avoids of pushing two same paths into * then set `params[0]` to current location. This avoids of
* history, because we compare the pointers (not the paths) when pushing * pushing two same paths into history, because we compare the
* it to history. * pointers (not the paths) when pushing it to history.
*/ */
if (dir.equals(getCurrentLocation())) if (params[0].equals(getCurrentLocation()))
dir = getCurrentLocation(); params[0] = getCurrentLocation();
if (BaseFileProviderUtils.fileCanRead(getActivity(), dir)) { if (BaseFileProviderUtils.fileCanRead(getActivity(), params[0])) {
/* /*
* Cancel previous loader if there is one. * Cancel previous loader if there is one.
*/ */
cancelPreviousLoader(); cancelPreviousLoader();
setCurrentLocation(dir); Bundle bundle = new Bundle();
bundle.putParcelable(PATH, params[0]);
return bundle;
}// if
Bundle b = new Bundle(); errMsg = getString(R.string.afc_pmsg_cannot_access_dir,
b.putParcelable(PATH, dir); BaseFileProviderUtils.getFileName(getActivity(),
getLoaderManager().restartLoader(mIdLoaderData, b, this); params[0]));
return true;
}
Dlg.toast( return null;
getActivity(), }// doInBackground()
getString(R.string.afc_pmsg_cannot_access_dir,
BaseFileProviderUtils.getFileName(getActivity(), dir)), @Override
Dlg.LENGTH_SHORT); protected void onPostExecute(Bundle result) {
return false; super.onPostExecute(result);
if (result != null) {
setCurrentLocation((Uri) result.getParcelable(PATH));
getLoaderManager().restartLoader(mIdLoaderData, result,
FragmentFiles.this);
} else if (errMsg != null)
Dlg.toast(getActivity(), errMsg, Dlg.LENGTH_SHORT);
else
showCannotConnectToServiceAndWaitForTheUserToFinish();
}// onPostExecute()
}.execute(dir);
}// goTo() }// goTo()
/** /**
@ -1664,71 +1807,66 @@ public class FragmentFiles extends Fragment implements
/** /**
* As the name means. * As the name means.
*/ */
private void createLocationButtons(Uri path) { private void buildAddressBar(final Uri path) {
if (path == null) if (path == null)
return; return;
mViewLocations.removeAllViews(); mViewAddressBar.removeAllViews();
LinearLayout.LayoutParams lpBtnLoc = new LinearLayout.LayoutParams( new LoadingDialog<Void, Cursor, Void>(getActivity(), false) {
LinearLayout.LayoutParams lpBtnLoc;
LinearLayout.LayoutParams lpDivider;
LayoutInflater inflater = getLayoutInflater(null);
final int dim = getResources().getDimensionPixelSize(
R.dimen.afc_5dp);
int count = 0;
@Override
protected void onPreExecute() {
super.onPreExecute();
lpBtnLoc = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT); LinearLayout.LayoutParams.WRAP_CONTENT);
lpBtnLoc.gravity = Gravity.CENTER; lpBtnLoc.gravity = Gravity.CENTER;
LinearLayout.LayoutParams lpDivider = null; }// onPreExecute()
LayoutInflater inflater = getLayoutInflater(null);
final int dim = getResources().getDimensionPixelSize(R.dimen.afc_5dp);
int count = 0;
Cursor cursor = BaseFileProviderUtils.queryInBackground(getActivity(), @Override
path, null, null, null, null); protected Void doInBackground(Void... params) {
Cursor cursor = getActivity().getContentResolver().query(path,
null, null, null, null);
while (cursor != null) { while (cursor != null) {
Uri lastUri = null;
if (cursor.moveToFirst()) { if (cursor.moveToFirst()) {
lastUri = Uri.parse(cursor.getString(cursor publishProgress(cursor);
.getColumnIndex(BaseFile.COLUMN_URI)));
TextView btnLoc = (TextView) inflater.inflate(
R.layout.afc_button_location, null);
String name = BaseFileProviderUtils.getFileName(cursor);
btnLoc.setText(TextUtils.isEmpty(name) ? getString(R.string.afc_root)
: name);
btnLoc.setTag(lastUri);
btnLoc.setOnClickListener(mBtnLocationOnClickListener);
btnLoc.setOnLongClickListener(mBtnLocationOnLongClickListener);
mViewLocations.addView(btnLoc, 0, lpBtnLoc);
if (count++ == 0) {
Rect r = new Rect();
btnLoc.getPaint().getTextBounds(name, 0, name.length(), r);
if (r.width() >= getResources().getDimensionPixelSize(
R.dimen.afc_button_location_max_width)
- btnLoc.getPaddingLeft()
- btnLoc.getPaddingRight()) {
mTxtFullDirName.setText(cursor.getString(cursor
.getColumnIndex(BaseFile.COLUMN_NAME)));
mTxtFullDirName.setVisibility(View.VISIBLE);
} else
mTxtFullDirName.setVisibility(View.GONE);
}
}
cursor.close(); cursor.close();
} else
if (lastUri == null)
break; break;
/* /*
* Process the parent directory. * Process the parent directory.
*/ */
cursor = BaseFileProviderUtils.queryInBackground( Uri uri = Uri.parse(cursor.getString(cursor
getActivity(), .getColumnIndex(BaseFile.COLUMN_URI)));
BaseFile.genContentUriApi(lastUri.getAuthority()) cursor = getActivity().getContentResolver().query(
BaseFile.genContentUriApi(uri.getAuthority())
.buildUpon() .buildUpon()
.appendPath(BaseFile.CMD_GET_PARENT) .appendPath(BaseFile.CMD_GET_PARENT)
.appendQueryParameter(BaseFile.PARAM_SOURCE, .appendQueryParameter(
lastUri.getLastPathSegment()).build(), BaseFile.PARAM_SOURCE,
uri.getLastPathSegment()).build(),
null, null, null, null); null, null, null, null);
if (cursor != null) { }// while
return null;
}// doInBackground()
@Override
protected void onProgressUpdate(Cursor... progress) {
/*
* Add divider.
*/
if (mViewAddressBar.getChildCount() > 0) {
View divider = inflater.inflate( View divider = inflater.inflate(
R.layout.afc_view_locations_divider, null); R.layout.afc_view_locations_divider, null);
@ -1737,10 +1875,42 @@ public class FragmentFiles extends Fragment implements
lpDivider.gravity = Gravity.CENTER; lpDivider.gravity = Gravity.CENTER;
lpDivider.setMargins(dim, dim, dim, dim); lpDivider.setMargins(dim, dim, dim, dim);
} }
mViewLocations.addView(divider, 0, lpDivider); mViewAddressBar.addView(divider, 0, lpDivider);
}
} }
Uri lastUri = Uri.parse(progress[0].getString(progress[0]
.getColumnIndex(BaseFile.COLUMN_URI)));
TextView btnLoc = (TextView) inflater.inflate(
R.layout.afc_button_location, null);
String name = BaseFileProviderUtils.getFileName(progress[0]);
btnLoc.setText(TextUtils.isEmpty(name) ? getString(R.string.afc_root)
: name);
btnLoc.setTag(lastUri);
btnLoc.setOnClickListener(mBtnLocationOnClickListener);
btnLoc.setOnLongClickListener(mBtnLocationOnLongClickListener);
mViewAddressBar.addView(btnLoc, 0, lpBtnLoc);
if (count++ == 0) {
Rect r = new Rect();
btnLoc.getPaint().getTextBounds(name, 0, name.length(), r);
if (r.width() >= getResources().getDimensionPixelSize(
R.dimen.afc_button_location_max_width)
- btnLoc.getPaddingLeft()
- btnLoc.getPaddingRight()) {
mTxtFullDirName.setText(progress[0]
.getString(progress[0]
.getColumnIndex(BaseFile.COLUMN_NAME)));
mTxtFullDirName.setVisibility(View.VISIBLE);
} else
mTxtFullDirName.setVisibility(View.GONE);
}// if
}// onProgressUpdate()
@Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
/* /*
* Sometimes without delay time, it doesn't work... * Sometimes without delay time, it doesn't work...
*/ */
@ -1749,9 +1919,12 @@ public class FragmentFiles extends Fragment implements
public void run() { public void run() {
mViewLocationsContainer mViewLocationsContainer
.fullScroll(HorizontalScrollView.FOCUS_RIGHT); .fullScroll(HorizontalScrollView.FOCUS_RIGHT);
} }// run()
}, DisplayPrefs.DELAY_TIME_FOR_VERY_SHORT_ANIMATION); }, DisplayPrefs.DELAY_TIME_FOR_VERY_SHORT_ANIMATION);
}// createLocationButtons() }// onPostExecute()
}.execute();
}// buildAddressBar()
/** /**
* Finishes this activity. * Finishes this activity.
@ -1794,8 +1967,10 @@ public class FragmentFiles extends Fragment implements
getActivity().finish(); getActivity().finish();
}// finish() }// finish()
/** /*
* ******************************************************* BUTTON LISTENERS * =========================================================================
* BUTTON LISTENERS
* =========================================================================
*/ */
private final View.OnClickListener mBtnGoHomeOnClickListener = new View.OnClickListener() { private final View.OnClickListener mBtnGoHomeOnClickListener = new View.OnClickListener() {
@ -1974,6 +2149,7 @@ public class FragmentFiles extends Fragment implements
};// mViewFilesOnItemLongClickListener };// mViewFilesOnItemLongClickListener
/** /**
* We use a {@link LoadingDialog} to avoid of * We use a {@link LoadingDialog} to avoid of
* {@code NetworkOnMainThreadException}. * {@code NetworkOnMainThreadException}.
@ -1991,7 +2167,7 @@ public class FragmentFiles extends Fragment implements
mFileSelector.cancel(true); mFileSelector.cancel(true);
mFileSelector = new LoadingDialog<Void, Void, Integer>(getActivity(), mFileSelector = new LoadingDialog<Void, Void, Integer>(getActivity(),
R.string.afc_msg_loading, true) { true) {
@Override @Override
protected Integer doInBackground(Void... params) { protected Integer doInBackground(Void... params) {
@ -2071,8 +2247,10 @@ public class FragmentFiles extends Fragment implements
/* /*
* Use a Runnable to make sure this works. Because if the list * Use a Runnable to make sure this works. Because if the list
* view is handling data, this might not work. * view is handling data, this might not work.
*
* Also sometimes it doesn't work without a delay.
*/ */
mViewFiles.post(new Runnable() { mViewFiles.postDelayed(new Runnable() {
@Override @Override
public void run() { public void run() {
@ -2081,8 +2259,9 @@ public class FragmentFiles extends Fragment implements
else if (!mFileAdapter.isEmpty()) else if (!mFileAdapter.isEmpty())
mViewFiles.setSelection(0); mViewFiles.setSelection(0);
}// run() }// run()
}); }, DisplayPrefs.DELAY_TIME_FOR_VERY_SHORT_ANIMATION);
}// onPostExecute() }// onPostExecute()
}; };
mFileSelector.execute(); mFileSelector.execute();

View File

@ -7,10 +7,10 @@
package group.pals.android.lib.ui.filechooser.prefs; package group.pals.android.lib.ui.filechooser.prefs;
import android.content.Context;
import group.pals.android.lib.ui.filechooser.FileChooserActivity.ViewType; import group.pals.android.lib.ui.filechooser.FileChooserActivity.ViewType;
import group.pals.android.lib.ui.filechooser.R; import group.pals.android.lib.ui.filechooser.R;
import group.pals.android.lib.ui.filechooser.providers.basefile.BaseFileContract.BaseFile; import group.pals.android.lib.ui.filechooser.providers.basefile.BaseFileContract.BaseFile;
import android.content.Context;
/** /**
* Display preferences. * Display preferences.
@ -44,7 +44,8 @@ public class DisplayPrefs extends Prefs {
/** /**
* Gets view type. * Gets view type.
* *
* @param c {@link Context} * @param c
* {@link Context}
* @return {@link ViewType} * @return {@link ViewType}
*/ */
public static ViewType getViewType(Context c) { public static ViewType getViewType(Context c) {
@ -58,8 +59,10 @@ public class DisplayPrefs extends Prefs {
/** /**
* Sets view type. * Sets view type.
* *
* @param c {@link Context} * @param c
* @param v {@link ViewType}, if {@code null}, default value will be used. * {@link Context}
* @param v
* {@link ViewType}, if {@code null}, default value will be used.
*/ */
public static void setViewType(Context c, ViewType v) { public static void setViewType(Context c, ViewType v) {
String key = c.getString(R.string.afc_pkey_display_view_type); String key = c.getString(R.string.afc_pkey_display_view_type);
@ -76,7 +79,8 @@ public class DisplayPrefs extends Prefs {
/** /**
* Gets sort type. * Gets sort type.
* *
* @param c {@link Context} * @param c
* {@link Context}
* @return one of {@link BaseFile#SORT_BY_MODIFICATION_TIME}, * @return one of {@link BaseFile#SORT_BY_MODIFICATION_TIME},
* {@link BaseFile#SORT_BY_NAME}, {@link BaseFile#SORT_BY_SIZE}. * {@link BaseFile#SORT_BY_NAME}, {@link BaseFile#SORT_BY_SIZE}.
*/ */
@ -90,8 +94,10 @@ public class DisplayPrefs extends Prefs {
/** /**
* Sets {@link SortType} * Sets {@link SortType}
* *
* @param c {@link Context} * @param c
* @param v one of {@link BaseFile#SORT_BY_MODIFICATION_TIME}, * {@link Context}
* @param v
* one of {@link BaseFile#SORT_BY_MODIFICATION_TIME},
* {@link BaseFile#SORT_BY_NAME}, {@link BaseFile#SORT_BY_SIZE}., * {@link BaseFile#SORT_BY_NAME}, {@link BaseFile#SORT_BY_SIZE}.,
* if {@code null}, default value will be used. * if {@code null}, default value will be used.
*/ */
@ -110,7 +116,8 @@ public class DisplayPrefs extends Prefs {
/** /**
* Gets sort ascending. * Gets sort ascending.
* *
* @param c {@link Context} * @param c
* {@link Context}
* @return {@code true} if sort is ascending, {@code false} otherwise. * @return {@code true} if sort is ascending, {@code false} otherwise.
*/ */
public static boolean isSortAscending(Context c) { public static boolean isSortAscending(Context c) {
@ -123,8 +130,10 @@ public class DisplayPrefs extends Prefs {
/** /**
* Sets sort ascending. * Sets sort ascending.
* *
* @param c {@link Context} * @param c
* @param v {@link Boolean}, if {@code null}, default value will be used. * {@link Context}
* @param v
* {@link Boolean}, if {@code null}, default value will be used.
*/ */
public static void setSortAscending(Context c, Boolean v) { public static void setSortAscending(Context c, Boolean v) {
if (v == null) if (v == null)
@ -140,7 +149,8 @@ public class DisplayPrefs extends Prefs {
* Checks setting of showing time for old days in this year. Default is * Checks setting of showing time for old days in this year. Default is
* {@code false}. * {@code false}.
* *
* @param c {@link Context}. * @param c
* {@link Context}.
* @return {@code true} or {@code false}. * @return {@code true} or {@code false}.
* @since v4.7 beta * @since v4.7 beta
*/ */
@ -156,8 +166,10 @@ public class DisplayPrefs extends Prefs {
/** /**
* Enables or disables showing time of old days in this year. * Enables or disables showing time of old days in this year.
* *
* @param c {@link Context}. * @param c
* @param v your preferred flag. If {@code null}, default will be used ( * {@link Context}.
* @param v
* your preferred flag. If {@code null}, default will be used (
* {@code false}). * {@code false}).
* @since v4.7 beta * @since v4.7 beta
*/ */
@ -176,7 +188,8 @@ public class DisplayPrefs extends Prefs {
* Checks setting of showing time for old days in last year and older. * Checks setting of showing time for old days in last year and older.
* Default is {@code false}. * Default is {@code false}.
* *
* @param c {@link Context}. * @param c
* {@link Context}.
* @return {@code true} or {@code false}. * @return {@code true} or {@code false}.
* @since v4.7 beta * @since v4.7 beta
*/ */
@ -190,8 +203,10 @@ public class DisplayPrefs extends Prefs {
/** /**
* Enables or disables showing time of old days in last year and older. * Enables or disables showing time of old days in last year and older.
* *
* @param c {@link Context}. * @param c
* @param v your preferred flag. If {@code null}, default will be used ( * {@link Context}.
* @param v
* your preferred flag. If {@code null}, default will be used (
* {@code false}). * {@code false}).
* @since v4.7 beta * @since v4.7 beta
*/ */
@ -208,7 +223,8 @@ public class DisplayPrefs extends Prefs {
/** /**
* Checks if remembering last location is enabled or not. * Checks if remembering last location is enabled or not.
* *
* @param c {@link Context}. * @param c
* {@link Context}.
* @return {@code true} if remembering last location is enabled. * @return {@code true} if remembering last location is enabled.
* @since v4.7 beta * @since v4.7 beta
*/ */
@ -219,8 +235,10 @@ public class DisplayPrefs extends Prefs {
/** /**
* Enables or disables remembering last location. * Enables or disables remembering last location.
* *
* @param c {@link Context}. * @param c
* @param v your preferred flag. If {@code null}, default will be used ( * {@link Context}.
* @param v
* your preferred flag. If {@code null}, default will be used (
* {@code true}). * {@code true}).
* @since v4.7 beta * @since v4.7 beta
*/ */
@ -237,7 +255,8 @@ public class DisplayPrefs extends Prefs {
/** /**
* Gets last location. * Gets last location.
* *
* @param c {@link Context}. * @param c
* {@link Context}.
* @return the last location, or {@code null} if not available. * @return the last location, or {@code null} if not available.
* @since v4.7 beta * @since v4.7 beta
*/ */
@ -249,8 +268,10 @@ public class DisplayPrefs extends Prefs {
/** /**
* Sets last location. * Sets last location.
* *
* @param c {@link Context}. * @param c
* @param v the last location. * {@link Context}.
* @param v
* the last location.
*/ */
public static void setLastLocation(Context c, String v) { public static void setLastLocation(Context c, String v) {
p(c).edit() p(c).edit()
@ -273,8 +294,8 @@ public class DisplayPrefs extends Prefs {
*/ */
public static class FileTimeDisplay { public static class FileTimeDisplay {
private boolean mShowTimeForOldDaysThisYear; public boolean showTimeForOldDaysThisYear;
private boolean mShowTimeForOldDays; public boolean showTimeForOldDays;
/** /**
* Creates new instance. * Creates new instance.
@ -284,26 +305,9 @@ public class DisplayPrefs extends Prefs {
*/ */
public FileTimeDisplay(boolean showTimeForOldDaysThisYear, public FileTimeDisplay(boolean showTimeForOldDaysThisYear,
boolean showTimeForOldDays) { boolean showTimeForOldDays) {
mShowTimeForOldDaysThisYear = showTimeForOldDaysThisYear; this.showTimeForOldDaysThisYear = showTimeForOldDaysThisYear;
mShowTimeForOldDays = showTimeForOldDays; this.showTimeForOldDays = showTimeForOldDays;
}// FileTimeDisplay() }// FileTimeDisplay()
public boolean isShowTimeForOldDaysThisYear() {
return mShowTimeForOldDaysThisYear;
}// isShowTimeForOldDaysThisYear()
public FileTimeDisplay setShowTimeForOldDaysThisYear(boolean v) {
mShowTimeForOldDaysThisYear = v;
return this;
}// setShowTimeForOldDaysThisYear()
public boolean isShowTimeForOldDays() {
return mShowTimeForOldDays;
}// isShowTimeForOldDays()
public FileTimeDisplay setShowTimeForOldDays(boolean v) {
mShowTimeForOldDays = v;
return this;
}// setShowTimeForOldDays()
}// FileTimeDisplay }// FileTimeDisplay
} }

View File

@ -32,4 +32,5 @@ public interface BaseColumns extends android.provider.BaseColumns {
* </P> * </P>
*/ */
public static final String COLUMN_MODIFICATION_TIME = "modification_time"; public static final String COLUMN_MODIFICATION_TIME = "modification_time";
} }

View File

@ -16,14 +16,11 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context; import android.content.Context;
import android.database.Cursor; import android.database.Cursor;
import android.database.MatrixCursor; import android.database.MatrixCursor;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log;
/** /**
* Utilities for base file provider. * Utilities for base file provider.
@ -118,9 +115,10 @@ public class BaseFileProviderUtils {
String result = getProviderName(providerId); String result = getProviderName(providerId);
if (result == null) { if (result == null) {
Cursor cursor = queryInBackground( Cursor cursor = context
context, .getContentResolver()
BaseFile.genContentUriApi(getProviderAuthority(providerId)), .query(BaseFile
.genContentUriApi(getProviderAuthority(providerId)),
null, null, null, null); null, null, null, null);
if (cursor == null) if (cursor == null)
return null; return null;
@ -167,9 +165,10 @@ public class BaseFileProviderUtils {
int attr = MAP_PROVIDER_INFO.get(providerId).getInt( int attr = MAP_PROVIDER_INFO.get(providerId).getInt(
BaseFile.COLUMN_PROVIDER_ICON_ATTR); BaseFile.COLUMN_PROVIDER_ICON_ATTR);
if (attr == 0) { if (attr == 0) {
Cursor cursor = queryInBackground( Cursor cursor = context
context, .getContentResolver()
BaseFile.genContentUriApi(getProviderAuthority(providerId)), .query(BaseFile
.genContentUriApi(getProviderAuthority(providerId)),
null, null, null, null); null, null, null, null);
if (cursor != null) { if (cursor != null) {
try { try {
@ -250,8 +249,8 @@ public class BaseFileProviderUtils {
* otherwise. * otherwise.
*/ */
public static boolean isDirectory(Context context, Uri uri) { public static boolean isDirectory(Context context, Uri uri) {
//Log.d("AFC", "isDir? "+uri.toString()); Cursor cursor = context.getContentResolver().query(uri, null, null,
Cursor cursor = queryInBackground(context, uri, null, null, null, null); null, null);
if (cursor == null) if (cursor == null)
return false; return false;
@ -286,8 +285,8 @@ public class BaseFileProviderUtils {
* @return {@code true} if {@code uri} is a file, {@code false} otherwise. * @return {@code true} if {@code uri} is a file, {@code false} otherwise.
*/ */
public static boolean isFile(Context context, Uri uri) { public static boolean isFile(Context context, Uri uri) {
//Log.d("AFC", "isFile? "+uri.toString()); Cursor cursor = context.getContentResolver().query(uri, null, null,
Cursor cursor = queryInBackground(context, uri, null, null, null, null); null, null);
if (cursor == null) if (cursor == null)
return false; return false;
@ -321,8 +320,8 @@ public class BaseFileProviderUtils {
* @return the file name if {@code uri} is a file, {@code null} otherwise. * @return the file name if {@code uri} is a file, {@code null} otherwise.
*/ */
public static String getFileName(Context context, Uri uri) { public static String getFileName(Context context, Uri uri) {
//Log.d("AFC", "getFileName "+uri.toString()); Cursor cursor = context.getContentResolver().query(uri, null, null,
Cursor cursor = queryInBackground(context, uri, null, null, null, null); null, null);
if (cursor == null) if (cursor == null)
return null; return null;
@ -359,8 +358,8 @@ public class BaseFileProviderUtils {
* @return the real URI of {@code uri}. * @return the real URI of {@code uri}.
*/ */
public static Uri getRealUri(Context context, Uri uri) { public static Uri getRealUri(Context context, Uri uri) {
//Log.d("AFC", "getRealUri "+uri.toString()); Cursor cursor = context.getContentResolver().query(uri, null, null,
Cursor cursor = queryInBackground(context, uri, null, null, null, null); null, null);
if (cursor == null) if (cursor == null)
return null; return null;
@ -400,8 +399,8 @@ public class BaseFileProviderUtils {
* {@link #FILE_TYPE_UNKNOWN}, {@link #FILE_TYPE_NOT_EXISTED}. * {@link #FILE_TYPE_UNKNOWN}, {@link #FILE_TYPE_NOT_EXISTED}.
*/ */
public static int getFileType(Context context, Uri uri) { public static int getFileType(Context context, Uri uri) {
//Log.d("AFC", "filetype? "+uri.toString()); Cursor cursor = context.getContentResolver().query(uri, null, null,
Cursor cursor = queryInBackground(context, uri, null, null, null, null); null, null);
if (cursor == null) if (cursor == null)
return BaseFile.FILE_TYPE_NOT_EXISTED; return BaseFile.FILE_TYPE_NOT_EXISTED;
@ -449,8 +448,8 @@ public class BaseFileProviderUtils {
* @return {@code true} or {@code false}. * @return {@code true} or {@code false}.
*/ */
public static boolean fileExists(Context context, Uri uri) { public static boolean fileExists(Context context, Uri uri) {
//Log.d("AFC", "exists? "+uri.toString()); Cursor cursor = context.getContentResolver().query(uri, null, null,
Cursor cursor = queryInBackground(context, uri, null, null, null, null); null, null);
if (cursor == null) if (cursor == null)
return false; return false;
@ -474,8 +473,8 @@ public class BaseFileProviderUtils {
* @return {@code true} or {@code false}. * @return {@code true} or {@code false}.
*/ */
public static boolean fileCanRead(Context context, Uri uri) { public static boolean fileCanRead(Context context, Uri uri) {
//Log.d("AFC", "canread? "+uri.toString()); Cursor cursor = context.getContentResolver().query(uri, null, null,
Cursor cursor = queryInBackground(context, uri, null, null, null, null); null, null);
if (cursor == null) if (cursor == null)
return false; return false;
@ -511,8 +510,8 @@ public class BaseFileProviderUtils {
* @return {@code true} or {@code false}. * @return {@code true} or {@code false}.
*/ */
public static boolean fileCanWrite(Context context, Uri uri) { public static boolean fileCanWrite(Context context, Uri uri) {
//Log.d("AFC", "canWrite? "+uri.toString()); Cursor cursor = context.getContentResolver().query(uri, null, null,
Cursor cursor = queryInBackground(context, uri, null, null, null, null); null, null);
if (cursor == null) if (cursor == null)
return false; return false;
@ -548,8 +547,7 @@ public class BaseFileProviderUtils {
* @return the default path, can be {@code null}. * @return the default path, can be {@code null}.
*/ */
public static Uri getDefaultPath(Context context, String authority) { public static Uri getDefaultPath(Context context, String authority) {
Cursor cursor = queryInBackground( Cursor cursor = context.getContentResolver().query(
context,
BaseFile.genContentUriApi(authority).buildUpon() BaseFile.genContentUriApi(authority).buildUpon()
.appendPath(BaseFile.CMD_GET_DEFAULT_PATH).build(), .appendPath(BaseFile.CMD_GET_DEFAULT_PATH).build(),
null, null, null, null); null, null, null, null);
@ -576,8 +574,7 @@ public class BaseFileProviderUtils {
* @return the parent file if it exists, {@code null} otherwise. * @return the parent file if it exists, {@code null} otherwise.
*/ */
public static Uri getParentFile(Context context, Uri uri) { public static Uri getParentFile(Context context, Uri uri) {
Cursor cursor = queryInBackground( Cursor cursor = context.getContentResolver().query(
context,
BaseFile.genContentUriApi(uri.getAuthority()) BaseFile.genContentUriApi(uri.getAuthority())
.buildUpon() .buildUpon()
.appendPath(BaseFile.CMD_GET_PARENT) .appendPath(BaseFile.CMD_GET_PARENT)
@ -610,8 +607,7 @@ public class BaseFileProviderUtils {
* {@code false} otherwise. * {@code false} otherwise.
*/ */
public static boolean isAncestorOf(Context context, Uri uri1, Uri uri2) { public static boolean isAncestorOf(Context context, Uri uri1, Uri uri2) {
return queryInBackground( return context.getContentResolver().query(
context,
BaseFile.genContentUriApi(uri1.getAuthority()) BaseFile.genContentUriApi(uri1.getAuthority())
.buildUpon() .buildUpon()
.appendPath(BaseFile.CMD_IS_ANCESTOR_OF) .appendPath(BaseFile.CMD_IS_ANCESTOR_OF)
@ -633,8 +629,7 @@ public class BaseFileProviderUtils {
* the task ID. * the task ID.
*/ */
public static void cancelTask(Context context, String authority, int taskId) { public static void cancelTask(Context context, String authority, int taskId) {
queryInBackground( context.getContentResolver().query(
context,
BaseFile.genContentUriApi(authority) BaseFile.genContentUriApi(authority)
.buildUpon() .buildUpon()
.appendPath(BaseFile.CMD_CANCEL) .appendPath(BaseFile.CMD_CANCEL)
@ -643,185 +638,4 @@ public class BaseFileProviderUtils {
null, null); null, null);
}// cancelTask() }// cancelTask()
/**
* Creates new background thread to delete given URI, waits for the thread
* to finish (or be interrupted) and returns the result.
*
* @param context
* the context.
* @param uri
* the URI to delete, see
* {@link ContentResolver#delete(Uri, String, String[])} for more
* details.
* @param where
* the {@code WHERE} clause, see
* {@link ContentResolver#delete(Uri, String, String[])} for more
* details.
* @param selectionArgs
* the selection arguments, see
* {@link ContentResolver#delete(Uri, String, String[])} for more
* details.
* @return the value returned from
* {@link ContentResolver#delete(Uri, String, String[])} , or
* {@code -1} if an error occurred.
*/
public static int deleteInBackground(final Context context, final Uri uri,
final String where, final String[] selectionArgs) {
final int[] result = { 0 };
Thread thread = new Thread() {
@Override
public void run() {
result[0] = context.getContentResolver().delete(uri, where,
selectionArgs);
}// run()
};
thread.start();
try {
thread.join();
return result[0];
} catch (InterruptedException e) {
return -1;
}
}// deleteInBackground()
/**
* Creates new background thread to insert values to given URI, waits for
* the thread to finish (or be interrupted) and returns the result.
*
* @param context
* the context.
* @param uri
* the URI to insert values into, see
* {@link ContentResolver#insert(Uri, ContentValues)} for more
* details.
* @param values
* the values to insert into, see
* {@link ContentResolver#insert(Uri, ContentValues)} for more
* details.
* @return the URI returned from
* {@link ContentResolver#insert(Uri, ContentValues)}, or
* {@code null} if an error occurred.
*/
public static Uri insertInBackground(final Context context, final Uri uri,
final ContentValues values) {
final Uri[] result = { null };
Thread thread = new Thread() {
@Override
public void run() {
result[0] = context.getContentResolver().insert(uri, values);
}// run()
};
thread.start();
try {
thread.join();
return result[0];
} catch (InterruptedException e) {
return null;
}
}// insertInBackground()
/**
* Creates new background thread to query given URI, waits for the thread to
* finish (or be interrupted) and returns the result.
*
* @param context
* the context.
* @param uri
* the URI to query, see
* {@link ContentResolver#query(Uri, String[], String, String[], String)}
* for more details.
* @param projection
* the projection, see
* {@link ContentResolver#query(Uri, String[], String, String[], String)}
* for more details.
* @param selection
* the selection, see
* {@link ContentResolver#query(Uri, String[], String, String[], String)}
* for more details.
* @param selectionArgs
* the selection arguments, see
* {@link ContentResolver#query(Uri, String[], String, String[], String)}
* for more details.
* @param sortOrder
* the sort order, see
* {@link ContentResolver#query(Uri, String[], String, String[], String)}
* for more details.
* @return the cursor returned from
* {@link ContentResolver#query(Uri, String[], String, String[], String)}
* , or {@code null} if an error occurred.
*/
public static Cursor queryInBackground(final Context context,
final Uri uri, final String[] projection, final String selection,
final String[] selectionArgs, final String sortOrder) {
final Cursor[] result = { null };
Thread thread = new Thread() {
@Override
public void run() {
result[0] = context.getContentResolver().query(uri, projection,
selection, selectionArgs, sortOrder);
}// run()
};
thread.start();
try {
thread.join();
return result[0];
} catch (InterruptedException e) {
return null;
}
}// queryInBackground()
/**
* Creates new background thread to update given URI, waits for the thread
* to finish (or be interrupted) and returns the result.
*
* @param context
* the context.
* @param uri
* the URI to update, see
* {@link ContentResolver#update(Uri, ContentValues, String, String[])}
* for more details.
* @param values
* the values to update, see
* {@link ContentResolver#update(Uri, ContentValues, String, String[])}
* for more details.
* @param where
* the {@code WHERE} clause, see
* {@link ContentResolver#update(Uri, ContentValues, String, String[])}
* for more details.
* @param selectionArgs
* the selection arguments, see
* {@link ContentResolver#update(Uri, ContentValues, String, String[])}
* for more details.
* @return the value returned from
* {@link ContentResolver#update(Uri, ContentValues, String, String[])}
* , or {@code -1} if an error occurred.
*/
public static int updateInBackground(final Context context, final Uri uri,
final ContentValues values, final String where,
final String[] selectionArgs) {
final int[] result = { 0 };
Thread thread = new Thread() {
@Override
public void run() {
result[0] = context.getContentResolver().update(uri, values,
where, selectionArgs);
}// run()
};
thread.start();
try {
thread.join();
return result[0];
} catch (InterruptedException e) {
return -1;
}
}// updateInBackground()
} }

View File

@ -39,7 +39,8 @@ public class DbUtils {
/** /**
* Joins all columns into one statement. * Joins all columns into one statement.
* *
* @param cols array of columns. * @param cols
* array of columns.
* @return E.g: "col1,col2,col3" * @return E.g: "col1,col2,col3"
*/ */
public static String joinColumns(String[] cols) { public static String joinColumns(String[] cols) {
@ -60,7 +61,8 @@ public class DbUtils {
* same length (for a {@link Long}). So it will work when comparing * same length (for a {@link Long}). So it will work when comparing
* different values as text. * different values as text.
* *
* @param n a long value. * @param n
* a long value.
* @return the formatted string. * @return the formatted string.
*/ */
public static String formatNumber(long n) { public static String formatNumber(long n) {
@ -71,7 +73,8 @@ public class DbUtils {
* Calls {@link DatabaseUtils#sqlEscapeString(String)}, then removes single * Calls {@link DatabaseUtils#sqlEscapeString(String)}, then removes single
* quotes at the begin and the end of the returned string. * quotes at the begin and the end of the returned string.
* *
* @param value the string to escape. If {@code null}, empty string will * @param value
* the string to escape. If {@code null}, empty string will
* return; * return;
* @return the "raw" escaped-string. * @return the "raw" escaped-string.
*/ */
@ -79,4 +82,5 @@ public class DbUtils {
return value == null ? "" : DatabaseUtils.sqlEscapeString(value) return value == null ? "" : DatabaseUtils.sqlEscapeString(value)
.replaceFirst("(?msi)^'", "").replaceFirst("(?msi)'$", ""); .replaceFirst("(?msi)^'", "").replaceFirst("(?msi)'$", "");
}// rawSqlEscapeString() }// rawSqlEscapeString()
} }

View File

@ -26,9 +26,12 @@ public class ProviderUtils {
/** /**
* Gets integer parameter. * Gets integer parameter.
* *
* @param uri the original URI. * @param uri
* @param key the key of query parameter. * the original URI.
* @param defaultValue will be returned if nothing found or parsing value failed. * @param key
* the key of query parameter.
* @param defaultValue
* will be returned if nothing found or parsing value failed.
* @return the integer value. * @return the integer value.
*/ */
public static int getIntQueryParam(Uri uri, String key, int defaultValue) { public static int getIntQueryParam(Uri uri, String key, int defaultValue) {
@ -42,9 +45,12 @@ public class ProviderUtils {
/** /**
* Gets long parameter. * Gets long parameter.
* *
* @param uri the original URI. * @param uri
* @param key the key of query parameter. * the original URI.
* @param defaultValue will be returned if nothing found or parsing value failed. * @param key
* the key of query parameter.
* @param defaultValue
* will be returned if nothing found or parsing value failed.
* @return the long value. * @return the long value.
*/ */
public static long getLongQueryParam(Uri uri, String key, long defaultValue) { public static long getLongQueryParam(Uri uri, String key, long defaultValue) {
@ -58,8 +64,10 @@ public class ProviderUtils {
/** /**
* Gets boolean parameter. * Gets boolean parameter.
* *
* @param uri the original URI. * @param uri
* @param key the key of query parameter. * the original URI.
* @param key
* the key of query parameter.
* @return {@code false} if the parameter does not exist, or it is either * @return {@code false} if the parameter does not exist, or it is either
* {@code "false"} or {@code "0"}. {@code true} otherwise. * {@code "false"} or {@code "0"}. {@code true} otherwise.
*/ */
@ -74,9 +82,12 @@ public class ProviderUtils {
/** /**
* Gets boolean parameter. * Gets boolean parameter.
* *
* @param uri the original URI. * @param uri
* @param key the key of query parameter. * the original URI.
* @param defaultValue the default value if the parameter does not exist. * @param key
* the key of query parameter.
* @param defaultValue
* the default value if the parameter does not exist.
* @return {@code defaultValue} if the parameter does not exist, or it is * @return {@code defaultValue} if the parameter does not exist, or it is
* either {@code "false"} or {@code "0"}. {@code true} otherwise. * either {@code "false"} or {@code "0"}. {@code true} otherwise.
*/ */
@ -89,4 +100,5 @@ public class ProviderUtils {
return false; return false;
return true; return true;
}// getBooleanQueryParam() }// getBooleanQueryParam()
} }

View File

@ -533,4 +533,5 @@ public class BaseFileContract {
*/ */
public static final String COLUMN_PROVIDER_ICON_ATTR = "provider_icon_attr"; public static final String COLUMN_PROVIDER_ICON_ATTR = "provider_icon_attr";
}// BaseFile }// BaseFile
} }

View File

@ -7,11 +7,11 @@
package group.pals.android.lib.ui.filechooser.providers.history; package group.pals.android.lib.ui.filechooser.providers.history;
import android.content.Context;
import android.net.Uri;
import group.pals.android.lib.ui.filechooser.providers.BaseColumns; import group.pals.android.lib.ui.filechooser.providers.BaseColumns;
import group.pals.android.lib.ui.filechooser.providers.ProviderUtils; import group.pals.android.lib.ui.filechooser.providers.ProviderUtils;
import group.pals.android.lib.ui.filechooser.providers.basefile.BaseFileContract.BaseFile; import group.pals.android.lib.ui.filechooser.providers.basefile.BaseFileContract.BaseFile;
import android.content.Context;
import android.net.Uri;
/** /**
* History contract. * History contract.
@ -123,4 +123,5 @@ public final class HistoryContract implements BaseColumns {
* Type: {@code URI} * Type: {@code URI}
*/ */
public static final String COLUMN_URI = "uri"; public static final String COLUMN_URI = "uri";
} }

View File

@ -423,4 +423,5 @@ public class HistoryProvider extends ContentProvider {
return result; return result;
}// appendNameAndRealUri() }// appendNameAndRealUri()
} }

View File

@ -131,4 +131,5 @@ public class FileObserverEx extends FileObserver {
HandlerThreadCompat_v5.quit(mHandlerThread); HandlerThreadCompat_v5.quit(mHandlerThread);
mHandlerThread.interrupt(); mHandlerThread.interrupt();
}// stopWatching() }// stopWatching()
} }

View File

@ -20,9 +20,11 @@ public class HandlerThreadCompat_v5 {
/** /**
* Wrapper for {@link HandlerThread#quit()}. * Wrapper for {@link HandlerThread#quit()}.
* *
* @param thread the handler thread. * @param thread
* the handler thread.
*/ */
public static void quit(HandlerThread thread) { public static void quit(HandlerThread thread) {
thread.quit(); thread.quit();
}// quit() }// quit()
} }

View File

@ -25,7 +25,8 @@ public class LocalFileContract {
/** /**
* Gets the authority of this provider. * Gets the authority of this provider.
* *
* @param context the context. * @param context
* the context.
* @return the authority. * @return the authority.
*/ */
public static final String getAuthority(Context context) { public static final String getAuthority(Context context) {
@ -36,4 +37,5 @@ public class LocalFileContract {
* The unique ID of this provider. * The unique ID of this provider.
*/ */
public static final String _ID = "7dab9818-0a8b-47ef-88cc-10fe538bfaf7"; public static final String _ID = "7dab9818-0a8b-47ef-88cc-10fe538bfaf7";
} }

View File

@ -269,15 +269,11 @@ public class LocalFileProvider extends BaseFileProvider {
else if (BaseFile.CMD_IS_ANCESTOR_OF.equals(uri.getLastPathSegment())) { else if (BaseFile.CMD_IS_ANCESTOR_OF.equals(uri.getLastPathSegment())) {
return doCheckAncestor(uri); return doCheckAncestor(uri);
} else if (BaseFile.CMD_GET_PARENT.equals(uri.getLastPathSegment())) { } else if (BaseFile.CMD_GET_PARENT.equals(uri.getLastPathSegment())) {
String sourcePath = Uri.parse( File file = new File(Uri.parse(
uri.getQueryParameter(BaseFile.PARAM_SOURCE)).getPath(); uri.getQueryParameter(BaseFile.PARAM_SOURCE)).getPath());
File file = new File(sourcePath);
file = file.getParentFile(); file = file.getParentFile();
if (file == null) if (file == null)
{
Log.d(CLASSNAME,"returning null as parent for "+sourcePath);
return null; return null;
}
matrixCursor = BaseFileProviderUtils.newBaseFileCursor(); matrixCursor = BaseFileProviderUtils.newBaseFileCursor();
@ -286,8 +282,6 @@ public class LocalFileProvider extends BaseFileProvider {
.exists() ? BaseFile.FILE_TYPE_UNKNOWN .exists() ? BaseFile.FILE_TYPE_UNKNOWN
: BaseFile.FILE_TYPE_NOT_EXISTED)); : BaseFile.FILE_TYPE_NOT_EXISTED));
Log.d(CLASSNAME, "Returning " + Uri.fromFile(file).toString()+" as parent for "+sourcePath);
RowBuilder newRow = matrixCursor.newRow(); RowBuilder newRow = matrixCursor.newRow();
newRow.add(0);// _ID newRow.add(0);// _ID
newRow.add(BaseFile newRow.add(BaseFile
@ -747,4 +741,5 @@ public class LocalFileProvider extends BaseFileProvider {
return new File(fileName); return new File(fileName);
}// extractFile() }// extractFile()
} }

View File

@ -471,4 +471,5 @@ public class AfcSearchView extends LinearLayout {
mTextSearch.setText(null); mTextSearch.setText(null);
}// onClick() }// onClick()
};// mButtonClearOnClickListener };// mButtonClearOnClickListener
} }

View File

@ -47,4 +47,5 @@ public class Converter {
String.format("%s %%sB", digitGroups == 0 ? "%,.0f" : "%,.2f"), String.format("%s %%sB", digitGroups == 0 ? "%,.0f" : "%,.2f"),
size, units[digitGroups]); size, units[digitGroups]);
}// sizeToStr() }// sizeToStr()
} }

View File

@ -7,12 +7,13 @@
package group.pals.android.lib.ui.filechooser.utils; package group.pals.android.lib.ui.filechooser.utils;
import android.content.Context;
import group.pals.android.lib.ui.filechooser.R; import group.pals.android.lib.ui.filechooser.R;
import group.pals.android.lib.ui.filechooser.prefs.DisplayPrefs.FileTimeDisplay; import group.pals.android.lib.ui.filechooser.prefs.DisplayPrefs.FileTimeDisplay;
import java.util.Calendar; import java.util.Calendar;
import android.content.Context;
/** /**
* Date utilities. * Date utilities.
* *
@ -46,9 +47,12 @@ public class DateUtils {
/** /**
* Formats date. * Formats date.
* *
* @param context {@link Context}. * @param context
* @param millis time in milliseconds. * {@link Context}.
* @param fileTimeDisplay {@link FileTimeDisplay}. * @param millis
* time in milliseconds.
* @param fileTimeDisplay
* {@link FileTimeDisplay}.
* @return the formatted string * @return the formatted string
*/ */
public static String formatDate(Context context, long millis, public static String formatDate(Context context, long millis,
@ -61,9 +65,12 @@ public class DateUtils {
/** /**
* Formats date. * Formats date.
* *
* @param context {@link Context}. * @param context
* @param date {@link Calendar}. * {@link Context}.
* @param fileTimeDisplay {@link FileTimeDisplay}. * @param date
* {@link Calendar}.
* @param fileTimeDisplay
* {@link FileTimeDisplay}.
* @return the formatted string, for local human reading. * @return the formatted string, for local human reading.
*/ */
public static String formatDate(Context context, Calendar date, public static String formatDate(Context context, Calendar date,
@ -87,7 +94,7 @@ public class DateUtils {
date.getTimeInMillis(), FORMAT_SHORT_TIME)); date.getTimeInMillis(), FORMAT_SHORT_TIME));
}// yesterday }// yesterday
else if (date.get(Calendar.YEAR) == yesterday.get(Calendar.YEAR)) { else if (date.get(Calendar.YEAR) == yesterday.get(Calendar.YEAR)) {
if (fileTimeDisplay.isShowTimeForOldDaysThisYear()) if (fileTimeDisplay.showTimeForOldDaysThisYear)
res = android.text.format.DateUtils.formatDateTime(context, res = android.text.format.DateUtils.formatDateTime(context,
date.getTimeInMillis(), FORMAT_SHORT_TIME date.getTimeInMillis(), FORMAT_SHORT_TIME
| FORMAT_MONTH_AND_DAY); | FORMAT_MONTH_AND_DAY);
@ -96,7 +103,7 @@ public class DateUtils {
date.getTimeInMillis(), FORMAT_MONTH_AND_DAY); date.getTimeInMillis(), FORMAT_MONTH_AND_DAY);
}// this year }// this year
else { else {
if (fileTimeDisplay.isShowTimeForOldDays()) if (fileTimeDisplay.showTimeForOldDays)
res = android.text.format.DateUtils.formatDateTime(context, res = android.text.format.DateUtils.formatDateTime(context,
date.getTimeInMillis(), FORMAT_SHORT_TIME date.getTimeInMillis(), FORMAT_SHORT_TIME
| FORMAT_MONTH_AND_DAY | FORMAT_YEAR); | FORMAT_MONTH_AND_DAY | FORMAT_YEAR);
@ -108,4 +115,5 @@ public class DateUtils {
return res; return res;
}// formatDate() }// formatDate()
} }

View File

@ -28,4 +28,5 @@ public class EnvUtils {
public static final int genId() { public static final int genId() {
return mId++; return mId++;
}// genId() }// genId()
} }

View File

@ -95,4 +95,5 @@ public class FileUtils {
public static boolean isFilenameValid(String name) { public static boolean isFilenameValid(String name) {
return name != null && name.trim().matches("[^\\\\/?%*:|\"<>]+"); return name != null && name.trim().matches("[^\\\\/?%*:|\"<>]+");
}// isFilenameValid() }// isFilenameValid()
} }

View File

@ -77,4 +77,5 @@ public class MimeTypes {
public static final String REGEX_FILE_TYPE_COMPRESSED = "(?si)^.+\\.(zip|" public static final String REGEX_FILE_TYPE_COMPRESSED = "(?si)^.+\\.(zip|"
+ "7z|lz?|[jrt]ar|gz|gzip|bzip|xz|cab|sfx|z|iso|bz?|rz|s7z|apk|" + "7z|lz?|[jrt]ar|gz|gzip|bzip|xz|cab|sfx|z|iso|bz?|rz|s7z|apk|"
+ "dmg)$"; + "dmg)$";
} }

View File

@ -23,11 +23,11 @@ public class Sys {
/** /**
* The library version name. * The library version name.
*/ */
public static final String LIB_VERSION_NAME = "5.4.3 beta"; public static final String LIB_VERSION_NAME = "5.4.4 beta";
/** /**
* The library version code. * The library version code.
*/ */
public static final int LIB_VERSION_CODE = 54; public static final int LIB_VERSION_CODE = 56;
} }

View File

@ -20,7 +20,8 @@ public class TextUtils {
/** /**
* Quotes a text in double quotation mark. * Quotes a text in double quotation mark.
* *
* @param s the text, if {@code null}, empty string will be used * @param s
* the text, if {@code null}, empty string will be used
* @return the quoted text * @return the quoted text
*/ */
public static String quote(String s) { public static String quote(String s) {
@ -30,7 +31,8 @@ public class TextUtils {
/** /**
* Compiles {@code regex}. * Compiles {@code regex}.
* *
* @param regex the regex. * @param regex
* the regex.
* @return a compiled {@link Pattern}, or {@code null} if there is an error * @return a compiled {@link Pattern}, or {@code null} if there is an error
* while compiling. * while compiling.
*/ */
@ -43,4 +45,5 @@ public class TextUtils {
return null; return null;
} }
}// compileRegex() }// compileRegex()
} }

View File

@ -7,14 +7,15 @@
package group.pals.android.lib.ui.filechooser.utils.history; package group.pals.android.lib.ui.filechooser.utils.history;
import android.os.Parcelable;
import java.util.ArrayList; import java.util.ArrayList;
import android.os.Parcelable;
/** /**
* A history store of any object. * A history store of any object.
* *
* @param <A> any type * @param <A>
* any type
* @author Hai Bison * @author Hai Bison
* @since v2.0 alpha * @since v2.0 alpha
*/ */
@ -24,14 +25,16 @@ public interface History<A> extends Parcelable {
* Pushes {@code newItem} to the history. If the top item is same as this * Pushes {@code newItem} to the history. If the top item is same as this
* one, then does nothing. * one, then does nothing.
* *
* @param newItem the new item * @param newItem
* the new item
*/ */
void push(A newItem); void push(A newItem);
/** /**
* Finds {@code item} and if it exists, removes all items after it. * Finds {@code item} and if it exists, removes all items after it.
* *
* @param item {@link A} * @param item
* {@link A}
* @return the total items truncated. * @return the total items truncated.
* @since v4.3 beta * @since v4.3 beta
*/ */
@ -40,7 +43,8 @@ public interface History<A> extends Parcelable {
/** /**
* Removes an item. * Removes an item.
* *
* @param item {@link A} * @param item
* {@link A}
* @since v4.0 beta * @since v4.0 beta
*/ */
void remove(A item); void remove(A item);
@ -48,7 +52,8 @@ public interface History<A> extends Parcelable {
/** /**
* Removes all items by a filter. * Removes all items by a filter.
* *
* @param filter {@link HistoryFilter} * @param filter
* {@link HistoryFilter}
* @since v4.0 beta * @since v4.0 beta
*/ */
void removeAll(HistoryFilter<A> filter); void removeAll(HistoryFilter<A> filter);
@ -63,7 +68,8 @@ public interface History<A> extends Parcelable {
/** /**
* Gets index of item {@code a} * Gets index of item {@code a}
* *
* @param a an item * @param a
* an item
* @return index of the {@code a}, or -1 if there is no one * @return index of the {@code a}, or -1 if there is no one
*/ */
int indexOf(A a); int indexOf(A a);
@ -71,7 +77,8 @@ public interface History<A> extends Parcelable {
/** /**
* Gets previous item of {@code a} * Gets previous item of {@code a}
* *
* @param a current item * @param a
* current item
* @return the previous item, can be {@code null} * @return the previous item, can be {@code null}
*/ */
A prevOf(A a); A prevOf(A a);
@ -79,7 +86,8 @@ public interface History<A> extends Parcelable {
/** /**
* Gets next item of {@code a} * Gets next item of {@code a}
* *
* @param a current item * @param a
* current item
* @return the next item, can be {@code null} * @return the next item, can be {@code null}
*/ */
A nextOf(A a); A nextOf(A a);
@ -110,7 +118,8 @@ public interface History<A> extends Parcelable {
/** /**
* Adds a {@link HistoryListener} * Adds a {@link HistoryListener}
* *
* @param listener {@link HistoryListener} * @param listener
* {@link HistoryListener}
* @since v4.0 beta * @since v4.0 beta
*/ */
void addListener(HistoryListener<A> listener); void addListener(HistoryListener<A> listener);
@ -118,7 +127,8 @@ public interface History<A> extends Parcelable {
/** /**
* Removes a {@link HistoryListener} * Removes a {@link HistoryListener}
* *
* @param listener {@link HistoryListener} * @param listener
* {@link HistoryListener}
* @return the removed listener * @return the removed listener
* @since v4.0 beta * @since v4.0 beta
*/ */
@ -132,12 +142,15 @@ public interface History<A> extends Parcelable {
/** /**
* Finds items with a filter. * Finds items with a filter.
* *
* @param filter {@link HistoryFilter} * @param filter
* @param ascending {@code true} if you want to process the history list ascending * {@link HistoryFilter}
* @param ascending
* {@code true} if you want to process the history list ascending
* (oldest to newest), {@code false} for descending. * (oldest to newest), {@code false} for descending.
* @return {@code true} if the desired items have been found, {@code false} * @return {@code true} if the desired items have been found, {@code false}
* otherwise. * otherwise.
* @since v5.1 beta * @since v5.1 beta
*/ */
boolean find(HistoryFilter<A> filter, boolean ascending); boolean find(HistoryFilter<A> filter, boolean ascending);
} }

View File

@ -18,8 +18,10 @@ public interface HistoryFilter<A> {
/** /**
* Filters item. * Filters item.
* *
* @param item {@link A} * @param item
* {@link A}
* @return {@code true} if the {@code item} is accepted * @return {@code true} if the {@code item} is accepted
*/ */
boolean accept(A item); boolean accept(A item);
} }

View File

@ -18,7 +18,9 @@ public interface HistoryListener<A> {
/** /**
* Will be called after the history changed. * Will be called after the history changed.
* *
* @param history {@link History} * @param history
* {@link History}
*/ */
void onChanged(History<A> history); void onChanged(History<A> history);
} }

View File

@ -259,4 +259,5 @@ public class HistoryStore<A extends Parcelable> implements History<A> {
private HistoryStore(Parcel in) { private HistoryStore(Parcel in) {
readFromParcel(in); readFromParcel(in);
}// HistoryStore() }// HistoryStore()
} }

View File

@ -129,4 +129,5 @@ public class ContextMenuUtils {
*/ */
void onClick(int resId); void onClick(int resId);
}// OnMenuItemClickListener }// OnMenuItemClickListener
} }

View File

@ -7,13 +7,13 @@
package group.pals.android.lib.ui.filechooser.utils.ui; package group.pals.android.lib.ui.filechooser.utils.ui;
import group.pals.android.lib.ui.filechooser.R;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.app.Dialog; import android.app.Dialog;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.view.ContextThemeWrapper; import android.view.ContextThemeWrapper;
import android.widget.Toast; import android.widget.Toast;
import group.pals.android.lib.ui.filechooser.R;
/** /**
* Utilities for message boxes. * Utilities for message boxes.
@ -37,9 +37,12 @@ public class Dlg {
/** /**
* Shows a toast message. * Shows a toast message.
* *
* @param context {@link Context} * @param context
* @param msg the message. * {@link Context}
* @param duration can be {@link #LENGTH_LONG} or {@link #LENGTH_SHORT}. * @param msg
* the message.
* @param duration
* can be {@link #LENGTH_LONG} or {@link #LENGTH_SHORT}.
*/ */
public static void toast(Context context, CharSequence msg, int duration) { public static void toast(Context context, CharSequence msg, int duration) {
if (mToast != null) if (mToast != null)
@ -51,9 +54,12 @@ public class Dlg {
/** /**
* Shows a toast message. * Shows a toast message.
* *
* @param context {@link Context} * @param context
* @param msgId the resource ID of the message. * {@link Context}
* @param duration can be {@link #LENGTH_LONG} or {@link #LENGTH_SHORT}. * @param msgId
* the resource ID of the message.
* @param duration
* can be {@link #LENGTH_LONG} or {@link #LENGTH_SHORT}.
*/ */
public static void toast(Context context, int msgId, int duration) { public static void toast(Context context, int msgId, int duration) {
toast(context, context.getString(msgId), duration); toast(context, context.getString(msgId), duration);
@ -62,9 +68,12 @@ public class Dlg {
/** /**
* Shows an info dialog. * Shows an info dialog.
* *
* @param context {@link Context} * @param context
* @param msg the message. * {@link Context}
* @param listener the {@link DialogInterface.OnDismissListener}. * @param msg
* the message.
* @param listener
* the {@link DialogInterface.OnDismissListener}.
*/ */
public static void showInfo(Context context, CharSequence msg, public static void showInfo(Context context, CharSequence msg,
DialogInterface.OnDismissListener listener) { DialogInterface.OnDismissListener listener) {
@ -79,9 +88,12 @@ public class Dlg {
/** /**
* Shows an info dialog. * Shows an info dialog.
* *
* @param context the context. * @param context
* @param msgId the resource ID of the message. * the context.
* @param listener the {@link DialogInterface.OnDismissListener}. * @param msgId
* the resource ID of the message.
* @param listener
* the {@link DialogInterface.OnDismissListener}.
*/ */
public static void showInfo(Context context, int msgId, public static void showInfo(Context context, int msgId,
DialogInterface.OnDismissListener listener) { DialogInterface.OnDismissListener listener) {
@ -91,8 +103,10 @@ public class Dlg {
/** /**
* Shows an info dialog. * Shows an info dialog.
* *
* @param context {@link Context} * @param context
* @param msg the message. * {@link Context}
* @param msg
* the message.
*/ */
public static void showInfo(Context context, CharSequence msg) { public static void showInfo(Context context, CharSequence msg) {
showInfo(context, msg, null); showInfo(context, msg, null);
@ -101,8 +115,10 @@ public class Dlg {
/** /**
* Shows an info dialog. * Shows an info dialog.
* *
* @param context {@link Context} * @param context
* @param msgId the resource ID of the message. * {@link Context}
* @param msgId
* the resource ID of the message.
*/ */
public static void showInfo(Context context, int msgId) { public static void showInfo(Context context, int msgId) {
showInfo(context, context.getString(msgId)); showInfo(context, context.getString(msgId));
@ -111,9 +127,12 @@ public class Dlg {
/** /**
* Shows an error message. * Shows an error message.
* *
* @param context {@link Context} * @param context
* @param msg the message. * {@link Context}
* @param listener will be called after the user cancelled the dialog. * @param msg
* the message.
* @param listener
* will be called after the user cancelled the dialog.
*/ */
public static void showError(Context context, CharSequence msg, public static void showError(Context context, CharSequence msg,
DialogInterface.OnCancelListener listener) { DialogInterface.OnCancelListener listener) {
@ -128,9 +147,12 @@ public class Dlg {
/** /**
* Shows an error message. * Shows an error message.
* *
* @param context {@link Context} * @param context
* @param msgId the resource ID of the message. * {@link Context}
* @param listener will be called after the user cancelled the dialog. * @param msgId
* the resource ID of the message.
* @param listener
* will be called after the user cancelled the dialog.
*/ */
public static void showError(Context context, int msgId, public static void showError(Context context, int msgId,
DialogInterface.OnCancelListener listener) { DialogInterface.OnCancelListener listener) {
@ -140,9 +162,12 @@ public class Dlg {
/** /**
* Shows an unknown error. * Shows an unknown error.
* *
* @param context {@link Context} * @param context
* @param t the {@link Throwable} * {@link Context}
* @param listener will be called after the user cancelled the dialog. * @param t
* the {@link Throwable}
* @param listener
* will be called after the user cancelled the dialog.
*/ */
public static void showUnknownError(Context context, Throwable t, public static void showUnknownError(Context context, Throwable t,
DialogInterface.OnCancelListener listener) { DialogInterface.OnCancelListener listener) {
@ -156,11 +181,15 @@ public class Dlg {
/** /**
* Shows a confirmation dialog. * Shows a confirmation dialog.
* *
* @param context {@link Context} * @param context
* @param msg the message. * {@link Context}
* @param onYes will be called if the user selects positive answer (a * @param msg
* the message.
* @param onYes
* will be called if the user selects positive answer (a
* <i>Yes</i> or <i>OK</i>). * <i>Yes</i> or <i>OK</i>).
* @param onNo will be called after the user cancelled the dialog. * @param onNo
* will be called after the user cancelled the dialog.
*/ */
public static void confirmYesno(Context context, CharSequence msg, public static void confirmYesno(Context context, CharSequence msg,
DialogInterface.OnClickListener onYes, DialogInterface.OnClickListener onYes,
@ -178,9 +207,12 @@ public class Dlg {
/** /**
* Shows a confirmation dialog. * Shows a confirmation dialog.
* *
* @param context {@link Context} * @param context
* @param msg the message. * {@link Context}
* @param onYes will be called if the user selects positive answer (a * @param msg
* the message.
* @param onYes
* will be called if the user selects positive answer (a
* <i>Yes</i> or <i>OK</i>). * <i>Yes</i> or <i>OK</i>).
*/ */
public static void confirmYesno(Context context, CharSequence msg, public static void confirmYesno(Context context, CharSequence msg,
@ -192,7 +224,8 @@ public class Dlg {
* Creates new {@link Dialog}. Set canceled on touch outside to {@code true} * Creates new {@link Dialog}. Set canceled on touch outside to {@code true}
* . * .
* *
* @param context the context which uses this library's theme. * @param context
* the context which uses this library's theme.
* @return the {@link Dialog}. * @return the {@link Dialog}.
* @since v4.3 beta * @since v4.3 beta
*/ */
@ -207,7 +240,8 @@ public class Dlg {
* Creates new {@link AlertDialog}. Set canceled on touch outside to * Creates new {@link AlertDialog}. Set canceled on touch outside to
* {@code true}. * {@code true}.
* *
* @param context the context which uses this library's theme. * @param context
* the context which uses this library's theme.
* @return {@link AlertDialog} * @return {@link AlertDialog}
* @since v4.3 beta * @since v4.3 beta
*/ */
@ -220,7 +254,8 @@ public class Dlg {
/** /**
* Creates new {@link AlertDialog.Builder}. * Creates new {@link AlertDialog.Builder}.
* *
* @param context the context which uses this library's theme. * @param context
* the context which uses this library's theme.
* @return {@link AlertDialog} * @return {@link AlertDialog}
* @since v4.3 beta * @since v4.3 beta
*/ */
@ -228,4 +263,5 @@ public class Dlg {
return new AlertDialog.Builder(new ContextThemeWrapper(context, return new AlertDialog.Builder(new ContextThemeWrapper(context,
Ui.resolveAttribute(context, R.attr.afc_theme_dialog))); Ui.resolveAttribute(context, R.attr.afc_theme_dialog)));
}// newAlertDlgBuilder() }// newAlertDlgBuilder()
} }

View File

@ -23,7 +23,7 @@ import android.widget.AbsListView;
*/ */
public class GestureUtils { public class GestureUtils {
public static final String CLASSNAME = GestureUtils.class.getName(); private static final String CLASSNAME = GestureUtils.class.getName();
/** /**
* The fling direction. * The fling direction.
@ -218,4 +218,5 @@ public class GestureUtils {
} }
}); });
}// setupGestureDetector() }// setupGestureDetector()
} }

View File

@ -7,6 +7,7 @@
package group.pals.android.lib.ui.filechooser.utils.ui; package group.pals.android.lib.ui.filechooser.utils.ui;
import group.pals.android.lib.ui.filechooser.R;
import android.app.ProgressDialog; import android.app.ProgressDialog;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
@ -24,7 +25,7 @@ import android.util.Log;
public abstract class LoadingDialog<Params, Progress, Result> extends public abstract class LoadingDialog<Params, Progress, Result> extends
AsyncTask<Params, Progress, Result> { AsyncTask<Params, Progress, Result> {
public static final String CLASSNAME = LoadingDialog.class.getName(); private static final String CLASSNAME = LoadingDialog.class.getName();
private final ProgressDialog mDialog; private final ProgressDialog mDialog;
/** /**
@ -79,6 +80,19 @@ public abstract class LoadingDialog<Params, Progress, Result> extends
this(context, context.getString(msgId), cancelable); this(context, context.getString(msgId), cancelable);
}// LoadingDialog() }// LoadingDialog()
/**
* Creates new {@link LoadingDialog} showing "Loading..." (
* {@link R.string#afc_msg_loading}).
*
* @param context
* {@link Context}
* @param cancelable
* as the name means.
*/
public LoadingDialog(Context context, boolean cancelable) {
this(context, context.getString(R.string.afc_msg_loading), cancelable);
}// LoadingDialog()
/** /**
* If you override this method, you must call {@code super.onPreExecute()} * If you override this method, you must call {@code super.onPreExecute()}
* at very first of the method. * at very first of the method.

View File

@ -65,4 +65,5 @@ public class MenuItemAdapter extends BaseAdapter {
return convertView; return convertView;
}// getView() }// getView()
} }

View File

@ -24,4 +24,5 @@ public interface TaskListener {
* the user data, can be {@code null}. * the user data, can be {@code null}.
*/ */
public void onFinish(boolean ok, Object any); public void onFinish(boolean ok, Object any);
} }

View File

@ -145,4 +145,5 @@ public class Ui {
dialogWindow.setLayout(width, height); dialogWindow.setLayout(width, height);
} }
}// adjustDialogSizeForLargeScreen() }// adjustDialogSizeForLargeScreen()
} }