diff --git a/build.gradle b/build.gradle index a93bd4d..09d2895 100644 --- a/build.gradle +++ b/build.gradle @@ -10,8 +10,6 @@ buildscript { repositories { jcenter() } - dependencies { - } } allprojects { diff --git a/examples/.gitignore b/examples/.gitignore deleted file mode 100644 index 796b96d..0000000 --- a/examples/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build diff --git a/examples/build.gradle b/examples/build.gradle deleted file mode 100644 index cd373f2..0000000 --- a/examples/build.gradle +++ /dev/null @@ -1,27 +0,0 @@ -apply plugin: 'com.android.application' - -android { - compileSdkVersion 24 - buildToolsVersion "24.0.1" - - defaultConfig { - applicationId "com.nononsenseapps.filepicker.examples" - minSdkVersion 15 - targetSdkVersion 24 - versionCode 1 - versionName "1.0" - } - buildTypes { - release { - minifyEnabled false - proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' - } - } -} - -dependencies { - compile fileTree(dir: 'libs', include: ['*.jar']) - compile project(':library') - testCompile 'junit:junit:4.12' - compile 'com.android.support:appcompat-v7:24.2.0' -} diff --git a/examples/proguard-rules.pro b/examples/proguard-rules.pro deleted file mode 100644 index e1675e5..0000000 --- a/examples/proguard-rules.pro +++ /dev/null @@ -1,17 +0,0 @@ -# Add project specific ProGuard rules here. -# By default, the flags in this file are appended to flags specified -# in /home/jonas/Android/Sdk/tools/proguard/proguard-android.txt -# You can edit the include path and order by changing the proguardFiles -# directive in build.gradle. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# Add any project specific keep options here: - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} diff --git a/examples/src/androidTest/java/com/nononsenseapps/filepicker/examples/ApplicationTest.java b/examples/src/androidTest/java/com/nononsenseapps/filepicker/examples/ApplicationTest.java deleted file mode 100644 index 3775895..0000000 --- a/examples/src/androidTest/java/com/nononsenseapps/filepicker/examples/ApplicationTest.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.nononsenseapps.filepicker.examples; - -import android.app.Application; -import android.test.ApplicationTestCase; - -/** - * Testing Fundamentals - */ -public class ApplicationTest extends ApplicationTestCase { - public ApplicationTest() { - super(Application.class); - } -} \ No newline at end of file diff --git a/examples/src/main/AndroidManifest.xml b/examples/src/main/AndroidManifest.xml deleted file mode 100644 index 890a54d..0000000 --- a/examples/src/main/AndroidManifest.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/examples/src/main/java/com/nononsenseapps/filepicker/examples/backbutton/BackHandlingFilePickerActivity.java b/examples/src/main/java/com/nononsenseapps/filepicker/examples/backbutton/BackHandlingFilePickerActivity.java deleted file mode 100644 index 4a076f3..0000000 --- a/examples/src/main/java/com/nononsenseapps/filepicker/examples/backbutton/BackHandlingFilePickerActivity.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.nononsenseapps.filepicker.examples.backbutton; - -import android.os.Environment; - -import com.nononsenseapps.filepicker.AbstractFilePickerFragment; -import com.nononsenseapps.filepicker.FilePickerActivity; - -import java.io.File; - -public class BackHandlingFilePickerActivity extends FilePickerActivity { - - /** - * Need access to the fragment - */ - BackHandlingFilePickerFragment currentFragment; - - /** - * Return a copy of the new fragment and set the variable above. - */ - @Override - protected AbstractFilePickerFragment getFragment( - final String startPath, final int mode, final boolean allowMultiple, - final boolean allowDirCreate, final boolean allowExistingFile, - final boolean singleClick) { - - // startPath is allowed to be null. - // In that case, default folder should be SD-card and not "/" - String path = (startPath != null ? startPath - : Environment.getExternalStorageDirectory().getPath()); - - currentFragment = new BackHandlingFilePickerFragment(); - currentFragment.setArgs(path, mode, allowMultiple, allowDirCreate, - allowExistingFile, singleClick); - return currentFragment; - } - - /** - * Override the back-button. - */ - @Override - public void onBackPressed() { - // If at top most level, normal behaviour - if (currentFragment.isBackTop()) { - super.onBackPressed(); - } else { - // Else go up - currentFragment.goUp(); - } - } -} diff --git a/examples/src/main/java/com/nononsenseapps/filepicker/examples/backbutton/BackHandlingFilePickerFragment.java b/examples/src/main/java/com/nononsenseapps/filepicker/examples/backbutton/BackHandlingFilePickerFragment.java deleted file mode 100644 index 56a2a14..0000000 --- a/examples/src/main/java/com/nononsenseapps/filepicker/examples/backbutton/BackHandlingFilePickerFragment.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.nononsenseapps.filepicker.examples.backbutton; - -import com.nononsenseapps.filepicker.FilePickerFragment; - -import java.io.File; - -public class BackHandlingFilePickerFragment extends FilePickerFragment { - - /** - * For consistency, the top level the back button checks against should be the start path. - * But it will fall back on /. - */ - public File getBackTop() { - return getPath(getArguments().getString(KEY_START_PATH, "/")); - } - - /** - * @return true if the current path is the startpath or / - */ - public boolean isBackTop() { - return 0 == compareFiles(mCurrentPath, getBackTop()) || - 0 == compareFiles(mCurrentPath, new File("/")); - } - - /** - * Go up on level, same as pressing on "..". - */ - public void goUp() { - mCurrentPath = getParent(mCurrentPath); - mCheckedItems.clear(); - mCheckedVisibleViewHolders.clear(); - refresh(mCurrentPath); - } -} \ No newline at end of file diff --git a/examples/src/main/res/mipmap-hdpi/ic_launcher.png b/examples/src/main/res/mipmap-hdpi/ic_launcher.png deleted file mode 100644 index cde69bc..0000000 Binary files a/examples/src/main/res/mipmap-hdpi/ic_launcher.png and /dev/null differ diff --git a/examples/src/main/res/mipmap-mdpi/ic_launcher.png b/examples/src/main/res/mipmap-mdpi/ic_launcher.png deleted file mode 100644 index c133a0c..0000000 Binary files a/examples/src/main/res/mipmap-mdpi/ic_launcher.png and /dev/null differ diff --git a/examples/src/main/res/mipmap-xhdpi/ic_launcher.png b/examples/src/main/res/mipmap-xhdpi/ic_launcher.png deleted file mode 100644 index bfa42f0..0000000 Binary files a/examples/src/main/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ diff --git a/examples/src/main/res/mipmap-xxhdpi/ic_launcher.png b/examples/src/main/res/mipmap-xxhdpi/ic_launcher.png deleted file mode 100644 index 324e72c..0000000 Binary files a/examples/src/main/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ diff --git a/examples/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/examples/src/main/res/mipmap-xxxhdpi/ic_launcher.png deleted file mode 100644 index aee44e1..0000000 Binary files a/examples/src/main/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ diff --git a/examples/src/main/res/values/colors.xml b/examples/src/main/res/values/colors.xml deleted file mode 100644 index c4c54cb..0000000 --- a/examples/src/main/res/values/colors.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - #F44336 - #D32F2F - #FFAB00 - diff --git a/examples/src/main/res/values/strings.xml b/examples/src/main/res/values/strings.xml deleted file mode 100644 index 855b71e..0000000 --- a/examples/src/main/res/values/strings.xml +++ /dev/null @@ -1,3 +0,0 @@ - - Examples - diff --git a/examples/src/main/res/values/styles.xml b/examples/src/main/res/values/styles.xml deleted file mode 100644 index a59f4d1..0000000 --- a/examples/src/main/res/values/styles.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - diff --git a/examples/src/test/java/com/nononsenseapps/filepicker/examples/ExampleUnitTest.java b/examples/src/test/java/com/nononsenseapps/filepicker/examples/ExampleUnitTest.java deleted file mode 100644 index c71797e..0000000 --- a/examples/src/test/java/com/nononsenseapps/filepicker/examples/ExampleUnitTest.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.nononsenseapps.filepicker.examples; - -import org.junit.Test; - -import static org.junit.Assert.*; - -/** - * To work on unit tests, switch the Test Artifact in the Build Variants view. - */ -public class ExampleUnitTest { - @Test - public void addition_isCorrect() throws Exception { - assertEquals(4, 2 + 2); - } -} \ No newline at end of file diff --git a/library/build.gradle b/library/build.gradle index 900e8c1..0a9dbd8 100644 --- a/library/build.gradle +++ b/library/build.gradle @@ -5,33 +5,19 @@ apply plugin: 'com.android.library' * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -// must be applied after your artifact generating plugin (eg. java / com.android.library) -//apply plugin: 'bintray-release' - -// query git for the the SHA, Tag and commit count. Use these to automate versioning. -def gitTag = 'git describe --tags'.execute([], project.rootDir).text.trim() -def gitCommitCount = - Integer.parseInt('git rev-list --count HEAD'.execute([], project.rootDir).text.trim()) - android { - compileSdkVersion 24 - buildToolsVersion "23.0.3" + compileSdkVersion 25 + buildToolsVersion '25.0.2' defaultConfig { minSdkVersion 9 - targetSdkVersion 23 - versionCode gitCommitCount - versionName gitTag + targetSdkVersion 25 } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) - compile 'com.android.support:appcompat-v7:24.2.1' - compile 'com.android.support:support-v4:24.2.1' - compile 'com.android.support:recyclerview-v7:24.2.1' - - testCompile 'junit:junit:4.12' + compile 'com.android.support:appcompat-v7:25.3.1' + compile 'com.android.support:support-v4:25.3.1' + compile 'com.android.support:recyclerview-v7:25.3.1' } - - diff --git a/library/src/main/res/layout/nnf_dialog_folder_name.xml b/library/src/main/res/layout/nnf_dialog_folder_name.xml index cfba5b3..6da719a 100644 --- a/library/src/main/res/layout/nnf_dialog_folder_name.xml +++ b/library/src/main/res/layout/nnf_dialog_folder_name.xml @@ -18,11 +18,11 @@ android:layout_marginLeft="16dp" android:layout_marginRight="16dp" android:fontFamily="light" + android:maxLines="1" android:gravity="center_vertical" android:hint="@string/nnf_name" android:imeOptions="actionDone" android:inputType="textAutoComplete|textAutoCorrect" - android:singleLine="true" android:padding="4dp" tools:ignore="UnusedAttribute"/> \ No newline at end of file diff --git a/library/src/main/res/layout/nnf_filepicker_listitem_checkable.xml b/library/src/main/res/layout/nnf_filepicker_listitem_checkable.xml index 7560480..a5924e6 100644 --- a/library/src/main/res/layout/nnf_filepicker_listitem_checkable.xml +++ b/library/src/main/res/layout/nnf_filepicker_listitem_checkable.xml @@ -28,7 +28,7 @@ android:src="@drawable/nnf_ic_folder_black_48dp" android:tint="?attr/nnf_dir_icon_color" android:visibility="visible" - tools:ignore="ContentDescription"/> + tools:ignore="ContentDescription,VectorDrawableCompat" /> + android:text="@string/nnf_name" /> + tools:ignore="ContentDescription,VectorDrawableCompat"/> + \ No newline at end of file diff --git a/library/src/main/res/layout/nnf_fragment_filepicker.xml b/library/src/main/res/layout/nnf_fragment_filepicker.xml index 54335f5..8258b2a 100644 --- a/library/src/main/res/layout/nnf_fragment_filepicker.xml +++ b/library/src/main/res/layout/nnf_fragment_filepicker.xml @@ -25,8 +25,8 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:ellipsize="start" - android:singleLine="true" - android:textAppearance="@style/TextAppearance.AppCompat.Widget.ActionBar.Title"/> + android:textAppearance="@style/TextAppearance.AppCompat.Widget.ActionBar.Title" + android:maxLines="1"/> + android:tint="?attr/nnf_save_icon_color" + tools:ignore="VectorDrawableCompat"/> diff --git a/sample/README.md b/sample/README.md deleted file mode 100644 index b0b4422..0000000 --- a/sample/README.md +++ /dev/null @@ -1,20 +0,0 @@ -# SD-card picker - -The sample app demonstrates the SD-card file chooser in action. No configuration is necessary for that. - - -# Dropbox picker - -If you want to try the Dropbox part of the sample, you'll need to get your own -API-keys at [https://www.dropbox.com/developers/apps](https://www.dropbox.com/developers/apps) -and insert them into DropboxSyncHelper.java and AndroidManifest.xml. See Dropbox for more details -on that: - - - -The dropbox sample uses the Core API. If you want to use the Sync API, have look at: - -https://github.com/spacecowboy/NotePad/tree/master/core/src/com/nononsenseapps/filepicker - -for an example of that. diff --git a/sample/build.gradle b/sample/build.gradle deleted file mode 100644 index 7edaddf..0000000 --- a/sample/build.gradle +++ /dev/null @@ -1,68 +0,0 @@ -/* - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -apply plugin: 'com.android.application' - -def gitTag = 'git describe --tags'.execute([], project.rootDir).text.trim() -def gitCommitCount = - Integer.parseInt('git rev-list --count HEAD'.execute([], project.rootDir).text.trim()) - -android { - compileSdkVersion 23 - buildToolsVersion "23.0.2" - - packagingOptions { - exclude 'META-INF/LICENSE.txt' - exclude 'META-INF/NOTICE.txt' - } - - lintOptions { - abortOnError false - } - - defaultConfig { - minSdkVersion 18 - targetSdkVersion 23 - versionCode gitCommitCount - versionName gitTag - archivesBaseName = "nononsensefilepicker-sample-${gitTag}".toString() - testInstrumentationRunner 'android.support.test.runner.AndroidJUnitRunner' - } - - buildTypes { - release { - release { - archivesBaseName = "nononsensefilepicker-sample-${gitTag}".toString() - //minifyEnabled true - //shrinkResources true - //proguardFiles getDefaultProguardFile('proguard-android.txt') - } - } - } -} - -dependencies { - compile fileTree(dir: 'libs', include: ['*.jar']) - compile project(':library') - - // Image loading sample - compile 'com.github.bumptech.glide:glide:3.6.1' - - // FTP browser sample - compile 'commons-net:commons-net:3.3' - - // Root example - compile 'eu.chainfire:libsuperuser:1.0.0.+' - - // Fast scroll example - compile 'com.simplecityapps:recyclerview-fastscroll:1.0.9' - - // UI Tests - compile 'com.android.support.test.espresso:espresso-core:2.2.2' - compile 'com.android.support.test:runner:0.5' - compile 'com.android.support.test.espresso:espresso-contrib:2.2.2' - compile 'com.android.support.test.uiautomator:uiautomator-v18:2.1.2' -} diff --git a/sample/libs/ALL_LIBS_ARE_FOR_DROPBOX b/sample/libs/ALL_LIBS_ARE_FOR_DROPBOX deleted file mode 100644 index e69de29..0000000 diff --git a/sample/libs/HTTPCOMPONENTS-LICENSE.txt b/sample/libs/HTTPCOMPONENTS-LICENSE.txt deleted file mode 100644 index 2c41ec8..0000000 --- a/sample/libs/HTTPCOMPONENTS-LICENSE.txt +++ /dev/null @@ -1,182 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - -This project contains annotations derived from JCIP-ANNOTATIONS -Copyright (c) 2005 Brian Goetz and Tim Peierls. -See http://www.jcip.net and the Creative Commons Attribution License -(http://creativecommons.org/licenses/by/2.5) - diff --git a/sample/libs/JSON-SIMPLE-LICENSE.txt b/sample/libs/JSON-SIMPLE-LICENSE.txt deleted file mode 100644 index 57bc88a..0000000 --- a/sample/libs/JSON-SIMPLE-LICENSE.txt +++ /dev/null @@ -1,202 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - 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 - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - diff --git a/sample/libs/dropbox-android-sdk-1.6.3.jar b/sample/libs/dropbox-android-sdk-1.6.3.jar deleted file mode 100644 index 1a0ee36..0000000 Binary files a/sample/libs/dropbox-android-sdk-1.6.3.jar and /dev/null differ diff --git a/sample/libs/httpmime-4.0.3.jar b/sample/libs/httpmime-4.0.3.jar deleted file mode 100644 index 0dfd331..0000000 Binary files a/sample/libs/httpmime-4.0.3.jar and /dev/null differ diff --git a/sample/libs/json_simple-1.1.jar b/sample/libs/json_simple-1.1.jar deleted file mode 100644 index f395f41..0000000 Binary files a/sample/libs/json_simple-1.1.jar and /dev/null differ diff --git a/sample/proguard-rules.txt b/sample/proguard-rules.txt deleted file mode 100644 index 5345dc7..0000000 --- a/sample/proguard-rules.txt +++ /dev/null @@ -1,17 +0,0 @@ -# Add project specific ProGuard rules here. -# By default, the flags in this file are appended to flags specified -# in /home/jonas/android-sdk-linux/tools/proguard/proguard-android.txt -# You can edit the include path and order by changing the ProGuard -# include property in project.properties. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# Add any project specific keep options here: - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} \ No newline at end of file diff --git a/sample/src/androidTest/java/com/nononsenseapps/filepicker/sample/FastScrollerNewFile.java b/sample/src/androidTest/java/com/nononsenseapps/filepicker/sample/FastScrollerNewFile.java deleted file mode 100644 index 6cea725..0000000 --- a/sample/src/androidTest/java/com/nononsenseapps/filepicker/sample/FastScrollerNewFile.java +++ /dev/null @@ -1,425 +0,0 @@ -package com.nononsenseapps.filepicker.sample; - - -import android.support.test.espresso.ViewInteraction; -import android.support.test.espresso.action.ViewActions; -import android.support.test.rule.ActivityTestRule; -import android.support.test.runner.AndroidJUnit4; -import android.test.suitebuilder.annotation.LargeTest; - -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.io.IOException; - -import static android.support.test.espresso.Espresso.onView; -import static android.support.test.espresso.action.ViewActions.click; -import static android.support.test.espresso.action.ViewActions.replaceText; -import static android.support.test.espresso.assertion.ViewAssertions.matches; -import static android.support.test.espresso.contrib.RecyclerViewActions.actionOnItemAtPosition; -import static android.support.test.espresso.contrib.RecyclerViewActions.scrollTo; -import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; -import static android.support.test.espresso.matcher.ViewMatchers.withId; -import static android.support.test.espresso.matcher.ViewMatchers.withParent; -import static android.support.test.espresso.matcher.ViewMatchers.withText; -import static com.nononsenseapps.filepicker.sample.PermissionGranter.allowPermissionsIfNeeded; -import static org.hamcrest.Matchers.allOf; - -@LargeTest -@RunWith(AndroidJUnit4.class) -public class FastScrollerNewFile { - - @Rule - public ActivityTestRule mActivityTestRule = - new ActivityTestRule<>(NoNonsenseFilePickerTest.class); - - @Before - public void allowPermissions() { - allowPermissionsIfNeeded(mActivityTestRule.getActivity()); - } - - @Test - public void selectNewFile() throws IOException { - ViewInteraction radioButton = onView( - allOf(withId(R.id.radioNewFile), withText("Select new file"), - withParent(withId(R.id.radioGroup)), - isDisplayed())); - radioButton.perform(click()); - - ViewInteraction checkBox = onView( - allOf(withId(R.id.checkAllowExistingFile), withText("Allow selection of existing (new) file"), isDisplayed())); - checkBox.perform(click()); - - onView(withId(R.id.button_fastscroll)).perform(ViewActions.scrollTo()); - - ViewInteraction button = onView( - allOf(withId(R.id.button_fastscroll), withText("Pick With Fast Scroller"), - isDisplayed())); - button.perform(click()); - - ViewInteraction recyclerView = onView( - allOf(withId(android.R.id.list), isDisplayed())); - - // Refresh view (into dir, and out again) - recyclerView.perform(actionOnItemAtPosition(1, click())); - recyclerView.perform(actionOnItemAtPosition(0, click())); - - // Click on test dir - recyclerView.perform(actionOnItemAtPosition(1, click())); - // sub dir - recyclerView.perform(actionOnItemAtPosition(3, click())); - - ViewInteraction appCompatEditText = onView( - allOf(withId(R.id.nnf_text_filename), - withParent(allOf(withId(R.id.nnf_newfile_button_container), - withParent(withId(R.id.nnf_buttons_container)))), - isDisplayed())); - // new file name - appCompatEditText.perform(replaceText("testfile")); - - ViewInteraction appCompatImageButton = onView( - allOf(withId(R.id.nnf_button_ok_newfile), - withParent(allOf(withId(R.id.nnf_newfile_button_container), - withParent(withId(R.id.nnf_buttons_container)))), - isDisplayed())); - // Click ok - appCompatImageButton.perform(click()); - - ViewInteraction textView = onView(withId(R.id.text)); - textView.check(matches(withText("file:///storage/emulated/0/000000_nonsense-tests/C-dir/testfile"))); - } - - @Test - public void withSingleClick() throws IOException { - ViewInteraction radioButton = onView( - allOf(withId(R.id.radioNewFile), - withParent(withId(R.id.radioGroup)), - isDisplayed())); - radioButton.perform(click()); - - ViewInteraction checkBox = onView( - allOf(withId(R.id.checkSingleClick), isDisplayed())); - checkBox.perform(click()); - - onView(withId(R.id.button_fastscroll)).perform(ViewActions.scrollTo()); - - ViewInteraction button = onView( - allOf(withId(R.id.button_fastscroll), isDisplayed())); - button.perform(click()); - - ViewInteraction recyclerView = onView( - allOf(withId(android.R.id.list), isDisplayed())); - - // Refresh view (into dir, and out again) - recyclerView.perform(actionOnItemAtPosition(1, click())); - recyclerView.perform(actionOnItemAtPosition(0, click())); - - // Navigate to file - recyclerView.perform(actionOnItemAtPosition(1, click())); - recyclerView.perform(actionOnItemAtPosition(2, click())); - // Click file - recyclerView.perform(actionOnItemAtPosition(4, click())); - - // Should have returned - ViewInteraction textView = onView(withId(R.id.text)); - textView.check(matches(withText("file:///storage/emulated/0/000000_nonsense-tests/B-dir/file-3.txt"))); - } - - @Test - public void clickTwiceShouldNotClearFilename() throws IOException { - ViewInteraction radioButton = onView( - allOf(withId(R.id.radioNewFile), withText("Select new file"), - withParent(withId(R.id.radioGroup)), - isDisplayed())); - radioButton.perform(click()); - - onView(withId(R.id.button_fastscroll)).perform(ViewActions.scrollTo()); - - ViewInteraction button = onView( - allOf(withId(R.id.button_fastscroll), withText("Pick With Fast Scroller"), - isDisplayed())); - button.perform(click()); - - ViewInteraction recyclerView = onView( - allOf(withId(android.R.id.list), isDisplayed())); - - // Refresh view (into dir, and out again) - recyclerView.perform(actionOnItemAtPosition(1, click())); - recyclerView.perform(actionOnItemAtPosition(0, click())); - - // Navigate to file - recyclerView.perform(actionOnItemAtPosition(1, click())); - - recyclerView.perform(actionOnItemAtPosition(2, click())); - - // Click on file once - recyclerView.perform(actionOnItemAtPosition(4, click())); - - // Filename should be entered in field - ViewInteraction editText = onView(withId(R.id.nnf_text_filename)); - editText.check(matches(withText("file-3.txt"))); - - // Click twice - recyclerView.perform(actionOnItemAtPosition(4, click())); - - // Filename should not change - editText.check(matches(withText("file-3.txt"))); - } - - @Test - public void enterFileNameWithPathWhichExists() throws IOException { - ViewInteraction radioButton = onView( - allOf(withId(R.id.radioNewFile), withText("Select new file"), - withParent(withId(R.id.radioGroup)), - isDisplayed())); - radioButton.perform(click()); - - ViewInteraction checkBox = onView( - allOf(withId(R.id.checkAllowExistingFile), - withText("Allow selection of existing (new) file"), isDisplayed())); - checkBox.perform(click()); - - onView(withId(R.id.button_fastscroll)).perform(ViewActions.scrollTo()); - - ViewInteraction button = onView( - allOf(withId(R.id.button_fastscroll), withText("Pick With Fast Scroller"), isDisplayed())); - button.perform(click()); - - ViewInteraction recyclerView = onView( - allOf(withId(android.R.id.list), isDisplayed())); - - // Refresh view (into dir, and out again) - recyclerView.perform(actionOnItemAtPosition(1, click())); - recyclerView.perform(actionOnItemAtPosition(0, click())); - - // Click on test dir - recyclerView.perform(actionOnItemAtPosition(1, click())); - - // Enter path in filename - ViewInteraction appCompatEditText = onView( - allOf(withId(R.id.nnf_text_filename), - withParent(allOf(withId(R.id.nnf_newfile_button_container), - withParent(withId(R.id.nnf_buttons_container)))), - isDisplayed())); - // new file name - appCompatEditText.perform(replaceText("B-dir/file-3.txt")); - - // Click ok - ViewInteraction appCompatImageButton = onView( - allOf(withId(R.id.nnf_button_ok_newfile), - withParent(allOf(withId(R.id.nnf_newfile_button_container), - withParent(withId(R.id.nnf_buttons_container)))), - isDisplayed())); - appCompatImageButton.perform(click()); - - // Should have returned - ViewInteraction textView = onView(withId(R.id.text)); - textView.check(matches(withText("file:///storage/emulated/0/000000_nonsense-tests/B-dir/file-3.txt"))); - } - - @Test - public void enterFileNameWithPathWhichDoesNotExist() throws IOException { - ViewInteraction radioButton = onView( - allOf(withId(R.id.radioNewFile), withText("Select new file"), - withParent(withId(R.id.radioGroup)), - isDisplayed())); - radioButton.perform(click()); - - ViewInteraction checkBox = onView( - allOf(withId(R.id.checkAllowExistingFile), - withText("Allow selection of existing (new) file"), isDisplayed())); - checkBox.perform(click()); - - onView(withId(R.id.button_fastscroll)).perform(ViewActions.scrollTo()); - - ViewInteraction button = onView( - allOf(withId(R.id.button_fastscroll), withText("Pick With Fast Scroller"), isDisplayed())); - button.perform(click()); - - ViewInteraction recyclerView = onView( - allOf(withId(android.R.id.list), isDisplayed())); - - // Refresh view (into dir, and out again) - recyclerView.perform(actionOnItemAtPosition(1, click())); - recyclerView.perform(actionOnItemAtPosition(0, click())); - - // Click on test dir - recyclerView.perform(actionOnItemAtPosition(1, click())); - - // Enter path in filename - ViewInteraction appCompatEditText = onView( - allOf(withId(R.id.nnf_text_filename), - withParent(allOf(withId(R.id.nnf_newfile_button_container), - withParent(withId(R.id.nnf_buttons_container)))), - isDisplayed())); - // new file name - appCompatEditText.perform(replaceText("path/to/file")); - - // Click ok - ViewInteraction appCompatImageButton = onView( - allOf(withId(R.id.nnf_button_ok_newfile), - withParent(allOf(withId(R.id.nnf_newfile_button_container), - withParent(withId(R.id.nnf_buttons_container)))), - isDisplayed())); - appCompatImageButton.perform(click()); - - // Should have returned - ViewInteraction textView = onView(withId(R.id.text)); - textView.check(matches(withText("file:///storage/emulated/0/000000_nonsense-tests/path/to/file"))); - } - - @Test - public void enterFileNameWithDotDot() throws IOException { - ViewInteraction radioButton = onView( - allOf(withId(R.id.radioNewFile), withText("Select new file"), - withParent(withId(R.id.radioGroup)), - isDisplayed())); - radioButton.perform(click()); - - ViewInteraction checkBox = onView( - allOf(withId(R.id.checkAllowExistingFile), - withText("Allow selection of existing (new) file"), isDisplayed())); - checkBox.perform(click()); - - onView(withId(R.id.button_fastscroll)).perform(ViewActions.scrollTo()); - - ViewInteraction button = onView( - allOf(withId(R.id.button_fastscroll), withText("Pick With Fast Scroller"), isDisplayed())); - button.perform(click()); - - ViewInteraction recyclerView = onView( - allOf(withId(android.R.id.list), isDisplayed())); - - // Refresh view (into dir, and out again) - recyclerView.perform(actionOnItemAtPosition(1, click())); - recyclerView.perform(actionOnItemAtPosition(0, click())); - - // Click on test dir - recyclerView.perform(actionOnItemAtPosition(1, click())); - - // Enter path in filename - ViewInteraction appCompatEditText = onView( - allOf(withId(R.id.nnf_text_filename), - withParent(allOf(withId(R.id.nnf_newfile_button_container), - withParent(withId(R.id.nnf_buttons_container)))), - isDisplayed())); - // new file name - appCompatEditText.perform(replaceText("../file.txt")); - - // Click ok - ViewInteraction appCompatImageButton = onView( - allOf(withId(R.id.nnf_button_ok_newfile), - withParent(allOf(withId(R.id.nnf_newfile_button_container), - withParent(withId(R.id.nnf_buttons_container)))), - isDisplayed())); - appCompatImageButton.perform(click()); - - // Should have returned - ViewInteraction textView = onView(withId(R.id.text)); - textView.check(matches(withText("file:///storage/emulated/0/000000_nonsense-tests/../file.txt"))); - } - - @Test - public void enterFileNameWithDot() throws IOException { - ViewInteraction radioButton = onView( - allOf(withId(R.id.radioNewFile), withText("Select new file"), - withParent(withId(R.id.radioGroup)), - isDisplayed())); - radioButton.perform(click()); - - ViewInteraction checkBox = onView( - allOf(withId(R.id.checkAllowExistingFile), - withText("Allow selection of existing (new) file"), isDisplayed())); - checkBox.perform(click()); - - onView(withId(R.id.button_fastscroll)).perform(ViewActions.scrollTo()); - - ViewInteraction button = onView( - allOf(withId(R.id.button_fastscroll), withText("Pick With Fast Scroller"), isDisplayed())); - button.perform(click()); - - ViewInteraction recyclerView = onView( - allOf(withId(android.R.id.list), isDisplayed())); - - // Refresh view (into dir, and out again) - recyclerView.perform(actionOnItemAtPosition(1, click())); - recyclerView.perform(actionOnItemAtPosition(0, click())); - - // Click on test dir - recyclerView.perform(actionOnItemAtPosition(1, click())); - - // Enter path in filename - ViewInteraction appCompatEditText = onView( - allOf(withId(R.id.nnf_text_filename), - withParent(allOf(withId(R.id.nnf_newfile_button_container), - withParent(withId(R.id.nnf_buttons_container)))), - isDisplayed())); - // new file name - appCompatEditText.perform(replaceText("./file.txt")); - - // Click ok - ViewInteraction appCompatImageButton = onView( - allOf(withId(R.id.nnf_button_ok_newfile), - withParent(allOf(withId(R.id.nnf_newfile_button_container), - withParent(withId(R.id.nnf_buttons_container)))), - isDisplayed())); - appCompatImageButton.perform(click()); - - // Should have returned - ViewInteraction textView = onView(withId(R.id.text)); - textView.check(matches(withText("file:///storage/emulated/0/000000_nonsense-tests/./file.txt"))); - } - - @Test - public void enterFileNameWithRoot() throws IOException { - ViewInteraction radioButton = onView( - allOf(withId(R.id.radioNewFile), withText("Select new file"), - withParent(withId(R.id.radioGroup)), - isDisplayed())); - radioButton.perform(click()); - - ViewInteraction checkBox = onView( - allOf(withId(R.id.checkAllowExistingFile), - withText("Allow selection of existing (new) file"), isDisplayed())); - checkBox.perform(click()); - - onView(withId(R.id.button_fastscroll)).perform(ViewActions.scrollTo()); - - ViewInteraction button = onView( - allOf(withId(R.id.button_fastscroll), withText("Pick With Fast Scroller"), isDisplayed())); - button.perform(click()); - - ViewInteraction recyclerView = onView( - allOf(withId(android.R.id.list), isDisplayed())); - - // Refresh view (into dir, and out again) - recyclerView.perform(actionOnItemAtPosition(1, click())); - recyclerView.perform(actionOnItemAtPosition(0, click())); - - // Click on test dir - recyclerView.perform(actionOnItemAtPosition(1, click())); - - // Enter path in filename - ViewInteraction appCompatEditText = onView( - allOf(withId(R.id.nnf_text_filename), - withParent(allOf(withId(R.id.nnf_newfile_button_container), - withParent(withId(R.id.nnf_buttons_container)))), - isDisplayed())); - // new file name - appCompatEditText.perform(replaceText("/file.txt")); - - // Click ok - ViewInteraction appCompatImageButton = onView( - allOf(withId(R.id.nnf_button_ok_newfile), - withParent(allOf(withId(R.id.nnf_newfile_button_container), - withParent(withId(R.id.nnf_buttons_container)))), - isDisplayed())); - appCompatImageButton.perform(click()); - - // Should have returned - ViewInteraction textView = onView(withId(R.id.text)); - textView.check(matches(withText("file:///file.txt"))); - } -} diff --git a/sample/src/androidTest/java/com/nononsenseapps/filepicker/sample/FtpPicker.java b/sample/src/androidTest/java/com/nononsenseapps/filepicker/sample/FtpPicker.java deleted file mode 100644 index 8594b17..0000000 --- a/sample/src/androidTest/java/com/nononsenseapps/filepicker/sample/FtpPicker.java +++ /dev/null @@ -1,73 +0,0 @@ -package com.nononsenseapps.filepicker.sample; - - -import android.support.test.espresso.ViewInteraction; -import android.support.test.espresso.action.ViewActions; -import android.support.test.rule.ActivityTestRule; -import android.support.test.runner.AndroidJUnit4; -import android.test.suitebuilder.annotation.LargeTest; - -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.io.IOException; - -import static android.support.test.espresso.Espresso.onView; -import static android.support.test.espresso.action.ViewActions.click; -import static android.support.test.espresso.action.ViewActions.replaceText; -import static android.support.test.espresso.assertion.ViewAssertions.matches; -import static android.support.test.espresso.contrib.RecyclerViewActions.actionOnItemAtPosition; -import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; -import static android.support.test.espresso.matcher.ViewMatchers.withId; -import static android.support.test.espresso.matcher.ViewMatchers.withParent; -import static android.support.test.espresso.matcher.ViewMatchers.withText; -import static com.nononsenseapps.filepicker.sample.PermissionGranter.allowPermissionsIfNeeded; -import static org.hamcrest.Matchers.allOf; - -@LargeTest -@RunWith(AndroidJUnit4.class) -public class FtpPicker { - - @Rule - public ActivityTestRule mActivityTestRule = - new ActivityTestRule<>(NoNonsenseFilePickerTest.class); - - @Before - public void allowPermissions() { - allowPermissionsIfNeeded(mActivityTestRule.getActivity()); - } - - @Test - public void selectDir() throws IOException { - ViewInteraction radioButton = onView( - allOf(withId(R.id.radioDir), withText("Select directory"), - withParent(withId(R.id.radioGroup)), - isDisplayed())); - radioButton.perform(click()); - - onView(withId(R.id.button_ftp)).perform(ViewActions.scrollTo()); - - ViewInteraction button = onView( - allOf(withId(R.id.button_ftp), isDisplayed())); - button.perform(click()); - - ViewInteraction recyclerView = onView( - allOf(withId(android.R.id.list), isDisplayed())); - - // press pub - recyclerView.perform(actionOnItemAtPosition(1, click())); - - ViewInteraction okButton = onView( - allOf(withId(R.id.nnf_button_ok), - withParent(allOf(withId(R.id.nnf_button_container), - withParent(withId(R.id.nnf_buttons_container)))), - isDisplayed())); - // Click ok - okButton.perform(click()); - - ViewInteraction textView = onView(withId(R.id.text)); - textView.check(matches(withText("ftp://anonymous:anonymous@debian.simnet.is:21/pub"))); - } -} diff --git a/sample/src/androidTest/java/com/nononsenseapps/filepicker/sample/PermissionGranter.java b/sample/src/androidTest/java/com/nononsenseapps/filepicker/sample/PermissionGranter.java deleted file mode 100644 index ef634ec..0000000 --- a/sample/src/androidTest/java/com/nononsenseapps/filepicker/sample/PermissionGranter.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.nononsenseapps.filepicker.sample; - -import android.Manifest; -import android.app.Activity; -import android.content.pm.PackageManager; -import android.os.Build; -import android.support.test.uiautomator.UiDevice; -import android.support.test.uiautomator.UiObject; -import android.support.test.uiautomator.UiObjectNotFoundException; -import android.support.test.uiautomator.UiSelector; -import android.support.v4.content.ContextCompat; - -import static android.support.test.InstrumentationRegistry.getInstrumentation; - -public class PermissionGranter { - - private static final int PERMISSIONS_DIALOG_DELAY = 3000; - private static final int GRANT_BUTTON_INDEX = 1; - - public static void allowPermissionsIfNeeded(Activity activity) { - allowPermissionsIfNeeded(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE); - } - - public static void allowPermissionsIfNeeded(Activity activity, String permissionNeeded) { - try { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !hasNeededPermission(activity, permissionNeeded)) { - sleep(PERMISSIONS_DIALOG_DELAY); - UiDevice device = UiDevice.getInstance(getInstrumentation()); - UiObject allowPermissions = device.findObject(new UiSelector().clickable(true).index(GRANT_BUTTON_INDEX)); - if (allowPermissions.exists()) { - allowPermissions.click(); - } - } - } catch (UiObjectNotFoundException e) { - System.out.println("There is no permissions dialog to interact with"); - } - } - - private static boolean hasNeededPermission(Activity activity, String permissionNeeded) { - int permissionStatus = ContextCompat.checkSelfPermission(activity, permissionNeeded); - return permissionStatus == PackageManager.PERMISSION_GRANTED; - } - - private static void sleep(long millis) { - try { - Thread.sleep(millis); - } catch (InterruptedException e) { - throw new RuntimeException("Cannot execute Thread.sleep()"); - } - } -} \ No newline at end of file diff --git a/sample/src/androidTest/java/com/nononsenseapps/filepicker/sample/SelectNewFile.java b/sample/src/androidTest/java/com/nononsenseapps/filepicker/sample/SelectNewFile.java deleted file mode 100644 index 5aac368..0000000 --- a/sample/src/androidTest/java/com/nononsenseapps/filepicker/sample/SelectNewFile.java +++ /dev/null @@ -1,406 +0,0 @@ -package com.nononsenseapps.filepicker.sample; - - -import android.support.test.espresso.ViewInteraction; -import android.support.test.rule.ActivityTestRule; -import android.support.test.runner.AndroidJUnit4; -import android.test.suitebuilder.annotation.LargeTest; - -import static android.support.test.espresso.Espresso.onView; -import static android.support.test.espresso.Espresso.pressBack; -import static android.support.test.espresso.contrib.RecyclerViewActions.actionOnItemAtPosition; -import static android.support.test.espresso.action.ViewActions.*; -import static android.support.test.espresso.assertion.ViewAssertions.*; -import static android.support.test.espresso.matcher.ViewMatchers.*; - -import com.nononsenseapps.filepicker.sample.R; - -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.io.IOException; - -import static com.nononsenseapps.filepicker.sample.PermissionGranter.allowPermissionsIfNeeded; -import static org.hamcrest.Matchers.allOf; -import static org.hamcrest.Matchers.is; - -@LargeTest -@RunWith(AndroidJUnit4.class) -public class SelectNewFile { - - @Rule - public ActivityTestRule mActivityTestRule = - new ActivityTestRule<>(NoNonsenseFilePickerTest.class); - - @Before - public void allowPermissions() { - allowPermissionsIfNeeded(mActivityTestRule.getActivity()); - } - - @Test - public void selectNewFile() throws IOException { - ViewInteraction radioButton = onView( - allOf(withId(R.id.radioNewFile), withText("Select new file"), - withParent(withId(R.id.radioGroup)), - isDisplayed())); - radioButton.perform(click()); - - ViewInteraction checkBox = onView( - allOf(withId(R.id.checkAllowExistingFile), withText("Allow selection of existing (new) file"), isDisplayed())); - checkBox.perform(click()); - - ViewInteraction button = onView( - allOf(withId(R.id.button_sd), withText("Pick SD-card"), isDisplayed())); - button.perform(click()); - - ViewInteraction recyclerView = onView( - allOf(withId(android.R.id.list), isDisplayed())); - - // Refresh view (into dir, and out again) - recyclerView.perform(actionOnItemAtPosition(1, click())); - recyclerView.perform(actionOnItemAtPosition(0, click())); - - // Click on test dir - recyclerView.perform(actionOnItemAtPosition(1, click())); - // sub dir - recyclerView.perform(actionOnItemAtPosition(3, click())); - - ViewInteraction appCompatEditText = onView( - allOf(withId(R.id.nnf_text_filename), - withParent(allOf(withId(R.id.nnf_newfile_button_container), - withParent(withId(R.id.nnf_buttons_container)))), - isDisplayed())); - // new file name - appCompatEditText.perform(replaceText("testfile")); - - ViewInteraction appCompatImageButton = onView( - allOf(withId(R.id.nnf_button_ok_newfile), - withParent(allOf(withId(R.id.nnf_newfile_button_container), - withParent(withId(R.id.nnf_buttons_container)))), - isDisplayed())); - // Click ok - appCompatImageButton.perform(click()); - - ViewInteraction textView = onView(withId(R.id.text)); - textView.check(matches(withText("file:///storage/emulated/0/000000_nonsense-tests/C-dir/testfile"))); - } - - @Test - public void withSingleClick() throws IOException { - ViewInteraction radioButton = onView( - allOf(withId(R.id.radioNewFile), - withParent(withId(R.id.radioGroup)), - isDisplayed())); - radioButton.perform(click()); - - ViewInteraction checkBox = onView( - allOf(withId(R.id.checkSingleClick), isDisplayed())); - checkBox.perform(click()); - - ViewInteraction button = onView( - allOf(withId(R.id.button_sd), isDisplayed())); - button.perform(click()); - - ViewInteraction recyclerView = onView( - allOf(withId(android.R.id.list), isDisplayed())); - - // Refresh view (into dir, and out again) - recyclerView.perform(actionOnItemAtPosition(1, click())); - recyclerView.perform(actionOnItemAtPosition(0, click())); - - // Navigate to file - recyclerView.perform(actionOnItemAtPosition(1, click())); - recyclerView.perform(actionOnItemAtPosition(2, click())); - // Click file - recyclerView.perform(actionOnItemAtPosition(4, click())); - - // Should have returned - ViewInteraction textView = onView(withId(R.id.text)); - textView.check(matches(withText("file:///storage/emulated/0/000000_nonsense-tests/B-dir/file-3.txt"))); - } - - @Test - public void clickTwiceShouldNotClearFilename() throws IOException { - ViewInteraction radioButton = onView( - allOf(withId(R.id.radioNewFile), withText("Select new file"), - withParent(withId(R.id.radioGroup)), - isDisplayed())); - radioButton.perform(click()); - - ViewInteraction button = onView( - allOf(withId(R.id.button_sd), withText("Pick SD-card"), isDisplayed())); - button.perform(click()); - - ViewInteraction recyclerView = onView( - allOf(withId(android.R.id.list), isDisplayed())); - - // Refresh view (into dir, and out again) - recyclerView.perform(actionOnItemAtPosition(1, click())); - recyclerView.perform(actionOnItemAtPosition(0, click())); - - // Navigate to file - recyclerView.perform(actionOnItemAtPosition(1, click())); - - recyclerView.perform(actionOnItemAtPosition(2, click())); - - // Click on file once - recyclerView.perform(actionOnItemAtPosition(4, click())); - - // Filename should be entered in field - ViewInteraction editText = onView(withId(R.id.nnf_text_filename)); - editText.check(matches(withText("file-3.txt"))); - - // Click twice - recyclerView.perform(actionOnItemAtPosition(4, click())); - - // Filename should not change - editText.check(matches(withText("file-3.txt"))); - } - - @Test - public void enterFileNameWithPathWhichExists() throws IOException { - ViewInteraction radioButton = onView( - allOf(withId(R.id.radioNewFile), withText("Select new file"), - withParent(withId(R.id.radioGroup)), - isDisplayed())); - radioButton.perform(click()); - - ViewInteraction checkBox = onView( - allOf(withId(R.id.checkAllowExistingFile), - withText("Allow selection of existing (new) file"), isDisplayed())); - checkBox.perform(click()); - - ViewInteraction button = onView( - allOf(withId(R.id.button_sd), withText("Pick SD-card"), isDisplayed())); - button.perform(click()); - - ViewInteraction recyclerView = onView( - allOf(withId(android.R.id.list), isDisplayed())); - - // Refresh view (into dir, and out again) - recyclerView.perform(actionOnItemAtPosition(1, click())); - recyclerView.perform(actionOnItemAtPosition(0, click())); - - // Click on test dir - recyclerView.perform(actionOnItemAtPosition(1, click())); - - // Enter path in filename - ViewInteraction appCompatEditText = onView( - allOf(withId(R.id.nnf_text_filename), - withParent(allOf(withId(R.id.nnf_newfile_button_container), - withParent(withId(R.id.nnf_buttons_container)))), - isDisplayed())); - // new file name - appCompatEditText.perform(replaceText("B-dir/file-3.txt")); - - // Click ok - ViewInteraction appCompatImageButton = onView( - allOf(withId(R.id.nnf_button_ok_newfile), - withParent(allOf(withId(R.id.nnf_newfile_button_container), - withParent(withId(R.id.nnf_buttons_container)))), - isDisplayed())); - appCompatImageButton.perform(click()); - - // Should have returned - ViewInteraction textView = onView(withId(R.id.text)); - textView.check(matches(withText("file:///storage/emulated/0/000000_nonsense-tests/B-dir/file-3.txt"))); - } - - @Test - public void enterFileNameWithPathWhichDoesNotExist() throws IOException { - ViewInteraction radioButton = onView( - allOf(withId(R.id.radioNewFile), withText("Select new file"), - withParent(withId(R.id.radioGroup)), - isDisplayed())); - radioButton.perform(click()); - - ViewInteraction checkBox = onView( - allOf(withId(R.id.checkAllowExistingFile), - withText("Allow selection of existing (new) file"), isDisplayed())); - checkBox.perform(click()); - - ViewInteraction button = onView( - allOf(withId(R.id.button_sd), withText("Pick SD-card"), isDisplayed())); - button.perform(click()); - - ViewInteraction recyclerView = onView( - allOf(withId(android.R.id.list), isDisplayed())); - - // Refresh view (into dir, and out again) - recyclerView.perform(actionOnItemAtPosition(1, click())); - recyclerView.perform(actionOnItemAtPosition(0, click())); - - // Click on test dir - recyclerView.perform(actionOnItemAtPosition(1, click())); - - // Enter path in filename - ViewInteraction appCompatEditText = onView( - allOf(withId(R.id.nnf_text_filename), - withParent(allOf(withId(R.id.nnf_newfile_button_container), - withParent(withId(R.id.nnf_buttons_container)))), - isDisplayed())); - // new file name - appCompatEditText.perform(replaceText("path/to/file")); - - // Click ok - ViewInteraction appCompatImageButton = onView( - allOf(withId(R.id.nnf_button_ok_newfile), - withParent(allOf(withId(R.id.nnf_newfile_button_container), - withParent(withId(R.id.nnf_buttons_container)))), - isDisplayed())); - appCompatImageButton.perform(click()); - - // Should have returned - ViewInteraction textView = onView(withId(R.id.text)); - textView.check(matches(withText("file:///storage/emulated/0/000000_nonsense-tests/path/to/file"))); - } - - @Test - public void enterFileNameWithDotDot() throws IOException { - ViewInteraction radioButton = onView( - allOf(withId(R.id.radioNewFile), withText("Select new file"), - withParent(withId(R.id.radioGroup)), - isDisplayed())); - radioButton.perform(click()); - - ViewInteraction checkBox = onView( - allOf(withId(R.id.checkAllowExistingFile), - withText("Allow selection of existing (new) file"), isDisplayed())); - checkBox.perform(click()); - - ViewInteraction button = onView( - allOf(withId(R.id.button_sd), withText("Pick SD-card"), isDisplayed())); - button.perform(click()); - - ViewInteraction recyclerView = onView( - allOf(withId(android.R.id.list), isDisplayed())); - - // Refresh view (into dir, and out again) - recyclerView.perform(actionOnItemAtPosition(1, click())); - recyclerView.perform(actionOnItemAtPosition(0, click())); - - // Click on test dir - recyclerView.perform(actionOnItemAtPosition(1, click())); - - // Enter path in filename - ViewInteraction appCompatEditText = onView( - allOf(withId(R.id.nnf_text_filename), - withParent(allOf(withId(R.id.nnf_newfile_button_container), - withParent(withId(R.id.nnf_buttons_container)))), - isDisplayed())); - // new file name - appCompatEditText.perform(replaceText("../file.txt")); - - // Click ok - ViewInteraction appCompatImageButton = onView( - allOf(withId(R.id.nnf_button_ok_newfile), - withParent(allOf(withId(R.id.nnf_newfile_button_container), - withParent(withId(R.id.nnf_buttons_container)))), - isDisplayed())); - appCompatImageButton.perform(click()); - - // Should have returned - ViewInteraction textView = onView(withId(R.id.text)); - textView.check(matches(withText("file:///storage/emulated/0/000000_nonsense-tests/../file.txt"))); - } - - @Test - public void enterFileNameWithDot() throws IOException { - ViewInteraction radioButton = onView( - allOf(withId(R.id.radioNewFile), withText("Select new file"), - withParent(withId(R.id.radioGroup)), - isDisplayed())); - radioButton.perform(click()); - - ViewInteraction checkBox = onView( - allOf(withId(R.id.checkAllowExistingFile), - withText("Allow selection of existing (new) file"), isDisplayed())); - checkBox.perform(click()); - - ViewInteraction button = onView( - allOf(withId(R.id.button_sd), withText("Pick SD-card"), isDisplayed())); - button.perform(click()); - - ViewInteraction recyclerView = onView( - allOf(withId(android.R.id.list), isDisplayed())); - - // Refresh view (into dir, and out again) - recyclerView.perform(actionOnItemAtPosition(1, click())); - recyclerView.perform(actionOnItemAtPosition(0, click())); - - // Click on test dir - recyclerView.perform(actionOnItemAtPosition(1, click())); - - // Enter path in filename - ViewInteraction appCompatEditText = onView( - allOf(withId(R.id.nnf_text_filename), - withParent(allOf(withId(R.id.nnf_newfile_button_container), - withParent(withId(R.id.nnf_buttons_container)))), - isDisplayed())); - // new file name - appCompatEditText.perform(replaceText("./file.txt")); - - // Click ok - ViewInteraction appCompatImageButton = onView( - allOf(withId(R.id.nnf_button_ok_newfile), - withParent(allOf(withId(R.id.nnf_newfile_button_container), - withParent(withId(R.id.nnf_buttons_container)))), - isDisplayed())); - appCompatImageButton.perform(click()); - - // Should have returned - ViewInteraction textView = onView(withId(R.id.text)); - textView.check(matches(withText("file:///storage/emulated/0/000000_nonsense-tests/./file.txt"))); - } - - @Test - public void enterFileNameWithRoot() throws IOException { - ViewInteraction radioButton = onView( - allOf(withId(R.id.radioNewFile), withText("Select new file"), - withParent(withId(R.id.radioGroup)), - isDisplayed())); - radioButton.perform(click()); - - ViewInteraction checkBox = onView( - allOf(withId(R.id.checkAllowExistingFile), - withText("Allow selection of existing (new) file"), isDisplayed())); - checkBox.perform(click()); - - ViewInteraction button = onView( - allOf(withId(R.id.button_sd), withText("Pick SD-card"), isDisplayed())); - button.perform(click()); - - ViewInteraction recyclerView = onView( - allOf(withId(android.R.id.list), isDisplayed())); - - // Refresh view (into dir, and out again) - recyclerView.perform(actionOnItemAtPosition(1, click())); - recyclerView.perform(actionOnItemAtPosition(0, click())); - - // Click on test dir - recyclerView.perform(actionOnItemAtPosition(1, click())); - - // Enter path in filename - ViewInteraction appCompatEditText = onView( - allOf(withId(R.id.nnf_text_filename), - withParent(allOf(withId(R.id.nnf_newfile_button_container), - withParent(withId(R.id.nnf_buttons_container)))), - isDisplayed())); - // new file name - appCompatEditText.perform(replaceText("/file.txt")); - - // Click ok - ViewInteraction appCompatImageButton = onView( - allOf(withId(R.id.nnf_button_ok_newfile), - withParent(allOf(withId(R.id.nnf_newfile_button_container), - withParent(withId(R.id.nnf_buttons_container)))), - isDisplayed())); - appCompatImageButton.perform(click()); - - // Should have returned - ViewInteraction textView = onView(withId(R.id.text)); - textView.check(matches(withText("file:///file.txt"))); - } -} diff --git a/sample/src/androidTest/java/com/nononsenseapps/filepicker/sample/SelectNewFileStartPathIsFile.java b/sample/src/androidTest/java/com/nononsenseapps/filepicker/sample/SelectNewFileStartPathIsFile.java deleted file mode 100644 index e276af0..0000000 --- a/sample/src/androidTest/java/com/nononsenseapps/filepicker/sample/SelectNewFileStartPathIsFile.java +++ /dev/null @@ -1,90 +0,0 @@ -package com.nononsenseapps.filepicker.sample; - -import android.content.Context; -import android.content.Intent; -import android.os.Environment; -import android.support.test.InstrumentationRegistry; -import android.support.test.espresso.ViewInteraction; -import android.support.test.rule.ActivityTestRule; -import android.support.test.runner.AndroidJUnit4; -import android.test.suitebuilder.annotation.LargeTest; - -import com.nononsenseapps.filepicker.AbstractFilePickerActivity; - -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.io.File; -import java.io.IOException; - -import static android.support.test.espresso.Espresso.onView; -import static android.support.test.espresso.action.ViewActions.click; -import static android.support.test.espresso.assertion.ViewAssertions.matches; -import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; -import static android.support.test.espresso.matcher.ViewMatchers.withId; -import static android.support.test.espresso.matcher.ViewMatchers.withParent; -import static android.support.test.espresso.matcher.ViewMatchers.withText; -import static com.nononsenseapps.filepicker.sample.PermissionGranter.allowPermissionsIfNeeded; -import static org.hamcrest.Matchers.allOf; - -/** - * In this class, the activity is launched using an intent pointing to a file. - */ -@LargeTest -@RunWith(AndroidJUnit4.class) -public class SelectNewFileStartPathIsFile { - - @Rule - public ActivityTestRule mActivityTestRule = - new ActivityTestRule(NoNonsenseFilePickerTest.class) { - @Override - protected Intent getActivityIntent() { - Context targetContext = InstrumentationRegistry.getInstrumentation() - .getTargetContext(); - Intent result = new Intent(targetContext, NoNonsenseFilePickerTest.class); - String path = new File(Environment.getExternalStorageDirectory().getAbsoluteFile(), - "000000_nonsense-tests/A-dir/file-3.txt").getAbsolutePath(); - result.putExtra(AbstractFilePickerActivity.EXTRA_START_PATH, path); - return result; - } - }; - - @Before - public void allowPermissions() { - allowPermissionsIfNeeded(mActivityTestRule.getActivity()); - } - - @Test - public void selectNewFileWithStartPath() throws IOException { - ViewInteraction radioButton = onView( - allOf(withId(R.id.radioNewFile), withText("Select new file"), - withParent(withId(R.id.radioGroup)), - isDisplayed())); - radioButton.perform(click()); - - ViewInteraction button = onView( - allOf(withId(R.id.button_sd), withText("Pick SD-card"), isDisplayed())); - button.perform(click()); - - ViewInteraction appCompatEditText = onView( - allOf(withId(R.id.nnf_text_filename), - withParent(allOf(withId(R.id.nnf_newfile_button_container), - withParent(withId(R.id.nnf_buttons_container)))), - isDisplayed())); - - appCompatEditText.check(matches(withText("file-3.txt"))); - - ViewInteraction appCompatImageButton = onView( - allOf(withId(R.id.nnf_button_ok_newfile), - withParent(allOf(withId(R.id.nnf_newfile_button_container), - withParent(withId(R.id.nnf_buttons_container)))), - isDisplayed())); - // Click ok - appCompatImageButton.perform(click()); - - ViewInteraction textView = onView(withId(R.id.text)); - textView.check(matches(withText("file:///storage/emulated/0/000000_nonsense-tests/A-dir/file-3.txt"))); - } -} diff --git a/sample/src/main/AndroidManifest.xml b/sample/src/main/AndroidManifest.xml deleted file mode 100644 index 3125573..0000000 --- a/sample/src/main/AndroidManifest.xml +++ /dev/null @@ -1,156 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/sample/src/main/java/com/nononsenseapps/filepicker/sample/FilePickerActivity2.java b/sample/src/main/java/com/nononsenseapps/filepicker/sample/FilePickerActivity2.java deleted file mode 100644 index 95609b8..0000000 --- a/sample/src/main/java/com/nononsenseapps/filepicker/sample/FilePickerActivity2.java +++ /dev/null @@ -1,17 +0,0 @@ -/* - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -package com.nononsenseapps.filepicker.sample; - - -import com.nononsenseapps.filepicker.FilePickerActivity; - -/** - * This is a copy of the included activity for the sole purpose - * of being to show you a second example theme - */ -public class FilePickerActivity2 extends FilePickerActivity { -} diff --git a/sample/src/main/java/com/nononsenseapps/filepicker/sample/NoNonsenseFilePicker.java b/sample/src/main/java/com/nononsenseapps/filepicker/sample/NoNonsenseFilePicker.java deleted file mode 100644 index ea60f37..0000000 --- a/sample/src/main/java/com/nononsenseapps/filepicker/sample/NoNonsenseFilePicker.java +++ /dev/null @@ -1,278 +0,0 @@ -/* - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -package com.nononsenseapps.filepicker.sample; - -import android.annotation.TargetApi; -import android.app.Activity; -import android.content.ClipData; -import android.content.Intent; -import android.os.Build; -import android.os.Bundle; -import android.util.Log; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.widget.CheckBox; -import android.widget.RadioGroup; -import android.widget.TextView; -import android.widget.Toast; - -import com.dropbox.client2.DropboxAPI; -import com.dropbox.client2.android.AndroidAuthSession; -import com.nononsenseapps.filepicker.AbstractFilePickerActivity; -import com.nononsenseapps.filepicker.AbstractFilePickerFragment; -import com.nononsenseapps.filepicker.FilePickerActivity; -import com.nononsenseapps.filepicker.sample.dropbox.DropboxFilePickerActivity; -import com.nononsenseapps.filepicker.sample.dropbox.DropboxFilePickerActivity2; -import com.nononsenseapps.filepicker.sample.dropbox.DropboxSyncHelper; -import com.nononsenseapps.filepicker.sample.fastscroller.FastScrollerFilePickerActivity; -import com.nononsenseapps.filepicker.sample.fastscroller.FastScrollerFilePickerActivity2; -import com.nononsenseapps.filepicker.sample.ftp.FtpPickerActivity; -import com.nononsenseapps.filepicker.sample.ftp.FtpPickerActivity2; -import com.nononsenseapps.filepicker.sample.multimedia.MultimediaPickerActivity; -import com.nononsenseapps.filepicker.sample.multimedia.MultimediaPickerActivity2; -import com.nononsenseapps.filepicker.sample.root.SUPickerActivity; -import com.nononsenseapps.filepicker.sample.root.SUPickerActivity2; - -import java.util.ArrayList; - - -public class NoNonsenseFilePicker extends Activity { - - static final int CODE_SD = 0; - static final int CODE_DB = 1; - static final int CODE_FTP = 2; - TextView textView; - DropboxAPI mDBApi = null; - CheckBox checkAllowCreateDir; - CheckBox checkAllowMultiple; - CheckBox checkSingleClick; - CheckBox checkLightTheme; - RadioGroup radioGroup; - CheckBox checkAllowExistingFile; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_no_nonsense_file_picker); - - checkAllowCreateDir = - (CheckBox) findViewById(R.id.checkAllowCreateDir); - checkAllowMultiple = - (CheckBox) findViewById(R.id.checkAllowMultiple); - checkAllowExistingFile = - (CheckBox) findViewById(R.id.checkAllowExistingFile); - checkSingleClick = - (CheckBox) findViewById(R.id.checkSingleClick); - checkLightTheme = - (CheckBox) findViewById(R.id.checkLightTheme); - radioGroup = - (RadioGroup) findViewById(R.id.radioGroup); - textView = (TextView) findViewById(R.id.text); - - findViewById(R.id.button_sd) - .setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(final View v) { - if (checkLightTheme.isChecked()) { - startActivity(CODE_SD, FilePickerActivity2.class); - } else { - startActivity(CODE_SD, FilePickerActivity.class); - } - } - }); - - findViewById(R.id.button_image) - .setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(final View v) { - if (checkLightTheme.isChecked()) { - startActivity(CODE_SD, MultimediaPickerActivity2.class); - } else { - startActivity(CODE_SD, MultimediaPickerActivity.class); - } - } - }); - - findViewById(R.id.button_ftp) - .setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(final View v) { - if (checkLightTheme.isChecked()) { - startActivity(CODE_FTP, FtpPickerActivity2.class); - } else { - startActivity(CODE_FTP, FtpPickerActivity.class); - } - } - }); - - findViewById(R.id.button_dropbox) - .setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(final View v) { - - // First we must authorize the user - if (mDBApi == null) { - mDBApi = DropboxSyncHelper - .getDBApi(NoNonsenseFilePicker.this); - } - - // If not authorized, then ask user for login/permission - if (!mDBApi.getSession().isLinked()) { - mDBApi.getSession().startOAuth2Authentication( - NoNonsenseFilePicker.this); - } else { // User is authorized, open file picker - Intent i; - if (checkLightTheme.isChecked()) { - startActivity(CODE_DB, DropboxFilePickerActivity2.class); - } else { - startActivity(CODE_DB, DropboxFilePickerActivity.class); - } - } - } - }); - - findViewById(R.id.button_root).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - if (checkLightTheme.isChecked()) { - startActivity(CODE_SD, SUPickerActivity.class); - } else { - startActivity(CODE_SD, SUPickerActivity2.class); - } - } - }); - - findViewById(R.id.button_fastscroll).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - if (checkLightTheme.isChecked()) { - startActivity(CODE_SD, FastScrollerFilePickerActivity.class); - } else { - startActivity(CODE_SD, FastScrollerFilePickerActivity2.class); - } - } - }); - } - - protected void startActivity(final int code, final Class klass) { - final Intent i = new Intent(this, klass); - - i.setAction(Intent.ACTION_GET_CONTENT); - - i.putExtra(SUPickerActivity.EXTRA_ALLOW_MULTIPLE, - checkAllowMultiple.isChecked()); - i.putExtra(FilePickerActivity.EXTRA_SINGLE_CLICK, - checkSingleClick.isChecked()); - i.putExtra(SUPickerActivity.EXTRA_ALLOW_CREATE_DIR, - checkAllowCreateDir.isChecked()); - i.putExtra(FilePickerActivity.EXTRA_ALLOW_EXISTING_FILE, - checkAllowExistingFile.isChecked()); - - // What mode is selected - final int mode; - switch (radioGroup.getCheckedRadioButtonId()) { - case R.id.radioDir: - mode = AbstractFilePickerFragment.MODE_DIR; - break; - case R.id.radioFilesAndDirs: - mode = AbstractFilePickerFragment.MODE_FILE_AND_DIR; - break; - case R.id.radioNewFile: - mode = AbstractFilePickerFragment.MODE_NEW_FILE; - break; - case R.id.radioFile: - default: - mode = AbstractFilePickerFragment.MODE_FILE; - break; - } - - i.putExtra(FilePickerActivity.EXTRA_MODE, mode); - - // This line is solely so that test classes can override intents given through UI - i.putExtras(getIntent()); - - startActivityForResult(i, code); - } - - /** - * This is entirely for Dropbox's benefit - */ - protected void onResume() { - super.onResume(); - - if (mDBApi != null && mDBApi.getSession().authenticationSuccessful()) { - try { - // Required to complete auth, sets the access token on the session - mDBApi.getSession().finishAuthentication(); - - String accessToken = mDBApi.getSession().getOAuth2AccessToken(); - DropboxSyncHelper.saveToken(this, accessToken); - } catch (IllegalStateException e) { - Log.i("DbAuthLog", "Error authenticating", e); - } - } - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - - // Inflate the menu; this adds items to the action bar if it is present. - getMenuInflater().inflate(R.menu.no_nonsense_file_picker, menu); - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - // Handle action bar item clicks here. The action bar will - // automatically handle clicks on the Home/Up button, so long - // as you specify a parent activity in AndroidManifest.xml. - int id = item.getItemId(); - return id == R.id.action_settings || super.onOptionsItemSelected(item); - } - - @TargetApi(Build.VERSION_CODES.JELLY_BEAN) - @Override - protected void onActivityResult(int requestCode, int resultCode, - Intent data) { - if ((CODE_SD == requestCode || CODE_DB == requestCode || CODE_FTP == requestCode) && - resultCode == Activity.RESULT_OK) { - if (data.getBooleanExtra(FilePickerActivity.EXTRA_ALLOW_MULTIPLE, - false)) { - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { - ClipData clip = data.getClipData(); - StringBuilder sb = new StringBuilder(); - - if (clip != null) { - for (int i = 0; i < clip.getItemCount(); i++) { - sb.append(clip.getItemAt(i).getUri().toString()); - sb.append("\n"); - } - } - - textView.setText(sb.toString()); - } else { - ArrayList paths = data.getStringArrayListExtra( - FilePickerActivity.EXTRA_PATHS); - StringBuilder sb = new StringBuilder(); - - if (paths != null) { - for (String path : paths) { - sb.append(path); - sb.append("\n"); - } - } - textView.setText(sb.toString()); - } - } else { - textView.setText(data.getData().toString()); - } - } - } - -} diff --git a/sample/src/main/java/com/nononsenseapps/filepicker/sample/NoNonsenseFilePickerTest.java b/sample/src/main/java/com/nononsenseapps/filepicker/sample/NoNonsenseFilePickerTest.java deleted file mode 100644 index e5883ee..0000000 --- a/sample/src/main/java/com/nononsenseapps/filepicker/sample/NoNonsenseFilePickerTest.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -package com.nononsenseapps.filepicker.sample; - -import android.Manifest; -import android.annotation.TargetApi; -import android.app.Activity; -import android.content.ClipData; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.os.Build; -import android.os.Bundle; -import android.os.Environment; -import android.support.annotation.NonNull; -import android.support.v4.content.ContextCompat; -import android.util.Log; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.widget.CheckBox; -import android.widget.RadioGroup; -import android.widget.TextView; -import android.widget.Toast; - -import com.dropbox.client2.DropboxAPI; -import com.dropbox.client2.android.AndroidAuthSession; -import com.nononsenseapps.filepicker.AbstractFilePickerFragment; -import com.nononsenseapps.filepicker.FilePickerActivity; -import com.nononsenseapps.filepicker.sample.dropbox.DropboxFilePickerActivity; -import com.nononsenseapps.filepicker.sample.dropbox.DropboxFilePickerActivity2; -import com.nononsenseapps.filepicker.sample.dropbox.DropboxSyncHelper; -import com.nononsenseapps.filepicker.sample.fastscroller.FastScrollerFilePickerActivity; -import com.nononsenseapps.filepicker.sample.fastscroller.FastScrollerFilePickerActivity2; -import com.nononsenseapps.filepicker.sample.ftp.FtpPickerActivity; -import com.nononsenseapps.filepicker.sample.ftp.FtpPickerActivity2; -import com.nononsenseapps.filepicker.sample.multimedia.MultimediaPickerActivity; -import com.nononsenseapps.filepicker.sample.multimedia.MultimediaPickerActivity2; -import com.nononsenseapps.filepicker.sample.root.SUPickerActivity; -import com.nononsenseapps.filepicker.sample.root.SUPickerActivity2; - -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import static org.junit.Assert.assertTrue; - - -public class NoNonsenseFilePickerTest extends NoNonsenseFilePicker { - private static final int PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE = 0; - - @Override - protected void onResume() { - super.onResume(); - - // Request permission - if (hasPermission()) { - try { - createTestData(); - } catch (IOException e) { - throw new RuntimeException(e); - } - } else { - requestPermission(); - } - } - - void createTestData() throws IOException { - File sdRoot = Environment.getExternalStorageDirectory().getAbsoluteFile(); - - File testRoot = new File(sdRoot, "000000_nonsense-tests"); - - testRoot.mkdir(); - assertTrue("Failed to create directory", testRoot.isDirectory()); - - List subdirs = Arrays.asList(new File(testRoot, "A-dir"), - new File(testRoot, "B-dir"), - new File(testRoot, "C-dir")); - - - for (File subdir : subdirs) { - subdir.mkdir(); - assertTrue("Failed to create sub directory", subdir.isDirectory()); - - for (int sf = 0; sf < 10; sf++) { - File subfile = new File(subdir, "file-" + sf + ".txt"); - - subfile.createNewFile(); - - assertTrue("Failed to create file", subfile.isFile()); - } - } - } - - protected boolean hasPermission() { - return PackageManager.PERMISSION_GRANTED == - ContextCompat.checkSelfPermission(this, - Manifest.permission.WRITE_EXTERNAL_STORAGE); - } - - protected void requestPermission() { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, - PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE); - } - } - - @Override - public void onRequestPermissionsResult(int requestCode, - @NonNull String[] permissions, - @NonNull int[] grantResults) { - // If arrays are empty, then process was cancelled - if (permissions.length > 0) { - if (PackageManager.PERMISSION_GRANTED == grantResults[0]) { - try { - createTestData(); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - } - } -} diff --git a/sample/src/main/java/com/nononsenseapps/filepicker/sample/dropbox/DropboxFilePickerActivity.java b/sample/src/main/java/com/nononsenseapps/filepicker/sample/dropbox/DropboxFilePickerActivity.java deleted file mode 100644 index ff9d8b8..0000000 --- a/sample/src/main/java/com/nononsenseapps/filepicker/sample/dropbox/DropboxFilePickerActivity.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -package com.nononsenseapps.filepicker.sample.dropbox; - -import android.os.Bundle; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; - -import com.dropbox.client2.DropboxAPI; -import com.dropbox.client2.android.AndroidAuthSession; -import com.nononsenseapps.filepicker.AbstractFilePickerActivity; -import com.nononsenseapps.filepicker.AbstractFilePickerFragment; - - -public class DropboxFilePickerActivity - extends AbstractFilePickerActivity { - - // In the class declaration section: - private DropboxAPI mDBApi; - - @Override - public void onCreate(Bundle b) { - mDBApi = DropboxSyncHelper.getDBApi(this); - if (!mDBApi.getSession().isLinked()) { - // No valid authentication - finish(); - } - - super.onCreate(b); - } - - @Override - protected AbstractFilePickerFragment getFragment( - @Nullable final String startPath, final int mode, final boolean allowMultiple, - final boolean allowCreateDir, final boolean allowExistingFile, - final boolean singleClick) { - if (mDBApi == null || !mDBApi.getSession().isLinked()) { - // No valid authentication - finish(); - return null; - } - - DropboxFilePickerFragment fragment = - new DropboxFilePickerFragment(mDBApi); - fragment.setArgs(startPath, mode, allowMultiple, allowCreateDir, - allowExistingFile, singleClick); - return fragment; - } -} diff --git a/sample/src/main/java/com/nononsenseapps/filepicker/sample/dropbox/DropboxFilePickerActivity2.java b/sample/src/main/java/com/nononsenseapps/filepicker/sample/dropbox/DropboxFilePickerActivity2.java deleted file mode 100644 index 21803df..0000000 --- a/sample/src/main/java/com/nononsenseapps/filepicker/sample/dropbox/DropboxFilePickerActivity2.java +++ /dev/null @@ -1,14 +0,0 @@ -/* - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -package com.nononsenseapps.filepicker.sample.dropbox; - -/** - * This is a copy of the included activity for the sole purpose - * of being to show you a second example theme - */ -public class DropboxFilePickerActivity2 extends DropboxFilePickerActivity { -} diff --git a/sample/src/main/java/com/nononsenseapps/filepicker/sample/dropbox/DropboxFilePickerFragment.java b/sample/src/main/java/com/nononsenseapps/filepicker/sample/dropbox/DropboxFilePickerFragment.java deleted file mode 100644 index de473a7..0000000 --- a/sample/src/main/java/com/nononsenseapps/filepicker/sample/dropbox/DropboxFilePickerFragment.java +++ /dev/null @@ -1,307 +0,0 @@ -/* - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -package com.nononsenseapps.filepicker.sample.dropbox; - -import android.annotation.SuppressLint; -import android.net.Uri; -import android.os.AsyncTask; -import android.os.Bundle; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; -import android.support.v4.content.AsyncTaskLoader; -import android.support.v4.content.Loader; -import android.support.v7.util.SortedList; -import android.support.v7.widget.LinearLayoutManager; -import android.support.v7.widget.RecyclerView; -import android.support.v7.widget.Toolbar; -import android.support.v7.widget.util.SortedListAdapterCallback; -import android.text.TextUtils; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ProgressBar; -import android.widget.TextView; -import android.widget.Toast; - -import com.dropbox.client2.DropboxAPI; -import com.dropbox.client2.android.AndroidAuthSession; -import com.dropbox.client2.exception.DropboxException; -import com.nononsenseapps.filepicker.AbstractFilePickerFragment; -import com.nononsenseapps.filepicker.FileItemAdapter; -import com.nononsenseapps.filepicker.sample.R; - -import java.io.File; - -@SuppressLint("ValidFragment") -public class DropboxFilePickerFragment - extends AbstractFilePickerFragment { - - private final DropboxAPI dbApi; - private ProgressBar progressBar; - private RecyclerView recyclerView; - - @SuppressLint("ValidFragment") - public DropboxFilePickerFragment(final DropboxAPI api) { - super(); - if (api == null) { - throw new NullPointerException("FileSystem may not be null"); - } else if (!api.getSession().isLinked()) { - throw new IllegalArgumentException("Must be linked with Dropbox"); - } - - this.dbApi = api; - } - - @Override - protected View inflateRootView(LayoutInflater inflater, ViewGroup container) { - // Load the specific layout we created for dropbox/ftp - View view = inflater.inflate(R.layout.fragment_loading_filepicker, container, false); - // And bind the progress bar - progressBar = (ProgressBar) view.findViewById(R.id.progressBar); - - return view; - } - - /** - * If we are loading, then hide the list and show the progress bar instead. - * - * @param nextPath path to list files for - */ - @Override - protected void refresh(DropboxAPI.Entry nextPath) { - super.refresh(nextPath); - if (isLoading) { - progressBar.setVisibility(View.VISIBLE); - recyclerView.setVisibility(View.INVISIBLE); - } - } - - /** - * Once loading has finished, show the list and hide the progress bar. - */ - @Override - public void onLoadFinished(Loader> loader, SortedList data) { - progressBar.setVisibility(View.INVISIBLE); - recyclerView.setVisibility(View.VISIBLE); - super.onLoadFinished(loader, data); - } - - /** - * Once loading has finished, show the list and hide the progress bar. - */ - @Override - public void onLoaderReset(Loader> loader) { - progressBar.setVisibility(View.INVISIBLE); - recyclerView.setVisibility(View.VISIBLE); - super.onLoaderReset(loader); - } - - @Override - public void onNewFolder(@NonNull final String name) { - File folder = new File(mCurrentPath.path, name); - new FolderCreator().execute(folder.getPath()); - } - - @Override - public boolean isDir(@NonNull final DropboxAPI.Entry file) { - return file.isDir; - } - - @NonNull - @Override - public DropboxAPI.Entry getParent(@NonNull final DropboxAPI.Entry from) { - // Take care of a slight limitation in Dropbox code: - if (from.path.length() > 1 && from.path.endsWith("/")) { - from.path = from.path.substring(0, from.path.length() - 1); - } - String parent = from.parentPath(); - if (TextUtils.isEmpty(parent)) { - parent = "/"; - } - - return getPath(parent); - - } - - @NonNull - @Override - public DropboxAPI.Entry getPath(@NonNull final String path) { - final DropboxAPI.Entry entry = new DropboxAPI.Entry(); - entry.path = path; - entry.isDir = true; - return entry; - - } - - @NonNull - @Override - public String getFullPath(@NonNull final DropboxAPI.Entry file) { - return file.path; - } - - @NonNull - @Override - public String getName(@NonNull final DropboxAPI.Entry file) { - return file.fileName(); - } - - @NonNull - @Override - public DropboxAPI.Entry getRoot() { - return getPath("/"); - } - - @NonNull - @Override - public Uri toUri(@NonNull final DropboxAPI.Entry file) { - return new Uri.Builder().scheme("dropbox").authority("").path(file.path).build(); - } - - @NonNull - @Override - public Loader> getLoader() { - return new AsyncTaskLoader>(getActivity()) { - - @Override - public SortedList loadInBackground() { - SortedList files = new SortedList<>(DropboxAPI.Entry.class, - new SortedListAdapterCallback(null) { - @Override - public int compare(DropboxAPI.Entry lhs, DropboxAPI.Entry rhs) { - if (isDir(lhs) && !isDir(rhs)) { - return -1; - } else if (isDir(rhs) && !isDir(lhs)) { - return 1; - } else { - return lhs.fileName().toLowerCase() - .compareTo(rhs.fileName().toLowerCase()); - } - } - - @Override - public void onInserted(int position, int count) { - // Ignore (DO NOT MODIFY ADAPTER HERE!) - } - - @Override - public void onRemoved(int position, int count) { - // Ignore (DO NOT MODIFY ADAPTER HERE!) - } - - @Override - public void onMoved(int fromPosition, int toPosition) { - // Ignore (DO NOT MODIFY ADAPTER HERE!) - } - - @Override - public void onChanged(int position, int count) { - // Ignore (DO NOT MODIFY ADAPTER HERE!) - } - - @Override - public boolean areContentsTheSame(DropboxAPI.Entry lhs, DropboxAPI.Entry rhs) { - return lhs.fileName().equals(rhs.fileName()) && (lhs.isDir == rhs.isDir); - } - - @Override - public boolean areItemsTheSame(DropboxAPI.Entry lhs, DropboxAPI.Entry rhs) { - return areContentsTheSame(lhs, rhs); - } - }, 0); - - try { - - if (!dbApi.metadata(mCurrentPath.path, 1, null, false, - null).isDir) { - mCurrentPath = getRoot(); - } - - DropboxAPI.Entry dirEntry = - dbApi.metadata(mCurrentPath.path, 0, null, true, - null); - - files.beginBatchedUpdates(); - - for (DropboxAPI.Entry entry : dirEntry.contents) { - if ((mode == MODE_FILE || mode == MODE_FILE_AND_DIR) || - entry.isDir) { - files.add(entry); - } - } - - files.endBatchedUpdates(); - } catch (DropboxException ignored) { - } - - return files; - } - - /** - * Handles a request to start the Loader. - */ - @Override - protected void onStartLoading() { - super.onStartLoading(); - - if (mCurrentPath == null || !mCurrentPath.isDir) { - mCurrentPath = getRoot(); - } - - forceLoad(); - } - - /** - * Handles a request to completely reset the Loader. - */ - @Override - protected void onReset() { - super.onReset(); - } - }; - } - - /** - * Dropbox requires stuff to be done in a background thread. Refreshing has to be done on the - * UI thread however (it restarts the loader so actual work is done in the background). - */ - private class FolderCreator extends AsyncTask { - @Override - protected void onPreExecute() { - // Switch to progress bar before starting work - progressBar.setVisibility(View.VISIBLE); - recyclerView.setVisibility(View.INVISIBLE); - } - - @Override - protected DropboxAPI.Entry doInBackground(final String... paths) { - if (paths.length == 0) { - return null; - } - - String path = paths[0]; - try { - dbApi.createFolder(path); - return dbApi.metadata(path, 1, null, false, null); - } catch (DropboxException e) { - return null; - } - } - - @Override - protected void onPostExecute(@Nullable DropboxAPI.Entry path) { - if (path != null) { - goToDir(path); - } else { - progressBar.setVisibility(View.INVISIBLE); - recyclerView.setVisibility(View.VISIBLE); - Toast.makeText(getActivity(), R.string.nnf_create_folder_error, - Toast.LENGTH_SHORT).show(); - } - } - } -} diff --git a/sample/src/main/java/com/nononsenseapps/filepicker/sample/dropbox/DropboxSyncHelper.java b/sample/src/main/java/com/nononsenseapps/filepicker/sample/dropbox/DropboxSyncHelper.java deleted file mode 100644 index 3792d1b..0000000 --- a/sample/src/main/java/com/nononsenseapps/filepicker/sample/dropbox/DropboxSyncHelper.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -package com.nononsenseapps.filepicker.sample.dropbox; - -import android.content.Context; -import android.preference.PreferenceManager; - -import com.dropbox.client2.DropboxAPI; -import com.dropbox.client2.android.AndroidAuthSession; -import com.dropbox.client2.session.AppKeyPair; - -/** - * This class has some utility functions for dealing with Dropbox. You need - * to input your API keys below. - * See Dropbox for more information: - * https://www.dropbox.com/developers/core/start/android - *

- * You also need to drop your APP_KEY in the manifest in - * com.dropbox.client2.android.AuthActivity - * See here for info: - * https://www.dropbox.com/developers/core/sdks/android - */ -public class DropboxSyncHelper { - // Change these two lines to your app's stuff - final static public String APP_KEY = "sm57t7s6lmgj745"; - final static public String APP_SECRET = "eie6mq0lvcw9t7x"; - - public static final String PREF_DROPBOX_TOKEN = "dropboxtoken"; - - public static DropboxAPI getDBApi( - final Context context) { - final DropboxAPI mDBApi; - - final AppKeyPair appKeys = new AppKeyPair(APP_KEY, APP_SECRET); - final AndroidAuthSession session; - - if (PreferenceManager.getDefaultSharedPreferences(context) - .contains(PREF_DROPBOX_TOKEN)) { - session = new AndroidAuthSession(appKeys, - PreferenceManager.getDefaultSharedPreferences(context) - .getString(PREF_DROPBOX_TOKEN, "")); - } else { - session = new AndroidAuthSession(appKeys); - } - mDBApi = new DropboxAPI(session); - return mDBApi; - } - - /** - * Save the dropbox oauth token so we can reuse the session without - * logging in again. - * @param context - * @param token - */ - public static void saveToken(final Context context, final String token) { - PreferenceManager.getDefaultSharedPreferences(context).edit() - .putString(PREF_DROPBOX_TOKEN, token).apply(); - } -} diff --git a/sample/src/main/java/com/nononsenseapps/filepicker/sample/fastscroller/FastScrollerFileItemAdapter.java b/sample/src/main/java/com/nononsenseapps/filepicker/sample/fastscroller/FastScrollerFileItemAdapter.java deleted file mode 100644 index 12dad2d..0000000 --- a/sample/src/main/java/com/nononsenseapps/filepicker/sample/fastscroller/FastScrollerFileItemAdapter.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.nononsenseapps.filepicker.sample.fastscroller; - -import android.support.annotation.NonNull; - -import com.nononsenseapps.filepicker.FileItemAdapter; -import com.nononsenseapps.filepicker.LogicHandler; -import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView; - -import java.io.File; - - -public class FastScrollerFileItemAdapter extends FileItemAdapter implements - FastScrollRecyclerView.SectionedAdapter { - - public FastScrollerFileItemAdapter( - @NonNull LogicHandler logic) { - super(logic); - } - - @NonNull - @Override - public String getSectionName(int position) { - File path = getItem(position); - if (path == null) { - return ".."; - } - return mLogic.getName(path).substring(0, 1).toLowerCase(); - } -} diff --git a/sample/src/main/java/com/nononsenseapps/filepicker/sample/fastscroller/FastScrollerFilePickerActivity.java b/sample/src/main/java/com/nononsenseapps/filepicker/sample/fastscroller/FastScrollerFilePickerActivity.java deleted file mode 100644 index 9c8a254..0000000 --- a/sample/src/main/java/com/nononsenseapps/filepicker/sample/fastscroller/FastScrollerFilePickerActivity.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -package com.nononsenseapps.filepicker.sample.fastscroller; - -import android.os.Environment; -import android.support.annotation.Nullable; - -import com.nononsenseapps.filepicker.AbstractFilePickerActivity; -import com.nononsenseapps.filepicker.AbstractFilePickerFragment; - -import java.io.File; - -/** - * All this class does is return a suitable fragment. - */ -public class FastScrollerFilePickerActivity extends AbstractFilePickerActivity { - - public FastScrollerFilePickerActivity() { - super(); - } - - @Override - protected AbstractFilePickerFragment getFragment( - @Nullable final String startPath, final int mode, final boolean allowMultiple, - final boolean allowCreateDir, final boolean allowExistingFile, - final boolean singleClick) { - AbstractFilePickerFragment fragment = new FastScrollerFilePickerFragment(); - // startPath is allowed to be null. In that case, default folder should be SD-card and not "/" - fragment.setArgs(startPath != null ? startPath : Environment.getExternalStorageDirectory().getPath(), - mode, allowMultiple, allowCreateDir, allowExistingFile, singleClick); - return fragment; - } -} diff --git a/sample/src/main/java/com/nononsenseapps/filepicker/sample/fastscroller/FastScrollerFilePickerActivity2.java b/sample/src/main/java/com/nononsenseapps/filepicker/sample/fastscroller/FastScrollerFilePickerActivity2.java deleted file mode 100644 index e31a248..0000000 --- a/sample/src/main/java/com/nononsenseapps/filepicker/sample/fastscroller/FastScrollerFilePickerActivity2.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.nononsenseapps.filepicker.sample.fastscroller; - -/** - * Just for theme sample purposes - */ -public class FastScrollerFilePickerActivity2 extends FastScrollerFilePickerActivity { -} diff --git a/sample/src/main/java/com/nononsenseapps/filepicker/sample/fastscroller/FastScrollerFilePickerFragment.java b/sample/src/main/java/com/nononsenseapps/filepicker/sample/fastscroller/FastScrollerFilePickerFragment.java deleted file mode 100644 index abb1501..0000000 --- a/sample/src/main/java/com/nononsenseapps/filepicker/sample/fastscroller/FastScrollerFilePickerFragment.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.nononsenseapps.filepicker.sample.fastscroller; - -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; - -import com.nononsenseapps.filepicker.FilePickerFragment; -import com.nononsenseapps.filepicker.sample.R; - -public class FastScrollerFilePickerFragment extends FilePickerFragment { - @Override - protected View inflateRootView(LayoutInflater inflater, ViewGroup container) { - return inflater.inflate(R.layout.fragment_fastscrollerfilepicker, container, false); - } -} diff --git a/sample/src/main/java/com/nononsenseapps/filepicker/sample/ftp/FTPPath.java b/sample/src/main/java/com/nononsenseapps/filepicker/sample/ftp/FTPPath.java deleted file mode 100644 index d0f7f43..0000000 --- a/sample/src/main/java/com/nononsenseapps/filepicker/sample/ftp/FTPPath.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -package com.nononsenseapps.filepicker.sample.ftp; - -import android.support.annotation.NonNull; - -import org.apache.commons.net.ftp.FTPFile; - -/** - * Adds path information to FtpFile objects - */ -public class FTPPath { - public final String path; - public final FTPFile file; - - public FTPPath(@NonNull String path, @NonNull FTPFile file) { - this.path = path; - this.file = file; - } - - public FTPPath(@NonNull FTPPath mCurrentPath, @NonNull FTPFile file) { - this.file = file; - if (mCurrentPath.path.endsWith("/")) { - this.path = mCurrentPath + file.getName(); - } else { - this.path = mCurrentPath.path + "/" + file.getName(); - } - } - - public boolean isDirectory() { - return file.isDirectory(); - } - - public String getName() { - return file.getName(); - } - - public String appendToDir(@NonNull String name) { - if (this.path.endsWith("/")) { - return path + name; - } else { - return path + "/" + name; - } - } -} diff --git a/sample/src/main/java/com/nononsenseapps/filepicker/sample/ftp/FtpDir.java b/sample/src/main/java/com/nononsenseapps/filepicker/sample/ftp/FtpDir.java deleted file mode 100644 index ec7d2a9..0000000 --- a/sample/src/main/java/com/nononsenseapps/filepicker/sample/ftp/FtpDir.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -package com.nononsenseapps.filepicker.sample.ftp; - -public class FtpDir extends FtpFile { - - public FtpDir(FtpFile dir, String name) { - super(dir, name); - } - - public FtpDir(String path) { - super(path); - } - - public FtpDir(String dirPath, String name) { - super(dirPath, name); - } - - @Override - public boolean isDirectory() { - return true; - } - - @Override - public boolean isFile() { - return false; - } -} diff --git a/sample/src/main/java/com/nononsenseapps/filepicker/sample/ftp/FtpFile.java b/sample/src/main/java/com/nononsenseapps/filepicker/sample/ftp/FtpFile.java deleted file mode 100644 index a481ef3..0000000 --- a/sample/src/main/java/com/nononsenseapps/filepicker/sample/ftp/FtpFile.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -package com.nononsenseapps.filepicker.sample.ftp; - -public class FtpFile { - - public static final char separatorChar = '/'; - public static final String separator = "/"; - private String path; - - public FtpFile(FtpFile dir, String name) { - this(dir == null ? null : dir.getPath(), name); - } - - public FtpFile(String path) { - this.path = fixSlashes(path); - } - - public FtpFile(String dirPath, String name) { - if (name == null) { - throw new NullPointerException("name == null"); - } - if (dirPath == null || dirPath.isEmpty()) { - this.path = fixSlashes(name); - } else if (name.isEmpty()) { - this.path = fixSlashes(dirPath); - } else { - this.path = fixSlashes(join(dirPath, name)); - } - } - - public static String fixSlashes(String origPath) { - // Remove duplicate adjacent slashes. - boolean lastWasSlash = false; - char[] newPath = origPath.toCharArray(); - int length = newPath.length; - int newLength = 0; - for (int i = 0; i < length; ++i) { - char ch = newPath[i]; - if (ch == '/') { - if (!lastWasSlash) { - newPath[newLength++] = separatorChar; - lastWasSlash = true; - } - } else { - newPath[newLength++] = ch; - lastWasSlash = false; - } - } - // Remove any trailing slash (unless this is the root of the file system). - if (lastWasSlash && newLength > 1) { - newLength--; - } - // Reuse the original string if possible. - return (newLength != length) ? new String(newPath, 0, newLength) : origPath; - } - - // Joins two path components, adding a separator only if necessary. - public static String join(String prefix, String suffix) { - int prefixLength = prefix.length(); - boolean haveSlash = (prefixLength > 0 && prefix.charAt(prefixLength - 1) == separatorChar); - if (!haveSlash) { - haveSlash = (suffix.length() > 0 && suffix.charAt(0) == separatorChar); - } - return haveSlash ? (prefix + suffix) : (prefix + separatorChar + suffix); - } - - public String getName() { - int separatorIndex = path.lastIndexOf(separator); - return (separatorIndex < 0) ? path : path.substring(separatorIndex + 1, path.length()); - } - - public String getParent() { - int length = path.length(), firstInPath = 0; - int index = path.lastIndexOf(separatorChar); - if (index == -1 || path.charAt(length - 1) == separatorChar) { - return null; - } - if (path.indexOf(separatorChar) == index - && path.charAt(firstInPath) == separatorChar) { - return path.substring(0, index + 1); - } - return path.substring(0, index); - } - - public FtpFile getParentFile() { - String tempParent = getParent(); - if (tempParent == null) { - return null; - } - return new FtpFile(tempParent); - } - - /** - * Returns the path of this file. - */ - public String getPath() { - return path; - } - - public boolean isDirectory() { - return false; - } - - public boolean isFile() { - return true; - } -} diff --git a/sample/src/main/java/com/nononsenseapps/filepicker/sample/ftp/FtpPickerActivity.java b/sample/src/main/java/com/nononsenseapps/filepicker/sample/ftp/FtpPickerActivity.java deleted file mode 100644 index 62ccb98..0000000 --- a/sample/src/main/java/com/nononsenseapps/filepicker/sample/ftp/FtpPickerActivity.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -package com.nononsenseapps.filepicker.sample.ftp; - - -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; - -import com.nononsenseapps.filepicker.AbstractFilePickerActivity; -import com.nononsenseapps.filepicker.AbstractFilePickerFragment; - -import org.apache.commons.net.ftp.FTPClient; - -/** - * An example implementation of an FTP file-picker - */ -public class FtpPickerActivity extends AbstractFilePickerActivity { - @Override - protected AbstractFilePickerFragment getFragment(@Nullable String startPath, int mode, - boolean allowMultiple, - boolean allowCreateDir, - boolean allowExistingFile, - boolean singleClick) { - return FtpPickerFragment.newInstance(startPath, mode, allowMultiple, allowCreateDir, - allowExistingFile, singleClick, - "debian.simnet.is", - FTPClient.DEFAULT_PORT, - null, - null, "/"); - } -} diff --git a/sample/src/main/java/com/nononsenseapps/filepicker/sample/ftp/FtpPickerActivity2.java b/sample/src/main/java/com/nononsenseapps/filepicker/sample/ftp/FtpPickerActivity2.java deleted file mode 100644 index b7d1b76..0000000 --- a/sample/src/main/java/com/nononsenseapps/filepicker/sample/ftp/FtpPickerActivity2.java +++ /dev/null @@ -1,15 +0,0 @@ -/* - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -package com.nononsenseapps.filepicker.sample.ftp; - - -/** - * This is a copy of the included activity for the sole purpose - * of being to show you a second example theme - */ -public class FtpPickerActivity2 extends FtpPickerActivity { -} diff --git a/sample/src/main/java/com/nononsenseapps/filepicker/sample/ftp/FtpPickerFragment.java b/sample/src/main/java/com/nononsenseapps/filepicker/sample/ftp/FtpPickerFragment.java deleted file mode 100644 index cbe7289..0000000 --- a/sample/src/main/java/com/nononsenseapps/filepicker/sample/ftp/FtpPickerFragment.java +++ /dev/null @@ -1,389 +0,0 @@ -/* - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -package com.nononsenseapps.filepicker.sample.ftp; - -import android.net.Uri; -import android.os.AsyncTask; -import android.os.Bundle; -import android.support.annotation.NonNull; -import android.support.v4.content.AsyncTaskLoader; -import android.support.v4.content.Loader; -import android.support.v7.util.SortedList; -import android.support.v7.widget.util.SortedListAdapterCallback; -import android.util.Log; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ProgressBar; -import android.widget.Toast; - -import com.nononsenseapps.filepicker.AbstractFilePickerFragment; -import com.nononsenseapps.filepicker.sample.R; - -import org.apache.commons.net.ftp.FTP; -import org.apache.commons.net.ftp.FTPClient; -import org.apache.commons.net.ftp.FTPFile; - -import java.io.IOException; - -/** - * This example allows you to browse the files on an FTP-server - */ -public class FtpPickerFragment extends AbstractFilePickerFragment { - - private static final String KEY_FTP_SERVER = "KEY_FTP_SERVER"; - private static final String KEY_FTP_PORT = "KEY_FTP_PORT"; - private static final String KEY_FTP_USERNAME = "KEY_FTP_USERNAME"; - private static final String KEY_FTP_PASSWORD = "KEY_FTP_PASSWORD"; - private static final String KEY_FTP_ROOTDIR = "KEY_FTP_ROOTDIR"; - private static final String TAG = "NoNonsenseFtp"; - private final FTPClient ftp; - private String server; - private int port; - private String username; - private String password; - private boolean loggedIn = false; - private String rootDir = "/"; - private ProgressBar progressBar; - - public FtpPickerFragment() { - super(); - ftp = new FTPClient(); - } - - public static AbstractFilePickerFragment newInstance(String startPath, int mode, - boolean allowMultiple, - boolean allowCreateDir, - boolean allowExistingFile, - boolean singleClick, - String server, int port, - String username, - String password, - String rootDir) { - FtpPickerFragment fragment = new FtpPickerFragment(); - // Add arguments - fragment.setArgs(startPath, mode, allowMultiple, allowCreateDir, - allowExistingFile, singleClick); - Bundle args = fragment.getArguments(); - - // Add ftp related stuff - args.putString(KEY_FTP_ROOTDIR, rootDir); - args.putString(KEY_FTP_SERVER, server); - args.putInt(KEY_FTP_PORT, port); - if (username != null && password != null) { - args.putString(KEY_FTP_USERNAME, username); - args.putString(KEY_FTP_PASSWORD, password); - } - - return fragment; - } - - @Override - public void onCreate(Bundle b) { - super.onCreate(b); - - Bundle args = getArguments(); - this.server = args.getString(KEY_FTP_SERVER); - this.port = args.getInt(KEY_FTP_PORT); - this.username = args.getString(KEY_FTP_USERNAME) != null ? args.getString(KEY_FTP_USERNAME) : "anonymous"; - this.password = args.getString(KEY_FTP_PASSWORD) != null ? args.getString(KEY_FTP_PASSWORD) : "anonymous"; - this.rootDir = args.getString(KEY_FTP_ROOTDIR) != null ? args.getString(KEY_FTP_ROOTDIR) : "/"; - } - - @Override - protected View inflateRootView(LayoutInflater inflater, ViewGroup container) { - // Load the specific layout we created for dropbox/ftp - View view = inflater.inflate(R.layout.fragment_loading_filepicker, container, false); - // And bind the progress bar - progressBar = (ProgressBar) view.findViewById(R.id.progressBar); - - return view; - } - - /** - * Return true if the path is a directory and not a file. - */ - @Override - public boolean isDir(@NonNull FtpFile path) { - return path.isDirectory(); - } - - /** - * @return filename of path - */ - @NonNull - @Override - public String getName(@NonNull FtpFile path) { - return path.getName(); - } - - /** - * Convert the path to a URI for the return intent - * - * @return a Uri - */ - @NonNull - @Override - public Uri toUri(@NonNull FtpFile path) { - String user = ""; - if (!username.isEmpty()) { - user = username; - if (!password.isEmpty()) { - user += ":" + password; - } - user += "@"; - } - return Uri.parse("ftp://" + user + server + ":" + port + path.getPath()); - - } - - /** - * Return the path to the parent directory. Should return the root if - * from is root. - */ - @NonNull - @Override - public FtpFile getParent(@NonNull FtpFile from) { - if (from.getPath().equals(getRoot().getPath())) { - // Already at root, we can't go higher - return from; - } else if (from.getParentFile() != null) { - return from.getParentFile(); - } else { - return from; - } - } - - /** - * @return the full path to the file - */ - @NonNull - @Override - public String getFullPath(@NonNull FtpFile path) { - return path.getPath(); - } - - /** - * Convert the path to the type used. - */ - @NonNull - @Override - public FtpFile getPath(@NonNull String path) { - return new FtpFile(path); - } - - /** - * Get the root path (lowest allowed). - */ - @NonNull - @Override - public FtpFile getRoot() { - return new FtpDir(rootDir); - } - - @Override - public void onDestroy() { - if (ftp.isConnected()) { - try { - ftp.disconnect(); - } catch (IOException ignored) { - } - } - super.onDestroy(); - } - - /** - * Get a loader that lists the files in the current path, - * and monitors changes. - */ - @NonNull - @Override - public Loader> getLoader() { - return new AsyncTaskLoader>(getContext()) { - @Override - public SortedList loadInBackground() { - SortedList sortedList = new SortedList<>(FtpFile.class, new SortedListAdapterCallback(getDummyAdapter()) { - @Override - public int compare(FtpFile lhs, FtpFile rhs) { - if (lhs.isDirectory() && !rhs.isDirectory()) { - return -1; - } else if (rhs.isDirectory() && !lhs.isDirectory()) { - return 1; - } else { - return lhs.getName().compareToIgnoreCase(rhs.getName()); - } - } - - @Override - public boolean areContentsTheSame(FtpFile oldItem, FtpFile newItem) { - return oldItem.getName().equals(newItem.getName()); - } - - @Override - public boolean areItemsTheSame(FtpFile item1, FtpFile item2) { - return item1.getName().equals(item2.getName()); - } - }); - - - if (!ftp.isConnected()) { - // Connect - try { - ftp.connect(server, port); - - ftp.setFileType(FTP.ASCII_FILE_TYPE); - ftp.enterLocalPassiveMode(); - ftp.setUseEPSVwithIPv4(false); - - if (!(loggedIn = ftp.login(username, password))) { - ftp.logout(); - Log.e(TAG, "Login failed"); - } - } catch (IOException e) { - if (ftp.isConnected()) { - try { - ftp.disconnect(); - } catch (IOException ignored) { - } - } - Log.e(TAG, "Could not connect to server."); - } - } - - if (loggedIn) { - try { - // handle if directory does not exist. Fall back to root. - if (mCurrentPath == null || !mCurrentPath.isDirectory()) { - mCurrentPath = getRoot(); - } - - sortedList.beginBatchedUpdates(); - for (FTPFile f : ftp.listFiles(mCurrentPath.getPath())) { - FtpFile file; - if (f.isDirectory()) { - file = new FtpDir(mCurrentPath, f.getName()); - } else { - file = new FtpFile(mCurrentPath, f.getName()); - } - if (isItemVisible(file)) { - sortedList.add(file); - } - } - sortedList.endBatchedUpdates(); - } catch (IOException e) { - Log.e(TAG, "IOException: " + e.getMessage()); - } - } - - return sortedList; - } - - /** - * Handles a request to start the Loader. - */ - @Override - protected void onStartLoading() { - super.onStartLoading(); - - // handle if directory does not exist. Fall back to root. - if (mCurrentPath == null || !mCurrentPath.isDirectory()) { - mCurrentPath = getRoot(); - } - - forceLoad(); - } - }; - } - - /** - * Used by the list to determine whether a file should be displayed or not. - * Default behavior is to always display folders. If files can be selected, - * then files are also displayed. Override this method to enable other - * filtering behaviour, like only displaying files with specific extensions (.zip, .txt, etc). - * - * @param file to maybe add. Can be either a directory or file. - * @return True if item should be added to the list, false otherwise - */ - protected boolean isItemVisible(final FtpFile file) { - return file.isDirectory() || (mode == MODE_FILE || mode == MODE_FILE_AND_DIR); - } - - /** - * Name is validated to be non-null, non-empty and not containing any - * slashes. - * - * @param name The name of the folder the user wishes to create. - */ - @Override - public void onNewFolder(@NonNull String name) { - AsyncTask task = new AsyncTask() { - - @Override - protected FtpFile doInBackground(String... names) { - FtpFile result = null; - if (names.length > 0) { - result = onNewFolderAsync(names[0]); - } - return result; - } - - @Override - protected void onPostExecute(FtpFile folder) { - if (folder != null) { - refresh(folder); - } else { - Toast.makeText(getContext(), R.string.nnf_create_folder_error, Toast.LENGTH_SHORT).show(); - } - } - }; - task.execute(name); - } - - /** - * If we are loading, then hide the list and show the progress bar instead. - * - * @param nextPath path to list files for - */ - @Override - protected void refresh(@NonNull FtpFile nextPath) { - super.refresh(nextPath); - if (isLoading) { - progressBar.setVisibility(View.VISIBLE); - recyclerView.setVisibility(View.INVISIBLE); - } - } - - @Override - public void onLoadFinished(Loader> loader, SortedList data) { - progressBar.setVisibility(View.INVISIBLE); - recyclerView.setVisibility(View.VISIBLE); - super.onLoadFinished(loader, data); - } - - @Override - public void onLoaderReset(Loader> loader) { - progressBar.setVisibility(View.INVISIBLE); - recyclerView.setVisibility(View.VISIBLE); - super.onLoaderReset(loader); - } - - /** - * @param name The name of the folder the user wishes to create. - */ - public FtpFile onNewFolderAsync(String name) { - FtpDir folder = new FtpDir(mCurrentPath, name); - try { - if (ftp.makeDirectory(folder.getPath())) { - // Success, return result - return folder; - } - } catch (IOException e) { - Log.e(TAG, "IO Exception: " + folder.getPath()); - } - return null; - } -} diff --git a/sample/src/main/java/com/nononsenseapps/filepicker/sample/multimedia/MultimediaPickerActivity.java b/sample/src/main/java/com/nononsenseapps/filepicker/sample/multimedia/MultimediaPickerActivity.java deleted file mode 100644 index 3cb896a..0000000 --- a/sample/src/main/java/com/nononsenseapps/filepicker/sample/multimedia/MultimediaPickerActivity.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -package com.nononsenseapps.filepicker.sample.multimedia; - -import android.os.Environment; -import android.support.annotation.Nullable; - -import com.nononsenseapps.filepicker.AbstractFilePickerActivity; -import com.nononsenseapps.filepicker.AbstractFilePickerFragment; - -import java.io.File; - -/** - * All this class does is return a suitable fragment. - */ -public class MultimediaPickerActivity extends AbstractFilePickerActivity { - - public MultimediaPickerActivity() { - super(); - } - - @Override - protected AbstractFilePickerFragment getFragment( - @Nullable final String startPath, final int mode, final boolean allowMultiple, - final boolean allowCreateDir, final boolean allowExistingFile, - final boolean singleClick) { - AbstractFilePickerFragment fragment = new MultimediaPickerFragment(); - // startPath is allowed to be null. In that case, default folder should be SD-card and not "/" - fragment.setArgs(startPath != null ? startPath : Environment.getExternalStorageDirectory().getPath(), - mode, allowMultiple, allowCreateDir, allowExistingFile, singleClick); - return fragment; - } -} diff --git a/sample/src/main/java/com/nononsenseapps/filepicker/sample/multimedia/MultimediaPickerActivity2.java b/sample/src/main/java/com/nononsenseapps/filepicker/sample/multimedia/MultimediaPickerActivity2.java deleted file mode 100644 index 6f6606e..0000000 --- a/sample/src/main/java/com/nononsenseapps/filepicker/sample/multimedia/MultimediaPickerActivity2.java +++ /dev/null @@ -1,13 +0,0 @@ -/* - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -package com.nononsenseapps.filepicker.sample.multimedia; - -/** - * Duplicate to allow second theme to be used. - */ -public class MultimediaPickerActivity2 extends MultimediaPickerActivity { -} diff --git a/sample/src/main/java/com/nononsenseapps/filepicker/sample/multimedia/MultimediaPickerFragment.java b/sample/src/main/java/com/nononsenseapps/filepicker/sample/multimedia/MultimediaPickerFragment.java deleted file mode 100644 index dd4b4c6..0000000 --- a/sample/src/main/java/com/nononsenseapps/filepicker/sample/multimedia/MultimediaPickerFragment.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -package com.nononsenseapps.filepicker.sample.multimedia; - -import android.support.annotation.NonNull; -import android.support.v7.widget.RecyclerView; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ImageView; - -import com.bumptech.glide.Glide; -import com.nononsenseapps.filepicker.FilePickerFragment; -import com.nononsenseapps.filepicker.sample.R; - -import java.io.File; - -/** - * A sample which demonstrates how appropriate methods - * can be overwritten in order to enable enhanced - * capabilities, in this case showing thumbnails of images. - *

- * I am still listing all files, so I extend from the ready made - * SD-card browser classes. This allows this class to focus - * entirely on the image side of things. - *

- * To load the image I am using the super great Glide library - * which only requires a single line of code in this file. - */ -public class MultimediaPickerFragment extends FilePickerFragment { - - // Make sure these do not collide with LogicHandler.VIEWTYPE codes. - // They are 1-2, so 11 leaves a lot of free space in between. - private static final int VIEWTYPE_IMAGE_CHECKABLE = 11; - private static final int VIEWTYPE_IMAGE = 12; - - private static final String[] MULTIMEDIA_EXTENSIONS = - new String[]{".png", ".jpg", ".gif", ".mp4"}; - - /** - * An extremely simple method for identifying multimedia. This - * could be improved, but it's good enough for this example. - * - * @param file which could be an image or a video - * @return true if the file can be previewed, false otherwise - */ - protected boolean isMultimedia(File file) { - //noinspection SimplifiableIfStatement - if (isDir(file)) { - return false; - } - - String path = file.getPath().toLowerCase(); - for (String ext : MULTIMEDIA_EXTENSIONS) { - if (path.endsWith(ext)) { - return true; - } - } - - return false; - } - - /** - * Here we check if the file is an image, and if thus if we should create views corresponding - * to our image layouts. - * - * @param position 0 - n, where the header has been subtracted - * @param file to check type of - * @return the viewtype of the item - */ - @Override - public int getItemViewType(int position, @NonNull File file) { - if (isMultimedia(file)) { - if (isCheckable(file)) { - return VIEWTYPE_IMAGE_CHECKABLE; - } else { - return VIEWTYPE_IMAGE; - } - } else { - return super.getItemViewType(position, file); - } - } - - /** - * We override this method and provide some special views for images. - * This is necessary to work around a bug on older Android versions (4.0.3 for example) - * where setting a "tint" would just make the entire image a square of solid color. - *

- * So the special layouts used here are merely "untinted" copies from the library. - * - * @param parent Containing view - * @param viewType which the ViewHolder will contain - * @return a DirViewHolder (or subclass thereof) - */ - @NonNull - @Override - public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - switch (viewType) { - case VIEWTYPE_IMAGE_CHECKABLE: - return new CheckableViewHolder(LayoutInflater.from(getActivity()) - .inflate(R.layout.listitem_image_checkable, parent, false)); - case VIEWTYPE_IMAGE: - return new DirViewHolder(LayoutInflater.from(getActivity()) - .inflate(R.layout.listitem_image, parent, false)); - default: - return super.onCreateViewHolder(parent, viewType); - } - } - - /** - * Overriding this method allows us to inject a preview image - * in the layout - * - * @param vh to bind data from either a file or directory - * @param position 0 - n, where the header has been subtracted - * @param file to show info about - */ - @Override - public void onBindViewHolder(@NonNull DirViewHolder vh, int position, @NonNull File file) { - // Let the super method do its thing with checkboxes and text - super.onBindViewHolder(vh, position, file); - - // Here we load the preview image if it is an image file - final int viewType = getItemViewType(position, file); - if (viewType == VIEWTYPE_IMAGE_CHECKABLE || viewType == VIEWTYPE_IMAGE) { - // Need to set it to visible because the base code will set it to invisible by default - vh.icon.setVisibility(View.VISIBLE); - // Just load the image - Glide.with(this).load(file).into((ImageView) vh.icon); - } - } -} diff --git a/sample/src/main/java/com/nononsenseapps/filepicker/sample/root/SUErrorFragment.java b/sample/src/main/java/com/nononsenseapps/filepicker/sample/root/SUErrorFragment.java deleted file mode 100644 index 207a688..0000000 --- a/sample/src/main/java/com/nononsenseapps/filepicker/sample/root/SUErrorFragment.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.nononsenseapps.filepicker.sample.root; - -import android.app.Dialog; -import android.content.DialogInterface; -import android.os.Bundle; -import android.support.annotation.NonNull; -import android.support.v4.app.DialogFragment; -import android.support.v4.app.FragmentManager; -import android.support.v7.app.AlertDialog; - -/** - * A dialog which tells the user that no SU binary is available - */ -public class SUErrorFragment extends DialogFragment { - - private static final String TAG = "SUErrorFragment"; - - public static void showDialog(@NonNull final FragmentManager fm) { - SUErrorFragment d = new SUErrorFragment(); - d.show(fm, TAG); - } - - @NonNull - @Override - public Dialog onCreateDialog(Bundle savedInstanceState) { - AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); - builder.setMessage("No read permisson, root unavailable") - .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - dialog.dismiss(); - } - }); - return builder.create(); - } -} diff --git a/sample/src/main/java/com/nononsenseapps/filepicker/sample/root/SUPickerActivity.java b/sample/src/main/java/com/nononsenseapps/filepicker/sample/root/SUPickerActivity.java deleted file mode 100644 index e220ceb..0000000 --- a/sample/src/main/java/com/nononsenseapps/filepicker/sample/root/SUPickerActivity.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.nononsenseapps.filepicker.sample.root; - -import android.os.Environment; -import android.support.annotation.Nullable; - -import com.nononsenseapps.filepicker.AbstractFilePickerActivity; -import com.nononsenseapps.filepicker.AbstractFilePickerFragment; - -import java.io.File; - -public class SUPickerActivity extends AbstractFilePickerActivity { - - public SUPickerActivity() { - super(); - } - - @Override - protected AbstractFilePickerFragment getFragment(@Nullable String startPath, - int mode, - boolean allowMultiple, - boolean allowCreateDir, - boolean allowExistingFile, - boolean singleClick) { - AbstractFilePickerFragment fragment = new SUPickerFragment(); - // startPath is allowed to be null. In that case, default folder should be SD-card and - // not "/" - fragment.setArgs( - startPath != null ? startPath : Environment.getExternalStorageDirectory().getPath(), - mode, allowMultiple, allowCreateDir, allowExistingFile, singleClick); - return fragment; - } -} diff --git a/sample/src/main/java/com/nononsenseapps/filepicker/sample/root/SUPickerActivity2.java b/sample/src/main/java/com/nononsenseapps/filepicker/sample/root/SUPickerActivity2.java deleted file mode 100644 index a349951..0000000 --- a/sample/src/main/java/com/nononsenseapps/filepicker/sample/root/SUPickerActivity2.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.nononsenseapps.filepicker.sample.root; - -/** - * Just for second theme - */ -public class SUPickerActivity2 extends SUPickerActivity { -} diff --git a/sample/src/main/java/com/nononsenseapps/filepicker/sample/root/SUPickerFragment.java b/sample/src/main/java/com/nononsenseapps/filepicker/sample/root/SUPickerFragment.java deleted file mode 100644 index 2e4049d..0000000 --- a/sample/src/main/java/com/nononsenseapps/filepicker/sample/root/SUPickerFragment.java +++ /dev/null @@ -1,71 +0,0 @@ -package com.nononsenseapps.filepicker.sample.root; - -import android.support.annotation.NonNull; -import android.util.Log; - -import com.nononsenseapps.filepicker.FilePickerFragment; - -import java.io.File; -import java.util.List; - -import eu.chainfire.libsuperuser.Shell; - -/** - * An example picker which calls out to LibSU to get Root-permissions to view otherwise hidden files. - */ -public class SUPickerFragment extends FilePickerFragment { - - @Override - protected boolean hasPermission(@NonNull File path) { - // Return the combination of normal file permissions and SU permissions - return super.hasPermission(path) & (!needSUPermission(path) | hasSUPermission()); - } - - @Override - protected void handlePermission(@NonNull File path) { - // Only call super if we don't have normal file permissions - if (!super.hasPermission(path)) { - super.handlePermission(path); - } - // Only if we need SU permissions - if (needSUPermission(path) && !hasSUPermission()) { - handleSUPermission(); - } - } - - private boolean haveReadPermission(@NonNull File file) { - List result = - Shell.SH.run("test -r " + file.getAbsolutePath() + " && echo \"rootsuccess\""); - return result != null && !result.isEmpty() && "rootsuccess".equals(result.get(0)); - } - - private boolean needSUPermission(@NonNull File path) { - return !haveReadPermission(path); - } - - private boolean isSUAvailable() { - return Shell.SU.available(); - } - - private boolean hasSUPermission() { - if (isSUAvailable()) { - List result = Shell.SU.run("ls -l /"); - if (result != null && !result.isEmpty()) { - return true; - } - } - return false; - } - - private void handleSUPermission() { - if (isSUAvailable()) { - // request - String suVersion = Shell.SU.version(false); - String suVersionInternal = Shell.SU.version(true); - Log.d("libsuperuser: ", "suVersion:"+suVersion+" suVersionInternal:"+suVersionInternal); - } else { - // Notify that no root access available - SUErrorFragment.showDialog(getFragmentManager()); - } - } -} diff --git a/sample/src/main/res/drawable-hdpi/ic_launcher.png b/sample/src/main/res/drawable-hdpi/ic_launcher.png deleted file mode 100644 index 96a442e..0000000 Binary files a/sample/src/main/res/drawable-hdpi/ic_launcher.png and /dev/null differ diff --git a/sample/src/main/res/drawable-mdpi/ic_launcher.png b/sample/src/main/res/drawable-mdpi/ic_launcher.png deleted file mode 100644 index 359047d..0000000 Binary files a/sample/src/main/res/drawable-mdpi/ic_launcher.png and /dev/null differ diff --git a/sample/src/main/res/drawable-xhdpi/ic_launcher.png b/sample/src/main/res/drawable-xhdpi/ic_launcher.png deleted file mode 100644 index 71c6d76..0000000 Binary files a/sample/src/main/res/drawable-xhdpi/ic_launcher.png and /dev/null differ diff --git a/sample/src/main/res/drawable-xxhdpi/ic_launcher.png b/sample/src/main/res/drawable-xxhdpi/ic_launcher.png deleted file mode 100644 index 4df1894..0000000 Binary files a/sample/src/main/res/drawable-xxhdpi/ic_launcher.png and /dev/null differ diff --git a/sample/src/main/res/layout/activity_no_nonsense_file_picker.xml b/sample/src/main/res/layout/activity_no_nonsense_file_picker.xml deleted file mode 100644 index 83cb96b..0000000 --- a/sample/src/main/res/layout/activity_no_nonsense_file_picker.xml +++ /dev/null @@ -1,215 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -