diff --git a/.gitignore b/.gitignore index cf2dbca..e986219 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,7 @@ lint.xml # Java class files *.class +*.jar # generated files bin/ @@ -51,4 +52,5 @@ Thumbs.db *.swp # backup files -*.bak \ No newline at end of file +*.bak +.backups diff --git a/Git-Commit.cmd b/Git-Commit.cmd new file mode 100644 index 0000000..99bd081 --- /dev/null +++ b/Git-Commit.cmd @@ -0,0 +1,30 @@ +::#! +::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: {{{1 ::::::::::: +:: Copyright © 2013 Martin Krischik +:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: +:: $Author$ +:: $Revision$ +:: $Date$ +:: $Id$ +:: $HeadURL$ +::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: }}}1 ::::::::::: +@ECHO OFF + +SETLOCAL + SET PATH=%PATH%;C:\opt\Git\bin + SET PATH=%PATH%;C:\opt\Scala\2.10.0\bin + + CALL scala -language:postfixOps -save %~f0 %* +ENDLOCAL + +GOTO :eof +::!# + +import scala.sys.process._ + +("git" :: "add" :: "." :: Nil).! +("git" :: "commit" :: "--message" :: argv (0) :: Nil).! +("git" :: "push" :: "-u" :: "origin" :: "master" :: Nil).! + +// vim: set wrap tabstop=8 shiftwidth=4 softtabstop=4 noexpandtab : +// vim: set textwidth=0 filetype=scala foldmethod=marker nospell : diff --git a/Git-Commit.command b/Git-Commit.command new file mode 100755 index 0000000..6069949 --- /dev/null +++ b/Git-Commit.command @@ -0,0 +1,29 @@ +#!/opt/local/bin/zsh +########################################################### {{{1 ########### +# Copyright © 2005 … 2013 Martin Krischik +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +############################################################################ +# $Author: krischik $ +# $Revision: 4694 $ +# $Date: 2012-03-29 20:47:27 +0200 (Do, 29. Mär 2012) $ +# $Id: Start-Vim.command 4694 2012-03-29 18:47:27Z krischik $ +# $HeadURL: https://uiq3.svn.sourceforge.net/svnroot/uiq3/trunk/Java/Utilities/Start-Vim.command $ +########################################################### }}}1 ########### + +scala -save Git-Commit.cmd ${0} + +# vim: set wrap tabstop=8 shiftwidth=4 softtabstop=4 noexpandtab : +# vim: set textwidth=0 filetype=zsh foldmethod=marker nospell : diff --git a/Git-Pull.cmd b/Git-Pull.cmd new file mode 100644 index 0000000..c7ecbfd --- /dev/null +++ b/Git-Pull.cmd @@ -0,0 +1,29 @@ +::#! +::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: {{{1 :::::::^:::: +:: Copyright © 2013 Martin Krischik +:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: +:: $Author$ +:: $Revision$ +:: $Date$ +:: $Id$ +:: $HeadURL$ +::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: }}}1 ::::::::::: +@ECHO OFF + +SETLOCAL + SET PATH=%PATH%;C:\opt\Git\bin + SET PATH=%PATH%;C:\opt\Scala\2.10.0\bin + + CALL scala -save %~f0 %* +ENDLOCAL + +GOTO :eof +::!# + +import scala.sys.process._ + +("git" :: "pull" :: "https://github.com/iPaulPro/aFileChooser" :: Nil).! +("git" :: "pull" :: "origin" :: "dev" :: Nil).! + +// vim: set wrap tabstop=8 shiftwidth=4 softtabstop=4 noexpandtab : +// vim: set textwidth=0 filetype=scala foldmethod=marker nospell : diff --git a/Git-Pull.command b/Git-Pull.command new file mode 100755 index 0000000..c16dea3 --- /dev/null +++ b/Git-Pull.command @@ -0,0 +1,29 @@ +#!/opt/local/bin/zsh +########################################################### {{{1 ########### +# Copyright © 2005 … 2013 Martin Krischik +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +############################################################################ +# $Author: krischik $ +# $Revision: 4694 $ +# $Date: 2012-03-29 20:47:27 +0200 (Do, 29. Mär 2012) $ +# $Id: Start-Vim.command 4694 2012-03-29 18:47:27Z krischik $ +# $HeadURL: https://uiq3.svn.sourceforge.net/svnroot/uiq3/trunk/Java/Utilities/Start-Vim.command $ +########################################################### }}}1 ########### + +scala -save Git-Pull.cmd + +# vim: set wrap tabstop=8 shiftwidth=4 softtabstop=4 noexpandtab : +# vim: set textwidth=0 filetype=zsh foldmethod=marker nospell : diff --git a/Maven-Deploy.cmd b/Maven-Deploy.cmd new file mode 100644 index 0000000..e4649be --- /dev/null +++ b/Maven-Deploy.cmd @@ -0,0 +1,45 @@ +::#! +::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: {{{1 :::::::^:::: +:: Copyright © 2013 Martin Krischik +:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: +:: $Author$ +:: $Revision$ +:: $Date$ +:: $Id$ +:: $HeadURL$ +::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: }}}1 ::::::::::: +@ECHO OFF + +SETLOCAL + SET PATH=%PATH%;C:\opt\Git\bin + SET PATH=%PATH%;C:\opt\Scala\2.10.0\bin + SET Scala_Library="${WORK}/Repositories/Local/net/sourceforge/uiq3/Calculator-Script/${CALCULATOR_VERSION}/Calculator-Script-${CALCULATOR_VERSION}.jar" + + PUSHD "AndroidAnnotations" + CALL scala -classpath %Scala_Library% -save ..\Maven-Deploy.cm %* + POPD +ENDLOCAL + +GOTO :eof +::!# + +import scala.sys.process._ +import net.sourceforge.uiq3.Maven.mvn +import net.sourceforge.uiq3.Shell.Err_Exit_Call + +val Maven_Deploy = System.getenv ("MAVEN_DEPLOY") +val Project_Name = System.getenv ("PROJECT_NAME") +val Maven_Name = Project_Name +" Maven Repository" + +Err_Exit_Call (mvn ::: "--activate-profiles" :: "release" :: "clean" :: Nil) +Err_Exit_Call (mvn ::: "--activate-profiles" :: "release" :: "install" :: Nil) +Err_Exit_Call (mvn ::: "--activate-profiles" :: "release" :: "javadoc:javadoc" :: Nil) +Err_Exit_Call (mvn ::: "--activate-profiles" :: "release" :: "source:jar" :: Nil) +Err_Exit_Call (mvn ::: + "--define" :: "repo.id=" + Project_Name :: + "--define" :: "repo.name=" + Maven_Name :: + "--define" :: "repo.url=" + Maven_Deploy :: + "deploy" :: Nil ) + +// vim: set wrap tabstop=8 shiftwidth=4 softtabstop=4 noexpandtab : +// vim: set textwidth=0 filetype=scala foldmethod=marker nospell : diff --git a/Maven-Deploy.command b/Maven-Deploy.command new file mode 100755 index 0000000..9426df4 --- /dev/null +++ b/Maven-Deploy.command @@ -0,0 +1,46 @@ +#!/opt/local/bin/zsh +########################################################### {{{1 ########### +# Copyright © 2005 … 2013 Martin Krischik +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +############################################################################ +# $Author: krischik $ +# $Revision: 4694 $ +# $Date: 2012-03-29 20:47:27 +0200 (Do, 29. Mär 2012) $ +# $Id: Start-Vim.command 4694 2012-03-29 18:47:27Z krischik $ +# $HeadURL: https://uiq3.svn.sourceforge.net/svnroot/uiq3/trunk/Java/Utilities/Start-Vim.command $ +########################################################### }}}1 ########### + +local Download_Server="krischik,uiq3@shell.sourceforge.net" +local Scala_Library="${WORK}/Repositories/Local/net/sourceforge/uiq3/Calculator-Script/6.2.0/Calculator-Script-6.2.0.jar" + +ssh-add \ + /Users/martin/.ssh/id_rsa \ + /Users/martin/.ssh/id_dsa \ + /Users/martin/.ssh/Martin_Krischik_SF + +scala -classpath ${Scala_Library} -save Maven-Deploy.cmd + +pushd "/Work/HomePage/uiq3/htdocs" + rsync \ + --archive \ + --delete \ + --verbose \ + --keep-dirlinks \ + "Repository" \ + "krischik,uiq3@web.sourceforge.net:htdocs" +popd +# vim: set wrap tabstop=8 shiftwidth=4 softtabstop=4 noexpandtab : +# vim: set textwidth=0 filetype=zsh foldmethod=marker nospell : diff --git a/README.markdown b/README.markdown index 7e80416..f5828af 100644 --- a/README.markdown +++ b/README.markdown @@ -1,3 +1,7 @@ +# Archived + +This file chooser is outdated and can't be used with current Android versions any more. + # aFileChooser - Android File Chooser aFileChooser is an __Android Library Project__ that simplifies the process of presenting a file chooser on Android 2.1+. @@ -23,10 +27,11 @@ Add `FileChooserActivity` to your project's AndroidManifest.xml file with a full __Important__ `FileChooserActivity` must have `android:exported="true"` and have the `` set as follows: +```xml @@ -38,13 +43,15 @@ __Important__ `FileChooserActivity` must have `android:exported="true"` and have +``` If you want to use the Storage Access Framework (API 19+), include [Ian Lake](https://github.com/ianhanniballake/)'s `LocalStorageProvider` (included in this library) in your ``: - @@ -52,6 +59,7 @@ If you want to use the Storage Access Framework (API 19+), include [Ian Lake](ht +``` __Note__ that like a `ContentProvider`, the `DocumentProvider` `authority` must be unique. You should change `com.ianhanniballake.localstorage.documents` in your Manifest, as well as the `LocalStorageProvider.AUTHORITY` field. @@ -61,6 +69,7 @@ Using `FileChooserActivity` and `LocalStorageProvider` together are redundant if Use `startActivityForResult(Intent, int)` to launch `FileChooserActivity` directly. `FileChooserActivity` returns the `Uri` of the file selected as the `Intent` data in `onActivityResult(int, int, Intent)`. Alternatively, you can use the helper method `FileUtils.createGetContentIntent()` to construct an `ACTION_GET_CONTENT` Intent that will show an "Intent Chooser" dialog on pre Kit-Kat devices, and the "Documents UI" otherwise. E.g.: +```java private static final int REQUEST_CHOOSER = 1234; @Override @@ -69,7 +78,7 @@ Use `startActivityForResult(Intent, int)` to launch `FileChooserActivity` direct // Create the ACTION_GET_CONTENT Intent Intent getContentIntent = FileUtils.createGetContentIntent(); - + Intent intent = Intent.createChooser(getContentIntent, "Select a file"); startActivityForResult(intent, REQUEST_CHOOSER); } @@ -77,37 +86,96 @@ Use `startActivityForResult(Intent, int)` to launch `FileChooserActivity` direct @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { - case REQUEST_CHOOSER: - if (resultCode == RESULT_OK) { - - final Uri uri = data.getData(); - - // Get the File path from the Uri - String path = FileUtils.getPath(this, uri); - - // Alternatively, use FileUtils.getFile(Context, Uri) - if (path != null && FileUtils.isLocal(path)) { - File file = new File(path); - } - } - break; + case REQUEST_CHOOSER: + if (resultCode == RESULT_OK) { + + final Uri uri = data.getData(); + + // Get the File path from the Uri + String path = FileUtils.getPath(this, uri); + + // Alternatively, use FileUtils.getFile(Context, Uri) + if (path != null && FileUtils.isLocal(path)) { + File file = new File(path); + } + } + break; } } +``` A more robust example can be found in the aFileChooserExample project. __Note__ the `FileUtils` method to get a file path from a `Uri` (`FileUtils.getPath(Context, Uri)`). This works for `File`, `MediaStore`, and `DocumentProvider` `Uris`. +###Filtering by file extension + +Provide an extra `EXTRA_FILTER_INCLUDE_EXTENSIONS` which is an `ArrayList` containing all the extensions that must be included. Note that the extentions must begin with a dot character. The behavior of this extra is specified as follows: + + - If this extra is specified, then **only** files with the supplied extensions will be shown. All other files will be hidden. + - If this extra is not specified, or it is an empty `ArrayList`, then no filtering is performed. + +Example: + +```java + private static final ArrayList INCLUDE_EXTENSIONS_LIST = new ArrayList(); + static{ + INCLUDE_EXTENSIONS_LIST.add(".apk"); + INCLUDE_EXTENSIONS_LIST.add(".bin"); + } + //... + //... + Intent intent = new Intent(this, FileChooserActivity.class); + intent.putStringArrayListExtra(FileChooserActivity.EXTRA_FILTER_INCLUDE_EXTENSIONS, INCLUDE_EXTENSIONS_LIST); + //Use this intent in startActivityForResult() + +``` + +or use the FileChooserActivity.startActivity convenience function. + +###Set base directory + +Provide an extra `EXTRA_FILTER_BASE_PATH` which is an `String` containing base directroy to be displayed: + +Example: + +```java + final Intent intent = new Intent (callingActivity, FileChooserActivity.class); + + intent.putExtra ( + FileChooserActivity.EXTRA_FILTER_BASE_PATH, + baseDirectory); + intent.putStringArrayListExtra ( + FileChooserActivity.EXTRA_FILTER_INCLUDE_EXTENSIONS, + filterIncludeExtensions); + + android.util.Log.v (TAG, "> intent = " + intent); + + try { + callingActivity.startActivityForResult (intent, requestCode); + } catch (@NotNull final android.content.ActivityNotFoundException e) { + // The reason for the existence of aFileChooser + android.util.Log.e (TAG, "LOG02230:", e); + } +``` + +or use the FileChooserActivity.startActivity convenience function. + ## Credits Developed by Paul Burke (iPaulPro) - [paulburke.co](http://paulburke.co/) +Filtering by file extension: [curioustechizen] (https://github.com/curioustechizen) + +Set start path by [krischik](https://github.com/krischik) + Translations by [TomTasche](https://github.com/TomTasche), [booknara](https://github.com/booknara), [brenouchoa](https://github.com/brenouchoa) Folder by [Sergio Calcara](http://thenounproject.com/fallacyaccount) from The Noun Project (ic_provider.png) Document by [Melvin Salas](http://thenounproject.com/msalas10) from The Noun Project (ic_file.png) + ## Licenses Copyright (C) 2011 - 2013 Paul Burke @@ -127,7 +195,7 @@ Document by [Melvin Salas](http://thenounproject.com/msalas10) from The Noun Pro Portions of FileUtils.java: Copyright (C) 2007-2008 OpenIntents.org - + Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at @@ -141,13 +209,17 @@ Portions of FileUtils.java: LocalStorageProvider.java: - Copyright (c) 2013, Ian Lake - All rights reserved. + Copyright (c) 2013, Ian Lake + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + - Neither the name of the nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. - Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - Neither the name of the nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file +> vim: set wrap tabstop=8 shiftwidth=4 softtabstop=4 expandtab : +> vim: set textwidth=0 filetype=markdown foldmethod=marker spell spelllang=en_gb: diff --git a/aFileChooser/pom.xml b/aFileChooser/pom.xml new file mode 100644 index 0000000..5a99216 --- /dev/null +++ b/aFileChooser/pom.xml @@ -0,0 +1,225 @@ + + + + + + + 4.0.0 + afilechooser-library + apklib + aFileChooser Library + aFileChooser is an Android Library Project that simplifies the process of presenting a file chooser on Android 2.1+. + + com.ipaulpro + afilechooser + 2.3 + + https://github.com/krischik/aFileChooser3 + + + krischik@users.sourceforge.net + krischik + Martin Krischik + UIQ3 open-source software and tools + https://sourceforge.net/projects/uiq3/ + + Deployer + + GMT+1 + https://sourceforge.net/users/krischik + + + + + pache License, Version 2.0 + + + + scm:git:https://github.com/krischik/aFileChooser3 + scm:git:https://github.com/krischik/aFileChooser3 + main + scm:git:https://github.com/krischik/aFileChooser3 + + + + + + + + android.support + compatibility-v4 + + + android + android + + + com.intellij + annotations + + + + + + + + + src + + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + org.apache.maven.plugins + maven-jar-plugin + + + com.jayway.maven.plugins.android.generation2 + android-maven-plugin + + false + true + + proguard.cfg + + -Xms256m + -Xmx512m + + false + + + false + + + true + + + org.apache.maven.plugins + maven-resources-plugin + + ${project.build.sourceEncoding} + + + + org.codehaus.mojo + build-helper-maven-plugin + + + add-source + generate-sources + + + gen + target/generated-sources/annotations + target/generated-sources/r + + + + add-source + + + + + + org.apache.maven.plugins + maven-clean-plugin + + + org.apache.maven.plugins + maven-checkstyle-plugin + + + install + + + + + + + + + release + + + + org.apache.maven.plugins + maven-compiler-plugin + + + + 1 + 1 + + + false + none + true + true + true + + + + com.jayway.maven.plugins.android.generation2 + android-maven-plugin + + true + + + + org.apache.maven.plugins + maven-source-plugin + + + attach-sources + + jar + test-jar + + + + + + + + + + + + + + + + + diff --git a/aFileChooser/src/com/ianhanniballake/localstorage/LocalStorageProvider.java b/aFileChooser/src/com/ianhanniballake/localstorage/LocalStorageProvider.java index ec59026..6f7ad8f 100644 --- a/aFileChooser/src/com/ianhanniballake/localstorage/LocalStorageProvider.java +++ b/aFileChooser/src/com/ianhanniballake/localstorage/LocalStorageProvider.java @@ -17,12 +17,15 @@ import android.webkit.MimeTypeMap; import com.ipaulpro.afilechooser.R; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; +@android.annotation.TargetApi (19) public class LocalStorageProvider extends DocumentsProvider { public static final String AUTHORITY = "com.ianhanniballake.localstorage.documents"; @@ -46,8 +49,8 @@ public class LocalStorageProvider extends DocumentsProvider { Document.COLUMN_LAST_MODIFIED }; - @Override - public Cursor queryRoots(final String[] projection) throws FileNotFoundException { + @Nullable @Override + public Cursor queryRoots(@Nullable final String[] projection) throws FileNotFoundException { // Create a cursor with either the requested fields, or the default // projection if "projection" is null. final MatrixCursor result = new MatrixCursor(projection != null ? projection @@ -70,7 +73,7 @@ public Cursor queryRoots(final String[] projection) throws FileNotFoundException return result; } - @Override + @Nullable @Override public String createDocument(final String parentDocumentId, final String mimeType, final String displayName) throws FileNotFoundException { File newFile = new File(parentDocumentId, displayName); @@ -83,8 +86,9 @@ public String createDocument(final String parentDocumentId, final String mimeTyp return null; } - @Override - public AssetFileDescriptor openDocumentThumbnail(final String documentId, final Point sizeHint, + @Nullable @Override + public AssetFileDescriptor openDocumentThumbnail(final String documentId, @NotNull + final Point sizeHint, final CancellationSignal signal) throws FileNotFoundException { // Assume documentId points to an image file. Build a thumbnail no // larger than twice the sizeHint @@ -136,8 +140,9 @@ public AssetFileDescriptor openDocumentThumbnail(final String documentId, final AssetFileDescriptor.UNKNOWN_LENGTH); } - @Override - public Cursor queryChildDocuments(final String parentDocumentId, final String[] projection, + @Nullable @Override + public Cursor queryChildDocuments(final String parentDocumentId, @Nullable + final String[] projection, final String sortOrder) throws FileNotFoundException { // Create a cursor with either the requested fields, or the default // projection if "projection" is null. @@ -154,8 +159,9 @@ public Cursor queryChildDocuments(final String parentDocumentId, final String[] return result; } - @Override - public Cursor queryDocument(final String documentId, final String[] projection) + @Nullable @Override + public Cursor queryDocument(final String documentId, @Nullable + final String[] projection) throws FileNotFoundException { // Create a cursor with either the requested fields, or the default // projection if "projection" is null. @@ -165,7 +171,9 @@ public Cursor queryDocument(final String documentId, final String[] projection) return result; } - private void includeFile(final MatrixCursor result, final File file) + private void includeFile( + @NotNull final MatrixCursor result, @NotNull + final File file) throws FileNotFoundException { final MatrixCursor.RowBuilder row = result.newRow(); // These columns are required @@ -215,7 +223,8 @@ public void deleteDocument(final String documentId) throws FileNotFoundException } @Override - public ParcelFileDescriptor openDocument(final String documentId, final String mode, + public ParcelFileDescriptor openDocument(final String documentId, @NotNull + final String mode, final CancellationSignal signal) throws FileNotFoundException { File file = new File(documentId); final boolean isWrite = (mode.indexOf('w') != -1); diff --git a/aFileChooser/src/com/ipaulpro/afilechooser/FileChooserActivity.java b/aFileChooser/src/com/ipaulpro/afilechooser/FileChooserActivity.java index 724cf1d..03e1297 100644 --- a/aFileChooser/src/com/ipaulpro/afilechooser/FileChooserActivity.java +++ b/aFileChooser/src/com/ipaulpro/afilechooser/FileChooserActivity.java @@ -16,6 +16,8 @@ package com.ipaulpro.afilechooser; +import android.annotation.SuppressLint; + import android.app.ActionBar; import android.content.BroadcastReceiver; import android.content.Context; @@ -33,8 +35,11 @@ import android.view.Menu; import android.view.MenuItem; import android.widget.Toast; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.io.File; +import java.util.ArrayList; /** * Main Activity that handles the FileListFragments @@ -42,41 +47,150 @@ * @version 2013-06-25 * @author paulburke (ipaulpro) */ +@SuppressWarnings ("CollectionDeclaredAsConcreteClass") public class FileChooserActivity extends FragmentActivity implements OnBackStackChangedListener, FileListFragment.Callbacks { - public static final String PATH = "path"; + /** + * TAG for log messages. + * */ + static final String TAG = FileChooserActivity.class.getName (); + + public static final String SAVE_INSTANCE_PATH = "path"; + public static final String EXTRA_FILTER_INCLUDE_EXTENSIONS = + "com.ipaulpro.afilechooser.EXTRA_FILTER_INCLUDE_EXTENSIONS"; + public static final String EXTRA_FILTER_BASE_PATH = + "com.ipaulpro.afilechooser.EXTRA_FILTER_BASE_PATH"; public static final String EXTERNAL_BASE_PATH = Environment .getExternalStorageDirectory().getAbsolutePath(); private static final boolean HAS_ACTIONBAR = Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB; - + /** + *

start activity

+ * + * @param callingActivity activity opening the chooser + * @param requestCode request code used to identiefy the result + * @param filterIncludeExtensions file extensions to display + */ + public static void startActivity ( + final android.app.Activity callingActivity, + final int requestCode, + final java.util.ArrayList filterIncludeExtensions) { + //android.util.Log.d (TAG, "+ startActivity"); + //android.util.Log.v (TAG, "> callingActivity = " + callingActivity); + //android.util.Log.v (TAG, "> requestCode = " + requestCode); + //android.util.Log.v (TAG, "> filterIncludeExtensions = " + filterIncludeExtensions); + + final Intent intent = new Intent (callingActivity, FileChooserActivity.class); + + intent.putStringArrayListExtra ( + FileChooserActivity.EXTRA_FILTER_INCLUDE_EXTENSIONS, + filterIncludeExtensions); + + //android.util.Log.v (TAG, "> intent = " + intent); + + try { + callingActivity.startActivityForResult (intent, requestCode); + } catch (@NotNull final android.content.ActivityNotFoundException e) { + // The reason for the existence of aFileChooser + android.util.Log.e (TAG, "LOG02230:", e); + } + + //android.util.Log.d (TAG, "- startActivity"); + return; + } // startActivity + + /** + *

start activity

+ * + * @param callingActivity activity opening the chooser + * @param requestCode request code used to identify the result + * @param baseDirectory base directory to show + * @param filterIncludeExtensions file extensions to display + */ + public static void startActivity ( + final android.app.Activity callingActivity, + final int requestCode, + final String baseDirectory, + final java.util.ArrayList filterIncludeExtensions) { + //android.util.Log.d (TAG, "+ startActivity"); + //android.util.Log.v (TAG, "> callingActivity = " + callingActivity); + //android.util.Log.v (TAG, "> requestCode = " + requestCode); + //android.util.Log.v (TAG, "> baseDirectory = " + baseDirectory); + //android.util.Log.v (TAG, "> filterIncludeExtensions = " + filterIncludeExtensions); + + final Intent intent = new Intent (callingActivity, FileChooserActivity.class); + + intent.putExtra ( + FileChooserActivity.EXTRA_FILTER_BASE_PATH, + baseDirectory); + intent.putStringArrayListExtra ( + FileChooserActivity.EXTRA_FILTER_INCLUDE_EXTENSIONS, + filterIncludeExtensions); + + //android.util.Log.v (TAG, "> intent = " + intent); + + try { + callingActivity.startActivityForResult (intent, requestCode); + } catch (@NotNull final android.content.ActivityNotFoundException e) { + // The reason for the existence of aFileChooser + android.util.Log.e (TAG, "LOG02230:", e); + } + + //android.util.Log.d (TAG, "- startActivity"); + return; + } // startActivity private FragmentManager mFragmentManager; - private BroadcastReceiver mStorageListener = new BroadcastReceiver() { + @NotNull private final BroadcastReceiver mStorageListener = new BroadcastReceiver() { @Override - public void onReceive(Context context, Intent intent) { + public void onReceive(final Context context, final Intent intent) { Toast.makeText(context, R.string.storage_removed, Toast.LENGTH_LONG).show(); finishWithResult(null); } }; - + /** + *

path to open first

+ */ private String mPath; + /** + *

extenstion to display

+ */ + private ArrayList mFilterIncludeExtensions = new ArrayList (); @Override - protected void onCreate(Bundle savedInstanceState) { + protected void onCreate(@Nullable final Bundle savedInstanceState) { + //android.util.Log.d (TAG, "+ onCreate"); + //android.util.Log.v (TAG, "> savedInstanceState = " + savedInstanceState); + super.onCreate(savedInstanceState); + final Intent intent = getIntent(); + + //android.util.Log.v (TAG, "> intent = " + intent); + + if(intent != null){ + mFilterIncludeExtensions = intent.getStringArrayListExtra ( + EXTRA_FILTER_INCLUDE_EXTENSIONS); + mPath = intent.getStringExtra ( + EXTRA_FILTER_BASE_PATH); + //android.util.Log.v (TAG, "> mFilterIncludeExtensions = " + mFilterIncludeExtensions); + //android.util.Log.v (TAG, "> mPath = " + mPath); + } mFragmentManager = getSupportFragmentManager(); - mFragmentManager.addOnBackStackChangedListener(this); + mFragmentManager.addOnBackStackChangedListener (this); if (savedInstanceState == null) { - mPath = EXTERNAL_BASE_PATH; + if (mPath == null) { + mPath = EXTERNAL_BASE_PATH; + } // if addFragment(); } else { - mPath = savedInstanceState.getString(PATH); + mPath = savedInstanceState.getString(SAVE_INSTANCE_PATH); } - setTitle(mPath); + setTitle(mPath); + + //android.util.Log.d (TAG, "- onCreate"); } @Override @@ -94,34 +208,37 @@ protected void onResume() { } @Override - protected void onSaveInstanceState(Bundle outState) { + protected void onSaveInstanceState(@NotNull final Bundle outState) { super.onSaveInstanceState(outState); - outState.putString(PATH, mPath); + outState.putString(SAVE_INSTANCE_PATH, mPath); } + @SuppressLint("NewApi") // Usages of New APIs are surrounded by sufficient conditional checks @Override public void onBackStackChanged() { - int count = mFragmentManager.getBackStackEntryCount(); + final int count = mFragmentManager.getBackStackEntryCount(); if (count > 0) { - BackStackEntry fragment = mFragmentManager.getBackStackEntryAt(count - 1); + final BackStackEntry fragment = mFragmentManager.getBackStackEntryAt(count - 1); mPath = fragment.getName(); } else { mPath = EXTERNAL_BASE_PATH; } setTitle(mPath); - if (HAS_ACTIONBAR) - invalidateOptionsMenu(); + if (HAS_ACTIONBAR) { + invalidateOptionsMenu (); + } } + @SuppressLint("NewApi") // Usages of New APIs are surrounded by sufficient conditional checks @Override - public boolean onCreateOptionsMenu(Menu menu) { + public boolean onCreateOptionsMenu(final Menu menu) { if (HAS_ACTIONBAR) { - boolean hasBackStack = mFragmentManager.getBackStackEntryCount() > 0; + final boolean hasBackStack = mFragmentManager.getBackStackEntryCount() > 0; + final ActionBar actionBar = getActionBar(); - ActionBar actionBar = getActionBar(); actionBar.setDisplayHomeAsUpEnabled(hasBackStack); actionBar.setHomeButtonEnabled(hasBackStack); } @@ -130,7 +247,7 @@ public boolean onCreateOptionsMenu(Menu menu) { } @Override - public boolean onOptionsItemSelected(MenuItem item) { + public boolean onOptionsItemSelected(@NotNull final MenuItem item) { switch (item.getItemId()) { case android.R.id.home: mFragmentManager.popBackStack(); @@ -144,7 +261,9 @@ public boolean onOptionsItemSelected(MenuItem item) { * Add the initial Fragment with given path. */ private void addFragment() { - FileListFragment fragment = FileListFragment.newInstance(mPath); + final FileListFragment fragment = FileListFragment.newInstance( + mPath, + mFilterIncludeExtensions); mFragmentManager.beginTransaction() .add(android.R.id.content, fragment).commit(); } @@ -155,10 +274,12 @@ private void addFragment() { * * @param file The file (directory) to display. */ - private void replaceFragment(File file) { + private void replaceFragment(@NotNull final File file) { mPath = file.getAbsolutePath(); - FileListFragment fragment = FileListFragment.newInstance(mPath); + final FileListFragment fragment = FileListFragment.newInstance( + mPath, + mFilterIncludeExtensions); mFragmentManager.beginTransaction() .replace(android.R.id.content, fragment) .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN) @@ -170,9 +291,9 @@ private void replaceFragment(File file) { * * @param file The file selected. */ - private void finishWithResult(File file) { + private void finishWithResult(@Nullable final File file) { if (file != null) { - Uri uri = Uri.fromFile(file); + final Uri uri = Uri.fromFile(file); setResult(RESULT_OK, new Intent().setData(uri)); finish(); } else { @@ -187,7 +308,7 @@ private void finishWithResult(File file) { * @param file The file that was selected */ @Override - public void onFileSelected(File file) { + public void onFileSelected(@Nullable final File file) { if (file != null) { if (file.isDirectory()) { replaceFragment(file); @@ -204,7 +325,7 @@ public void onFileSelected(File file) { * Register the external storage BroadcastReceiver. */ private void registerStorageListener() { - IntentFilter filter = new IntentFilter(); + final IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_MEDIA_REMOVED); registerReceiver(mStorageListener, filter); } diff --git a/aFileChooser/src/com/ipaulpro/afilechooser/FileListAdapter.java b/aFileChooser/src/com/ipaulpro/afilechooser/FileListAdapter.java index 3480122..8c53586 100644 --- a/aFileChooser/src/com/ipaulpro/afilechooser/FileListAdapter.java +++ b/aFileChooser/src/com/ipaulpro/afilechooser/FileListAdapter.java @@ -29,7 +29,7 @@ /** * List adapter for Files. - * + * * @version 2013-12-11 * @author paulburke (ipaulpro) */ @@ -42,8 +42,10 @@ public class FileListAdapter extends BaseAdapter { private List mData = new ArrayList(); - public FileListAdapter(Context context) { - mInflater = LayoutInflater.from(context); + public FileListAdapter(Context context) + { + super (); + mInflater = LayoutInflater.from (context); } public void add(File file) { diff --git a/aFileChooser/src/com/ipaulpro/afilechooser/FileListFragment.java b/aFileChooser/src/com/ipaulpro/afilechooser/FileListFragment.java index 5da363a..6d7dd57 100644 --- a/aFileChooser/src/com/ipaulpro/afilechooser/FileListFragment.java +++ b/aFileChooser/src/com/ipaulpro/afilechooser/FileListFragment.java @@ -24,19 +24,27 @@ import android.support.v4.content.Loader; import android.view.View; import android.widget.ListView; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.io.File; import java.util.List; +import java.util.ArrayList; /** * Fragment that displays a list of Files in a given path. - * + * * @version 2013-12-11 * @author paulburke (ipaulpro) */ +@SuppressWarnings ("CollectionDeclaredAsConcreteClass") public class FileListFragment extends ListFragment implements LoaderManager.LoaderCallbacks> { + /** + * TAG for log messages. + * */ + static final String TAG = FileListFragment.class.getName (); /** * Interface to listen for events. */ @@ -51,8 +59,15 @@ public interface Callbacks { private static final int LOADER_ID = 0; + @NotNull private FileListAdapter mAdapter; + /** + *

path to display. Not null after onCreate

+ */ + @NotNull private String mPath; + @Nullable + private ArrayList mFilterIncludeExtensions = new ArrayList(); private Callbacks mListener; @@ -62,39 +77,67 @@ public interface Callbacks { * @param path The absolute path of the file (directory) to display. * @return A new Fragment with the given file path. */ - public static FileListFragment newInstance(String path) { - FileListFragment fragment = new FileListFragment(); - Bundle args = new Bundle(); - args.putString(FileChooserActivity.PATH, path); + @NotNull public static FileListFragment newInstance( + @NotNull final String path, + @Nullable final ArrayList filterIncludeExtensions ) { + //android.util.Log.d (TAG, "+ newInstance"); + //android.util.Log.v (TAG, "> path = " + path); + //android.util.Log.v (TAG, "> filterIncludeExtensions = " + filterIncludeExtensions); + + final FileListFragment fragment = new FileListFragment(); + final Bundle args = new Bundle(); + + args.putString(FileChooserActivity.SAVE_INSTANCE_PATH, path); + args.putStringArrayList ( + FileChooserActivity.EXTRA_FILTER_INCLUDE_EXTENSIONS, + filterIncludeExtensions); fragment.setArguments(args); + //android.util.Log.v (TAG, "> fragment = " + fragment); + //android.util.Log.d (TAG, "+ newInstance"); return fragment; } @Override - public void onAttach(Activity activity) { + public void onAttach(@NotNull final Activity activity) { super.onAttach(activity); try { mListener = (Callbacks) activity; - } catch (ClassCastException e) { + } catch (@NotNull final ClassCastException e) { + android.util.Log.e (TAG, "LOG02240:", e); throw new ClassCastException(activity.toString() + " must implement FileListFragment.Callbacks"); } } @Override - public void onCreate(Bundle savedInstanceState) { + public void onCreate(final Bundle savedInstanceState) { + //android.util.Log.d (TAG, "+ onCreate"); + //android.util.Log.v (TAG, "> savedInstanceState = " + savedInstanceState); + super.onCreate(savedInstanceState); + final android.os.Bundle arguments = getArguments (); + mAdapter = new FileListAdapter(getActivity()); - mPath = getArguments() != null ? getArguments().getString( - FileChooserActivity.PATH) : Environment - .getExternalStorageDirectory().getAbsolutePath(); + + //android.util.Log.v (TAG, "> mAdapter = " + mAdapter); + //android.util.Log.v (TAG, "> arguments = " + arguments); + + mPath = arguments != null + ? arguments.getString (FileChooserActivity.SAVE_INSTANCE_PATH) + : Environment.getExternalStorageDirectory().getAbsolutePath(); + if(arguments != null){ + mFilterIncludeExtensions = arguments.getStringArrayList ( + FileChooserActivity.EXTRA_FILTER_INCLUDE_EXTENSIONS); + } + + //android.util.Log.d (TAG, "+ onCreate"); } @Override - public void onActivityCreated(Bundle savedInstanceState) { + public void onActivityCreated(final Bundle savedInstanceState) { setEmptyText(getString(R.string.empty_directory)); setListAdapter(mAdapter); setListShown(false); @@ -105,22 +148,22 @@ public void onActivityCreated(Bundle savedInstanceState) { } @Override - public void onListItemClick(ListView l, View v, int position, long id) { - FileListAdapter adapter = (FileListAdapter) l.getAdapter(); + public void onListItemClick(@NotNull final ListView l, final View v, final int position, final long id) { + final FileListAdapter adapter = (FileListAdapter) l.getAdapter(); if (adapter != null) { - File file = (File) adapter.getItem(position); + final File file = adapter.getItem(position); mPath = file.getAbsolutePath(); mListener.onFileSelected(file); } } - @Override - public Loader> onCreateLoader(int id, Bundle args) { - return new FileLoader(getActivity(), mPath); + @Nullable @Override + public Loader> onCreateLoader(final int id, final Bundle args) { + return new FileLoader(getActivity(), mPath, mFilterIncludeExtensions); } @Override - public void onLoadFinished(Loader> loader, List data) { + public void onLoadFinished(final Loader> loader, final List data) { mAdapter.setListItems(data); if (isResumed()) @@ -130,7 +173,7 @@ public void onLoadFinished(Loader> loader, List data) { } @Override - public void onLoaderReset(Loader> loader) { + public void onLoaderReset(final Loader> loader) { mAdapter.clear(); } } diff --git a/aFileChooser/src/com/ipaulpro/afilechooser/FileLoader.java b/aFileChooser/src/com/ipaulpro/afilechooser/FileLoader.java index f8903ac..b60cc2b 100644 --- a/aFileChooser/src/com/ipaulpro/afilechooser/FileLoader.java +++ b/aFileChooser/src/com/ipaulpro/afilechooser/FileLoader.java @@ -21,6 +21,8 @@ import android.support.v4.content.AsyncTaskLoader; import com.ipaulpro.afilechooser.utils.FileUtils; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.io.File; import java.util.ArrayList; @@ -29,7 +31,7 @@ /** * Loader that returns a list of Files in a given file path. - * + * * @version 2013-12-11 * @author paulburke (ipaulpro) */ @@ -40,20 +42,25 @@ public class FileLoader extends AsyncTaskLoader> { | FileObserver.MOVED_FROM | FileObserver.MOVED_TO | FileObserver.MODIFY | FileObserver.MOVE_SELF; - private FileObserver mFileObserver; + @Nullable private FileObserver mFileObserver; - private List mData; - private String mPath; + @Nullable private List mData; + private final String mPath; + @Nullable private final ArrayList mFilterIncludeExtensions; - public FileLoader(Context context, String path) { + public FileLoader( + @NotNull final Context context, + final String path, + @Nullable final ArrayList filterIncludeExtensions) { super(context); this.mPath = path; + this.mFilterIncludeExtensions = filterIncludeExtensions; } - @Override + @NotNull @Override public List loadInBackground() { - ArrayList list = new ArrayList(); + final ArrayList list = new ArrayList(); // Current directory File instance final File pathDir = new File(mPath); @@ -64,31 +71,30 @@ public List loadInBackground() { // Sort the folders alphabetically Arrays.sort(dirs, FileUtils.sComparator); // Add each folder to the File list for the list adapter - for (File dir : dirs) - list.add(dir); + java.util.Collections.addAll (list, dirs); } // List file in this directory with the file filter - final File[] files = pathDir.listFiles(FileUtils.sFileFilter); + final File[] files = pathDir.listFiles( + new FileUtils.FileExtensionFilter (mFilterIncludeExtensions)); if (files != null) { // Sort the files alphabetically Arrays.sort(files, FileUtils.sComparator); // Add each file to the File list for the list adapter - for (File file : files) - list.add(file); + java.util.Collections.addAll (list, files); } return list; } @Override - public void deliverResult(List data) { + public void deliverResult(final List data) { if (isReset()) { onReleaseResources(data); return; } - List oldData = mData; + final List oldData = mData; mData = data; if (isStarted()) @@ -100,21 +106,23 @@ public void deliverResult(List data) { @Override protected void onStartLoading() { - if (mData != null) - deliverResult(mData); + if (mData != null) { + deliverResult (mData); + } if (mFileObserver == null) { mFileObserver = new FileObserver(mPath, FILE_OBSERVER_MASK) { @Override - public void onEvent(int event, String path) { + public void onEvent(final int event, final String path) { onContentChanged(); } }; } mFileObserver.startWatching(); - if (takeContentChanged() || mData == null) - forceLoad(); + if (takeContentChanged() || mData == null) { + forceLoad (); + } } @Override @@ -133,13 +141,13 @@ protected void onReset() { } @Override - public void onCanceled(List data) { + public void onCanceled(final List data) { super.onCanceled(data); onReleaseResources(data); } - protected void onReleaseResources(List data) { + protected void onReleaseResources(final List data) { if (mFileObserver != null) { mFileObserver.stopWatching(); diff --git a/aFileChooser/src/com/ipaulpro/afilechooser/utils/FileUtils.java b/aFileChooser/src/com/ipaulpro/afilechooser/utils/FileUtils.java index 25c8008..c21f48d 100644 --- a/aFileChooser/src/com/ipaulpro/afilechooser/utils/FileUtils.java +++ b/aFileChooser/src/com/ipaulpro/afilechooser/utils/FileUtils.java @@ -32,10 +32,13 @@ import android.webkit.MimeTypeMap; import com.ianhanniballake.localstorage.LocalStorageProvider; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.io.File; import java.io.FileFilter; import java.text.DecimalFormat; +import java.util.ArrayList; import java.util.Comparator; /** @@ -44,11 +47,14 @@ * @version 2013-12-11 * @author paulburke (ipaulpro) */ +@SuppressWarnings ("HardcodedFileSeparator") public class FileUtils { private FileUtils() {} //private constructor to enforce Singleton pattern - - /** TAG for log messages. */ - static final String TAG = "FileUtils"; + + /** + * TAG for log messages. + * */ + static final String TAG = FileUtils.class.getName (); private static final boolean DEBUG = false; // Set to true to enable logging public static final String MIME_TYPE_AUDIO = "audio/*"; @@ -59,6 +65,47 @@ private FileUtils() {} //private constructor to enforce Singleton pattern public static final String HIDDEN_PREFIX = "."; + /** + * File Filter that includes only files with the specified extensions to pass + * @author Kiran Rao + * + */ + public static class FileExtensionFilter implements FileFilter{ + /** + *

file extension filter

+ */ + @Nullable private final ArrayList mFilterIncludeExtensions; + + public FileExtensionFilter (@Nullable final ArrayList filterIncludeExtensions){ + //android.util.Log.d (TAG, "+ FileExtensionFilter"); + //android.util.Log.v (TAG, "> filterIncludeExtensions = " + filterIncludeExtensions); + + this.mFilterIncludeExtensions = filterIncludeExtensions; + + //android.util.Log.d (TAG, "+ FileExtensionFilter"); + } + + @Override + public boolean accept(@NotNull final File file) { + //android.util.Log.d (TAG, "+ accept"); + //android.util.Log.v (TAG, "> file = " + file); + + final String fileName = file.getName(); + final android.net.Uri uri = android.net.Uri.fromFile (file); + final boolean passesExtensionsFilter = mFilterIncludeExtensions == null || + mFilterIncludeExtensions.isEmpty () || mFilterIncludeExtensions.contains ( + getExtension (uri.toString ())); + // Return files only (not directories) and skip hidden files + final boolean retval = file.isFile() && !fileName.startsWith(HIDDEN_PREFIX) && + passesExtensionsFilter; + + //android.util.Log.v (TAG, "> retval = " + retval); + //android.util.Log.d (TAG, "- accept"); + return retval; + } + + } + /** * Gets the extension of a file name, like ".png" or ".jpg". * @@ -66,12 +113,13 @@ private FileUtils() {} //private constructor to enforce Singleton pattern * @return Extension including the dot("."); "" if there is no extension; * null if uri was null. */ - public static String getExtension(String uri) { + @Nullable + public static String getExtension(@Nullable final String uri) { if (uri == null) { return null; } - int dot = uri.lastIndexOf("."); + final int dot = uri.lastIndexOf("."); if (dot >= 0) { return uri.substring(dot); } else { @@ -83,7 +131,7 @@ public static String getExtension(String uri) { /** * @return Whether the URI is a local one. */ - public static boolean isLocal(String url) { + public static boolean isLocal(@Nullable final String url) { if (url != null && !url.startsWith("http://") && !url.startsWith("https://")) { return true; } @@ -94,7 +142,7 @@ public static boolean isLocal(String url) { * @return True if Uri is a MediaStore Uri. * @author paulburke */ - public static boolean isMediaUri(Uri uri) { + public static boolean isMediaUri(@NotNull final Uri uri) { return "media".equalsIgnoreCase(uri.getAuthority()); } @@ -104,7 +152,8 @@ public static boolean isMediaUri(Uri uri) { * @param file * @return uri */ - public static Uri getUri(File file) { + @Nullable + public static Uri getUri(@Nullable final File file) { if (file != null) { return Uri.fromFile(file); } @@ -117,14 +166,15 @@ public static Uri getUri(File file) { * @param file * @return */ - public static File getPathWithoutFilename(File file) { + @Nullable + public static File getPathWithoutFilename(@Nullable final File file) { if (file != null) { if (file.isDirectory()) { // no file to be split off. Return everything return file; } else { - String filename = file.getName(); - String filepath = file.getAbsolutePath(); + final String filename = file.getName(); + final String filepath = file.getAbsolutePath(); // Construct path without file name. String pathwithoutname = filepath.substring(0, @@ -141,9 +191,9 @@ public static File getPathWithoutFilename(File file) { /** * @return The MIME type for the given file. */ - public static String getMimeType(File file) { + public static String getMimeType(@NotNull final File file) { - String extension = getExtension(file.getName()); + final String extension = getExtension(file.getName()); if (extension.length() > 0) return MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension.substring(1)); @@ -154,8 +204,10 @@ public static String getMimeType(File file) { /** * @return The MIME type for the give Uri. */ - public static String getMimeType(Context context, Uri uri) { - File file = new File(getPath(context, uri)); + public static String getMimeType( + @NotNull final Context context, @NotNull final + Uri uri) { + final File file = new File(getPath(context, uri)); return getMimeType(file); } @@ -164,7 +216,7 @@ public static String getMimeType(Context context, Uri uri) { * @return Whether the Uri authority is {@link LocalStorageProvider}. * @author paulburke */ - public static boolean isLocalStorageDocument(Uri uri) { + public static boolean isLocalStorageDocument(@NotNull final Uri uri) { return LocalStorageProvider.AUTHORITY.equals(uri.getAuthority()); } @@ -173,7 +225,7 @@ public static boolean isLocalStorageDocument(Uri uri) { * @return Whether the Uri authority is ExternalStorageProvider. * @author paulburke */ - public static boolean isExternalStorageDocument(Uri uri) { + public static boolean isExternalStorageDocument(@NotNull final Uri uri) { return "com.android.externalstorage.documents".equals(uri.getAuthority()); } @@ -182,7 +234,7 @@ public static boolean isExternalStorageDocument(Uri uri) { * @return Whether the Uri authority is DownloadsProvider. * @author paulburke */ - public static boolean isDownloadsDocument(Uri uri) { + public static boolean isDownloadsDocument(@NotNull final Uri uri) { return "com.android.providers.downloads.documents".equals(uri.getAuthority()); } @@ -191,7 +243,7 @@ public static boolean isDownloadsDocument(Uri uri) { * @return Whether the Uri authority is MediaProvider. * @author paulburke */ - public static boolean isMediaDocument(Uri uri) { + public static boolean isMediaDocument(@NotNull final Uri uri) { return "com.android.providers.media.documents".equals(uri.getAuthority()); } @@ -199,7 +251,7 @@ public static boolean isMediaDocument(Uri uri) { * @param uri The Uri to check. * @return Whether the Uri authority is Google Photos. */ - public static boolean isGooglePhotosUri(Uri uri) { + public static boolean isGooglePhotosUri(@NotNull final Uri uri) { return "com.google.android.apps.photos.content".equals(uri.getAuthority()); } @@ -214,8 +266,11 @@ public static boolean isGooglePhotosUri(Uri uri) { * @return The value of the _data column, which is typically a file path. * @author paulburke */ - public static String getDataColumn(Context context, Uri uri, String selection, - String[] selectionArgs) { + @Nullable public static String getDataColumn( + @NotNull final Context context, + final Uri uri, + final String selection, + final String[] selectionArgs) { Cursor cursor = null; final String column = "_data"; @@ -247,14 +302,18 @@ public static String getDataColumn(Context context, Uri uri, String selection, *
* Callers should check whether the path is local before assuming it * represents a local file. - * + * * @param context The context. * @param uri The Uri to query. * @see #isLocal(String) * @see #getFile(Context, Uri) * @author paulburke */ - public static String getPath(final Context context, final Uri uri) { + @Nullable + @android.annotation.SuppressLint ("NewApi") // Usages of New APIs are surrounded by sufficient conditional checks + public static String getPath( + @NotNull final Context context, + @NotNull final Uri uri) { if (DEBUG) Log.d(TAG + " File -", @@ -345,9 +404,12 @@ else if ("file".equalsIgnoreCase(uri.getScheme())) { * @see #getPath(Context, Uri) * @author paulburke */ - public static File getFile(Context context, Uri uri) { + @Nullable + public static File getFile( + @NotNull final Context context, + @Nullable final Uri uri) { if (uri != null) { - String path = getPath(context, uri); + final String path = getPath(context, uri); if (path != null && isLocal(path)) { return new File(path); } @@ -362,7 +424,7 @@ public static File getFile(Context context, Uri uri) { * @return * @author paulburke */ - public static String getReadableFileSize(int size) { + public static String getReadableFileSize(final int size) { final int BYTES_IN_KILOBYTES = 1024; final DecimalFormat dec = new DecimalFormat("###.#"); final String KILOBYTES = " KB"; @@ -395,7 +457,10 @@ public static String getReadableFileSize(int size) { * @return * @author paulburke */ - public static Bitmap getThumbnail(Context context, File file) { + @Nullable + public static Bitmap getThumbnail( + @NotNull final Context context, + @NotNull final File file) { return getThumbnail(context, getUri(file), getMimeType(file)); } @@ -408,7 +473,10 @@ public static Bitmap getThumbnail(Context context, File file) { * @return * @author paulburke */ - public static Bitmap getThumbnail(Context context, Uri uri) { + @Nullable + public static Bitmap getThumbnail( + @NotNull final Context context, + @NotNull final Uri uri) { return getThumbnail(context, uri, getMimeType(context, uri)); } @@ -422,7 +490,11 @@ public static Bitmap getThumbnail(Context context, Uri uri) { * @return * @author paulburke */ - public static Bitmap getThumbnail(Context context, Uri uri, String mimeType) { + @Nullable + public static Bitmap getThumbnail( + @NotNull final Context context, + @NotNull final Uri uri, + @NotNull final String mimeType) { if (DEBUG) Log.d(TAG, "Attempting to get thumbnail"); @@ -457,7 +529,7 @@ else if (mimeType.contains(FileUtils.MIME_TYPE_IMAGE)) { null); } } - } catch (Exception e) { + } catch (final Exception e) { if (DEBUG) Log.e(TAG, "getThumbnail", e); } finally { @@ -473,37 +545,26 @@ else if (mimeType.contains(FileUtils.MIME_TYPE_IMAGE)) { * * @author paulburke */ - public static Comparator sComparator = new Comparator() { + @NotNull public static Comparator sComparator = new Comparator() { @Override - public int compare(File f1, File f2) { + public int compare( + @NotNull final File f1, @NotNull final + File f2) { // Sort alphabetically by lower case, which is much cleaner - return f1.getName().toLowerCase().compareTo( + return f1.getName().toLowerCase(Locale.getDefault()).compareTo( f2.getName().toLowerCase()); } }; - /** - * File (not directories) filter. - * - * @author paulburke - */ - public static FileFilter sFileFilter = new FileFilter() { - @Override - public boolean accept(File file) { - final String fileName = file.getName(); - // Return files only (not directories) and skip hidden files - return file.isFile() && !fileName.startsWith(HIDDEN_PREFIX); - } - }; /** * Folder (directories) filter. * * @author paulburke */ - public static FileFilter sDirFilter = new FileFilter() { + @NotNull public static FileFilter sDirFilter = new FileFilter() { @Override - public boolean accept(File file) { + public boolean accept(@NotNull final File file) { final String fileName = file.getName(); // Return directories only and skip hidden directories return file.isDirectory() && !fileName.startsWith(HIDDEN_PREFIX); @@ -516,7 +577,7 @@ public boolean accept(File file) { * @return The intent for opening a file with Intent.createChooser() * @author paulburke */ - public static Intent createGetContentIntent() { + @NotNull public static Intent createGetContentIntent() { // Implicitly allow the user to select a particular kind of data final Intent intent = new Intent(Intent.ACTION_GET_CONTENT); // The MIME data type filter diff --git a/aFileChooserExample/AndroidManifest.xml b/aFileChooserExample/AndroidManifest.xml index e348b00..3ff8e02 100644 --- a/aFileChooserExample/AndroidManifest.xml +++ b/aFileChooserExample/AndroidManifest.xml @@ -30,7 +30,7 @@ android:icon="@drawable/ic_launcher" android:label="@string/app_name" > @@ -54,7 +54,6 @@ - - \ No newline at end of file + diff --git a/aFileChooserExample/pom.xml b/aFileChooserExample/pom.xml new file mode 100644 index 0000000..1d515f5 --- /dev/null +++ b/aFileChooserExample/pom.xml @@ -0,0 +1,276 @@ + + + + + + + 4.0.0 + afilechooser-expample + apk + aFileChooser Example + aFileChooser is an Android Library Project that simplifies the process of presenting a file chooser on Android 2.1+. + + com.ipaulpro + afilechooser + 2.3 + + https://github.com/krischik/aFileChooser3 + + + krischik@users.sourceforge.net + krischik + Martin Krischik + UIQ3 open-source software and tools + https://sourceforge.net/projects/uiq3/ + + Deployer + + GMT+1 + https://sourceforge.net/users/krischik + + + + + pache License, Version 2.0 + + + + scm:git:https://github.com/krischik/aFileChooser3 + scm:git:https://github.com/krischik/aFileChooser3 + main + scm:git:https://github.com/krischik/aFileChooser3 + + + + + + + + android.support + compatibility-v4 + compile + + + android + android + + + com.ipaulpro + afilechooser-library + apklib + + + org.androidannotations + androidannotations + provided + + + org.androidannotations + androidannotations-api + + + com.intellij + annotations + + + + + + + + + src + + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + org.apache.maven.plugins + maven-jar-plugin + + + com.jayway.maven.plugins.android.generation2 + android-maven-plugin + + false + true + + proguard.cfg + + -Xms256m + -Xmx512m + + true + + + true + + + true + + + org.apache.maven.plugins + maven-resources-plugin + + ${project.build.sourceEncoding} + + + + org.codehaus.mojo + build-helper-maven-plugin + + + add-source + generate-sources + + + gen + target/generated-sources/annotations + target/generated-sources/r + + + + add-source + + + + + + org.apache.maven.plugins + maven-clean-plugin + + + org.apache.maven.plugins + maven-checkstyle-plugin + + + org.apache.maven.plugins + maven-antrun-plugin + + + Initialize + initialize + + + + + + + + + + + run + + + + + + install + + + + + + + + + release + + + + org.apache.maven.plugins + maven-compiler-plugin + + + + 1 + 1 + + + false + none + true + true + true + + + + com.jayway.maven.plugins.android.generation2 + android-maven-plugin + + true + + + + org.apache.maven.plugins + maven-source-plugin + + + attach-sources + + jar + test-jar + + + + + + + + + + + + + + + + + diff --git a/aFileChooserExample/proguard.cfg b/aFileChooserExample/proguard.cfg index b1cdf17..54cbec1 100644 --- a/aFileChooserExample/proguard.cfg +++ b/aFileChooserExample/proguard.cfg @@ -2,6 +2,7 @@ -dontusemixedcaseclassnames -dontskipnonpubliclibraryclasses -dontpreverify +-dontoptimize -verbose -optimizations !code/simplification/arithmetic,!field/*,!class/merging/* diff --git a/aFileChooserExample/project.properties b/aFileChooserExample/project.properties index 6e983b1..22fdffb 100644 --- a/aFileChooserExample/project.properties +++ b/aFileChooserExample/project.properties @@ -10,3 +10,5 @@ # Project target. target=android-19 android.library.reference.1=../aFileChooser + + diff --git a/aFileChooserExample/res/layout/example.xml b/aFileChooserExample/res/layout/example.xml new file mode 100644 index 0000000..8cb7fea --- /dev/null +++ b/aFileChooserExample/res/layout/example.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + diff --git a/aFileChooserExample/res/values-v19/bools.xml b/aFileChooserExample/res/values-v19/bools.xml new file mode 100644 index 0000000..9cdd78a --- /dev/null +++ b/aFileChooserExample/res/values-v19/bools.xml @@ -0,0 +1,6 @@ + + + + true + + \ No newline at end of file diff --git a/aFileChooserExample/res/values/strings.xml b/aFileChooserExample/res/values/strings.xml index 8de29c7..c02fad9 100644 --- a/aFileChooserExample/res/values/strings.xml +++ b/aFileChooserExample/res/values/strings.xml @@ -1,5 +1,5 @@ - - - aFileChooserExample - Lorem ipsum + aFileChooserExample + Lorem ipsum + Choose from all files… + Choose pdf files… + Choose calculator files… \ No newline at end of file diff --git a/aFileChooserExample/src/com/ipaulpro/afilechooserexample/FileChooserExampleActivity.java b/aFileChooserExample/src/com/ipaulpro/afilechooserexample/FileChooserExampleActivity.java index 8fd11a8..fcfaaea 100644 --- a/aFileChooserExample/src/com/ipaulpro/afilechooserexample/FileChooserExampleActivity.java +++ b/aFileChooserExample/src/com/ipaulpro/afilechooserexample/FileChooserExampleActivity.java @@ -20,58 +20,101 @@ import android.content.ActivityNotFoundException; import android.content.Intent; import android.net.Uri; -import android.os.Bundle; import android.util.Log; -import android.view.View; -import android.view.View.OnClickListener; -import android.widget.Button; -import android.widget.Toast; - +import com.ipaulpro.afilechooser.FileChooserActivity; import com.ipaulpro.afilechooser.utils.FileUtils; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; /** * @author paulburke (ipaulpro) */ +@SuppressWarnings ({"CollectionDeclaredAsConcreteClass", "HardcodedFileSeparator"}) +@org.androidannotations.annotations.EActivity (R.layout.example) public class FileChooserExampleActivity extends Activity { - private static final String TAG = "FileChooserExampleActivity"; - - private static final int REQUEST_CODE = 6384; // onActivityResult request - // code + private static final String TAG = FileChooserExampleActivity.class.getName (); + /** + *

onActivityResult request code

+ */ + private static final int REQUEST_CODE = 6384; + @NotNull private static final ArrayList PDF_Files; + /** + *

File types for my calculator app. Replace it with whatever you want to test.

+ * + * author Martin Krischik" + */ + @NotNull private static final ArrayList Calculator_Files; + /** + *

Directory why the unit tests of my calculator app stores there files. The + * real app uses {@link android.content.Context.getExternalFilesDir(java.lang.String)}

+ * + * author Martin Krischik" + */ + @NotNull private static final String Calculator_Dir; - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - // Create a simple button to start the file chooser process - Button button = new Button(this); - button.setText(R.string.choose_file); - button.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - // Display the file chooser dialog - showChooser(); - } - }); - - setContentView(button); + static + { + PDF_Files = new java.util.ArrayList (); + PDF_Files.add (".pdf"); + Calculator_Files = new java.util.ArrayList (); + Calculator_Files.add (".af"); + Calculator_Files.add (".df"); + Calculator_Files.add (".pf"); + Calculator_Dir = FileChooserActivity.EXTERNAL_BASE_PATH + "/Android/FX-602P"; } - private void showChooser() { + @org.androidannotations.annotations.res.StringRes (R.string.chooser_title) + String chooser_title; + + @org.androidannotations.annotations.Click (R.id.All_Files) + void appFiles() { + android.util.Log.d (TAG, "+ All_Files"); + // Use the GET_CONTENT intent from the utility class - Intent target = FileUtils.createGetContentIntent(); + final Intent target = FileUtils.createGetContentIntent(); // Create the chooser Intent - Intent intent = Intent.createChooser( - target, getString(R.string.chooser_title)); + final Intent intent = Intent.createChooser(target, chooser_title); try { startActivityForResult(intent, REQUEST_CODE); - } catch (ActivityNotFoundException e) { - // The reason for the existence of aFileChooser + } catch (@NotNull final ActivityNotFoundException e) { + // The reason for the existence of aFileChooser + android.util.Log.e (TAG, "LOG02230:", e); } + + android.util.Log.d (TAG, "+ All_Files"); } + @org.androidannotations.annotations.Click (R.id.PDF_Files) + void pdfFiles() { + android.util.Log.d (TAG, "+ pdfFiles"); + + FileChooserActivity.startActivity ( + /* callingActivity => */ this, + /* requestCode => */ REQUEST_CODE, + /* filterIncludeExtensions => */ PDF_Files); + + android.util.Log.d (TAG, "- pdfFiles"); + } + @org.androidannotations.annotations.Click (R.id.Calculator_Files) + void calculatorFiles() { + android.util.Log.d (TAG, "+ calculatorFiles"); + + FileChooserActivity.startActivity ( + /* callingActivity => */ this, + /* requestCode => */ REQUEST_CODE, + /* baseDirectory => */ Calculator_Dir, + /* filterIncludeExtensions => */ Calculator_Files); + + android.util.Log.d (TAG, "- calculatorFiles"); + } @Override - protected void onActivityResult(int requestCode, int resultCode, Intent data) { + protected void onActivityResult( + final int requestCode, + final int resultCode, + @Nullable final Intent data) { switch (requestCode) { case REQUEST_CODE: // If the file selection was successful @@ -83,10 +126,12 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) { try { // Get the file path from the URI final String path = FileUtils.getPath(this, uri); - Toast.makeText(FileChooserExampleActivity.this, - "File Selected: " + path, Toast.LENGTH_LONG).show(); - } catch (Exception e) { - Log.e("FileSelectorTestActivity", "File select error", e); + final android.widget.Toast toast = android.widget.Toast.makeText ( + com.ipaulpro.afilechooserexample.FileChooserExampleActivity.this, + "File Selected: " + path, android.widget.Toast.LENGTH_LONG); + toast.show (); + } catch (@NotNull final Exception e) { + Log.e(TAG, "File select error", e); } } } @@ -94,4 +139,15 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) { } super.onActivityResult(requestCode, resultCode, data); } + + @Override public String toString () + { + return TAG + + "{super=" + + super.toString () + + ", chooser_title=“" + + chooser_title + + '”' + + '}'; + } } diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..2ced06a --- /dev/null +++ b/pom.xml @@ -0,0 +1,533 @@ + + + + + + + 4.0.0 + com.ipaulpro + afilechooser + pom + 2.3 + aFileChooser + aFileChooser is an Android Library Project that simplifies the process of presenting a file chooser on Android 2.1+. + https://github.com/krischik/aFileChooser3 + + + krischik@users.sourceforge.net + krischik + Martin Krischik + UIQ3 open-source software and tools + https://sourceforge.net/projects/uiq3/ + + Developer + + GMT+1 + https://sourceforge.net/users/krischik + + + + + pache License, Version 2.0 + + + + scm:git:https://github.com/krischik/aFileChooser3 + scm:git:https://github.com/krischik/aFileChooser3 + main + scm:git:https://github.com/krischik/aFileChooser3 + + + + + + ${repo.id} + ${repo.name} + ${repo.url} + + + ${repo.id} + ${repo.name} + ${repo.url} + + + + + + + + android.support + compatibility-v4 + ${android.support.version} + provided + jar + + + android + android + ${android.version} + provided + jar + + + com.ipaulpro + afilechooser-library + 2.3 + compile + apklib + + + org.androidannotations + androidannotations + ${androidannotations.version} + provided + + + org.androidannotations + androidannotations-api + ${androidannotations.version} + + + com.intellij + annotations + 12.0 + + + + + + + + + UIQ3-Library + UIQ3-Library + http://uiq3.sourceforge.net/Repository + + + codehaus.org + Codehaus repository + http://repository.codehaus.org/ + + + sonatype.org + Sonatype repository + https://oss.sonatype.org/content/groups/public + + + + + codehaus.org + http://repository.codehaus.org + Codehaus repository + + + sonatype.org + Sonatype repository + https://oss.sonatype.org/content/groups/public + + + + + + src + + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.9 + + + com.ipaulpro:* + + true + UTF-8 + UTF-8 + false + true + true + private + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.1 + + + + 10 + 10 + + + true + lines,vars,source + ${project.build.sourceEncoding} + + **/._* + **/.backups/* + **/.backups + **/.DS_Store + + true + 256m + 128m + false + true + true + ${java.version} + ${java.version} + + + + org.apache.maven.plugins + maven-source-plugin + 2.2.1 + + + org.apache.maven.plugins + maven-resources-plugin + 2.6 + + ${project.build.sourceEncoding} + + + + org.apache.maven.plugins + maven-dependency-plugin + 2.8 + + + org.apache.maven.plugins + maven-antrun-plugin + 1.7 + + + org.apache.maven.plugins + maven-jar-plugin + 2.4 + + + **/.DS_Store + **/*Suite.class + **/*Test.class + **/._* + **/.backups/* + **/.backups + + + + + org.apache.maven.plugins + maven-assembly-plugin + 2.4 + + + org.apache.maven.plugins + maven-checkstyle-plugin + 2.10 + + checkstyle-suppressions.xml + checkstyle-allman.xml + false + + + + net.sourceforge.uiq3 + Calculator-Checkstyle + 6.2.0 + + + + + com.jayway.maven.plugins.android.generation2 + android-maven-plugin + 3.7.0 + + true + + ${env.ANDROID_HOME} + ${android.platform} + + + false + + + + + org.apache.maven.plugins + maven-clean-plugin + 2.5 + + + + obj + + + gen + + + bin + + + gen-external-apklibs + + + + + + org.apache.maven.plugins + maven-antrun-plugin + 1.7 + + + org.apache.maven.plugins + maven-scm-plugin + 1.8.1 + + developerConnection + + + + org.codehaus.mojo + build-helper-maven-plugin + 1.8 + + + org.apache.maven.plugins + maven-site-plugin + 3.3 + + + org.apache.maven.plugins + maven-surefire-plugin + 2.15 + + true + + + + org.apache.maven.plugins + maven-project-info-reports-plugin + 2.7 + + + org.codehaus.mojo + dashboard-maven-plugin + 1.0.0-beta-1 + + + org.eclipse.m2e + lifecycle-mapping + 1.0.0 + + + + + + + + + maven-antrun-plugin + + run + + org.apache.maven.plugins + [1.7,) + + + + + + + + build-helper-maven-plugin + + add-source + add-test-source + + org.codehaus.mojo + [1.7,) + + + + + + + + + + + install + + + + wagon-ssh + org.apache.maven.wagon + 2.4 + + + wagon-scm + org.apache.maven.wagon + 2.4 + + + maven-scm-manager-plexus + org.apache.maven.scm + 1.8.1 + + + maven-scm-provider-svnexe + org.apache.maven.scm + 1.8.1 + + + + + + + + + + release + + + + org.apache.maven.plugins + maven-source-plugin + + + attach-sources + + jar + test-jar + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + + + attach-documentation + + jar + test-jar + + + + + + org.apache.maven.plugins + maven-site-plugin + + private + true + UTF-8 + UTF-8 + true + false + + + org.apache.maven.plugins + maven-javadoc-plugin + + private + true + true + + com.ipaulpro:* + + UTF-8 + UTF-8 + true + false + + + + net.alchim31.maven + scala-maven-plugin + + ${scala.version} + + + + org.apache.maven.plugins + maven-project-info-reports-plugin + + + org.codehaus.mojo + dashboard-maven-plugin + + + org.apache.maven.plugins + maven-surefire-plugin + + + org.scalatest + scalatest-maven-plugin + + + org.apache.maven.plugins + maven-checkstyle-plugin + + + + + + + + + + + + + 19 + 19 + 4.4_r1 + 1.6 + UTF-8 + UTF-8 + UTF-8 + 3.0 + + + + + aFileChooser + aFileChooserExample + + + + +