) {}
58 | }
59 |
--------------------------------------------------------------------------------
/examples/app/demoapp/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
16 |
17 |
24 |
25 |
32 |
33 |
40 |
41 |
49 |
50 |
57 |
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/examples/app/demoapp/src/main/java/net/gotev/uploadservicedemo/views/AddItem.kt:
--------------------------------------------------------------------------------
1 | package net.gotev.uploadservicedemo.views
2 |
3 | import android.annotation.TargetApi
4 | import android.content.Context
5 | import android.content.res.TypedArray
6 | import android.graphics.PorterDuff
7 | import android.util.AttributeSet
8 | import android.view.LayoutInflater
9 | import android.view.MotionEvent
10 | import android.widget.ImageView
11 | import android.widget.LinearLayout
12 | import android.widget.TextView
13 | import net.gotev.uploadservicedemo.R
14 |
15 | class AddItem : LinearLayout {
16 | protected lateinit var image: ImageView
17 | protected lateinit var title: TextView
18 |
19 | constructor(context: Context) : super(context) {
20 | init(context, null)
21 | }
22 |
23 | constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
24 | init(context, attrs)
25 | }
26 |
27 | constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
28 | context,
29 | attrs,
30 | defStyleAttr
31 | ) {
32 | init(context, attrs)
33 | }
34 |
35 | @TargetApi(21)
36 | constructor(
37 | context: Context,
38 | attrs: AttributeSet?,
39 | defStyleAttr: Int,
40 | defStyleRes: Int
41 | ) : super(context, attrs, defStyleAttr, defStyleRes) {
42 | init(context, attrs)
43 | }
44 |
45 | private fun init(context: Context, attrs: AttributeSet?) {
46 | if (isInEditMode) return
47 | LayoutInflater.from(context).inflate(R.layout.item_add, this)
48 | image = findViewById(R.id.image)
49 | title = findViewById(R.id.title)
50 |
51 | if (attrs == null) return
52 |
53 | val types = context.obtainStyledAttributes(attrs, R.styleable.AddItemView, 0, 0)
54 | handleTypedArray(types)
55 | types.recycle()
56 | }
57 |
58 | private fun handleTypedArray(types: TypedArray) {
59 | val titleText = types.getString(R.styleable.AddItemView_titleText)
60 | if (titleText != null) title.text = titleText
61 | val valueColor = types.getColor(R.styleable.AddItemView_colorFilter, -1)
62 | if (valueColor != -1) image.setColorFilter(valueColor, PorterDuff.Mode.SRC_ATOP)
63 | }
64 |
65 | override fun dispatchTouchEvent(event: MotionEvent): Boolean {
66 | if (event.action == MotionEvent.ACTION_UP) {
67 | if (hasOnClickListeners()) {
68 | callOnClick()
69 | }
70 | }
71 | return super.dispatchTouchEvent(event)
72 | }
73 |
74 | fun setTitleText(newTitleText: String?): AddItem {
75 | title.text = newTitleText
76 | return this
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/examples/app/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/examples/app/demoapp/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/uploadservice-ftp/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/assets/uploadservice-architecture.xml:
--------------------------------------------------------------------------------
1 | 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
--------------------------------------------------------------------------------
/examples/app/demoapp/src/main/java/net/gotev/uploadservicedemo/dialogs/AddFileParameterNameDialog.kt:
--------------------------------------------------------------------------------
1 | package net.gotev.uploadservicedemo.dialogs
2 |
3 | import android.content.DialogInterface
4 | import android.view.View
5 | import android.view.inputmethod.InputMethodManager
6 | import android.widget.EditText
7 | import android.widget.TextView
8 | import androidx.annotation.StringRes
9 | import androidx.appcompat.app.AlertDialog
10 | import androidx.appcompat.app.AppCompatActivity
11 | import net.gotev.uploadservicedemo.R
12 | import net.gotev.uploadservicedemo.extensions.inputMethodManager
13 |
14 | class AddFileParameterNameDialog(
15 | context: AppCompatActivity,
16 | @StringRes hint: Int,
17 | @StringRes errorMessage: Int,
18 | @StringRes detailsMessage: Int,
19 | private val delegate: (value: String) -> Unit
20 | ) : View.OnClickListener {
21 | private val dialogView: View =
22 | context.layoutInflater.inflate(R.layout.dialog_add_file_parameter_name, null)
23 | private val input: EditText = dialogView.findViewById(R.id.input)
24 | private val details: TextView = dialogView.findViewById(R.id.details)
25 | private val valueErrorString: String = context.getString(errorMessage)
26 | private val dialog: AlertDialog
27 |
28 | init {
29 | input.setHint(hint)
30 | details.text = context.getString(detailsMessage)
31 |
32 | dialog = AlertDialog.Builder(context)
33 | .setTitle(R.string.add_file)
34 | .setView(dialogView)
35 | .setPositiveButton(R.string.next) { _, _ ->
36 | // do not use this, as is dismisses the dialog without validation
37 | // http://stackoverflow.com/questions/11363209/alertdialog-with-positive-button-and-validating-custom-edittext
38 | }
39 | .setNegativeButton(R.string.cancel) { _, _ ->
40 | context.inputMethodManager.hideSoftInputFromWindow(input.windowToken, 0)
41 | }
42 | .create()
43 | }
44 |
45 | override fun onClick(view: View) {
46 | val inputString = input.text.toString()
47 |
48 | if (inputString.isBlank()) {
49 | input.error = valueErrorString
50 | return
51 | }
52 |
53 | if (inputString.contains(" ")) {
54 | input.error = view.context.getString(R.string.no_whitespaces_here)
55 | return
56 | }
57 |
58 | delegate(inputString.trim())
59 |
60 | hide()
61 | }
62 |
63 | fun show() {
64 | input.setText("")
65 | input.error = null
66 |
67 | dialog.show()
68 | dialog.getButton(DialogInterface.BUTTON_POSITIVE).setOnClickListener(this)
69 |
70 | input.requestFocus()
71 | dialog.context.inputMethodManager.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0)
72 | }
73 |
74 | fun hide() {
75 | if (dialog.isShowing) {
76 | dialog.context.inputMethodManager.hideSoftInputFromWindow(input.windowToken, 0)
77 | dialog.dismiss()
78 | }
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/examples/app/demoapp/src/main/res/layout/activity_upload_ftp.xml:
--------------------------------------------------------------------------------
1 |
2 |
13 |
14 |
15 |
19 |
20 |
29 |
30 |
39 |
40 |
41 |
42 |
50 |
51 |
60 |
61 |
68 |
69 |
75 |
76 |
77 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | ## Contents
2 | * [Contributing](#contribute)
3 | * [Issues](#issues)
4 | * [Asking for help and bug reports](#help)
5 |
6 | ### Contributing
7 | * Do you have a new feature in mind?
8 | * Do you know how to improve existing docs or code?
9 | * Have you found a bug?
10 |
11 | Contributions are welcome and encouraged! Just fork the project and then send a pull request. Be ready to discuss your code and design decisions.
12 |
13 | ### Issues
14 | Before opening a new issue, search the existing ones. If an issue is closed and you have the same problem, either reopen the issue or create a new one, filling in all the details required in the issue template. If you don't provide those data, you may not have a response in return for lack of relevant context.
15 |
16 | Bugs are better explained with a test or a demo project. At least with some working code.
17 |
18 | When posting code, logs or stack traces, please use the following Markdown syntax to improve readability:
19 |
20 | ```kotlin
21 | your code, log or stack trace
22 | ```
23 |
24 |
25 |
26 | #### Code Style
27 | Android Upload Service enforces Kotlin standard coding style, using [ktlint](https://ktlint.github.io/).
28 |
29 | To speed up development, it's highly recommended to install ktlint and to execute the following in `android-upload-service` root directory:
30 |
31 | ```
32 | ktlint installGitPreCommitHook
33 | cd examples/app/ && ktlint --android applyToIDEAProject -y && cd ../..
34 | ```
35 | If you are using Atlassian SourceTree to commit, you may encounter the following problem with pre commit hook:
36 |
37 | ```
38 | xargs ktlint: No such file or directory
39 | ```
40 |
41 | To solve it, open `.git/hooks/pre_commit` with your favourite editor and add the following in the second line:
42 |
43 | ```bash
44 | export PATH=/usr/local/bin:$PATH
45 | ```
46 |
47 | #### Development
48 | To develop Android Upload Service and its core modules, clone the project, then open `examples/app/build.gradle` from your Android Studio. In this way you can see all the modules and the demo app, make changes and deploy to your emulator or real device for testing.
49 |
50 | **Working on your first Pull Request?** You can learn how from this *free* series [How to Contribute to an Open Source Project on GitHub](https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github)
51 |
52 | ### Asking for help and bug reports
53 | If you need help because you can't make a successful upload to your server, first check the [troubleshooting procedure](https://github.com/gotev/android-upload-service/wiki/Troubleshooting-Procedure).
54 |
55 | Bug reports without relevant details will be closed. Time is precious for everybody.
56 |
57 | Good and precise bug reports help improve the library fast and make it easier for everybody.
58 |
59 | > Complaints are not useful.
60 |
61 | [Here](http://coenjacobs.me/2013/12/06/effective-bug-reports-on-github/) there's a nice blog post about effective bug reports.
62 | If you already know how to fix the bug, you can directly send a pull request.
63 |
--------------------------------------------------------------------------------
/uploadservice-ftp/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply plugin: 'kotlin-android'
3 | apply plugin: 'kotlin-parcelize'
4 | apply plugin: "org.jlleitschuh.gradle.ktlint"
5 |
6 | // start - do not modify this if your project is on github
7 | project.ext {
8 | mavDevelopers = [(github_username): (maintainer)]
9 | mavSiteUrl = "https://github.com/${github_username}/${github_repository_name}"
10 | mavGitUrl = mavSiteUrl + '.git'
11 | bugTrackerUrl = mavSiteUrl + '/issues/'
12 | mavProjectName = "android-upload-service-ftp"
13 | mavLibraryLicenses = ["Apache-2.0": 'http://www.apache.org/licenses/LICENSE-2.0.txt']
14 | mavLibraryDescription = "FTP Upload implementation for Android Upload Service."
15 | mavVersion = library_version
16 | }
17 | // end - do not modify this if your project is on github
18 |
19 | group = library_project_group
20 | version = library_version
21 |
22 | android {
23 | namespace "net.gotev.uploadservice.ftp"
24 | compileSdkVersion target_sdk
25 |
26 | defaultConfig {
27 | minSdkVersion min_sdk
28 | targetSdkVersion target_sdk
29 | versionCode version_code
30 | versionName library_version
31 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
32 | consumerProguardFiles 'proguard-rules.pro'
33 | }
34 |
35 | buildTypes {
36 | release {
37 | minifyEnabled false
38 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
39 | }
40 | }
41 |
42 | compileOptions {
43 | sourceCompatibility JavaVersion.VERSION_17
44 | targetCompatibility JavaVersion.VERSION_17
45 | }
46 |
47 | lintOptions {
48 | warning 'InvalidPackage'
49 | }
50 | }
51 |
52 | dependencies {
53 | // Testing - https://developer.android.com/training/testing/set-up-project
54 | testImplementation "junit:junit:$junit_version"
55 |
56 | // Core library
57 | androidTestImplementation "androidx.test:core:$androidx_test_core_version"
58 |
59 | // AndroidJUnitRunner and JUnit Rules
60 | androidTestImplementation "androidx.test:runner:$androidx_test_runner_version"
61 | androidTestImplementation "androidx.test:rules:$androidx_test_rules_version"
62 |
63 | // Assertions
64 | androidTestImplementation "androidx.test.ext:junit:$androidx_test_ext_junit_version"
65 | androidTestImplementation "androidx.test.ext:truth:$androidx_test_ext_truth_version"
66 | androidTestImplementation "com.google.truth:truth:$truth_version"
67 |
68 | // Espresso dependencies
69 | androidTestImplementation "androidx.test.espresso:espresso-core:$androidx_test_espresso_version"
70 |
71 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
72 |
73 | api 'commons-net:commons-net:3.10.0'
74 | //api "net.gotev:uploadservice:${version}"
75 | //comment the previous line and uncomment the next line for development (it uses the local lib)
76 | api project(':uploadservice')
77 | }
78 |
79 | apply from: 'https://raw.githubusercontent.com/sky-uk/gradle-maven-plugin/master/gradle-mavenizer.gradle'
80 |
--------------------------------------------------------------------------------
/uploadservice/src/main/java/net/gotev/uploadservice/network/BodyWriter.kt:
--------------------------------------------------------------------------------
1 | package net.gotev.uploadservice.network
2 |
3 | import java.io.Closeable
4 | import java.io.IOException
5 | import java.io.InputStream
6 | import net.gotev.uploadservice.UploadServiceConfig
7 |
8 | abstract class BodyWriter(private val listener: OnStreamWriteListener) : Closeable {
9 |
10 | /**
11 | * Receives the stream write progress and has the ability to cancel it.
12 | */
13 | interface OnStreamWriteListener {
14 | /**
15 | * Indicates if the writing of the stream into the body should continue.
16 | * @return true to continue writing the stream into the body, false to cancel
17 | */
18 | fun shouldContinueWriting(): Boolean
19 |
20 | /**
21 | * Called every time that a bunch of bytes were written to the body
22 | * @param bytesWritten number of written bytes
23 | */
24 | fun onBytesWritten(bytesWritten: Int)
25 | }
26 |
27 | /**
28 | * Writes an input stream to the request body.
29 | * The stream will be automatically closed after successful write or if an exception is thrown.
30 | * @param stream input stream from which to read
31 | * @throws IOException if an I/O error occurs
32 | */
33 | @Throws(IOException::class)
34 | fun writeStream(stream: InputStream) {
35 | val buffer = ByteArray(UploadServiceConfig.bufferSizeBytes)
36 |
37 | stream.use {
38 | while (listener.shouldContinueWriting()) {
39 | val bytesRead = it.read(buffer, 0, buffer.size)
40 | if (bytesRead <= 0) break
41 |
42 | write(buffer, bytesRead)
43 | }
44 | }
45 | }
46 |
47 | /**
48 | * Write a byte array into the request body.
49 | * @param bytes array with the bytes to write
50 | * @throws IOException if an error occurs while writing
51 | */
52 | fun write(bytes: ByteArray) {
53 | internalWrite(bytes)
54 | flush()
55 | listener.onBytesWritten(bytes.size)
56 | }
57 |
58 | /**
59 | * Write a portion of a byte array into the request body.
60 | * @param bytes array with the bytes to write
61 | * @param lengthToWriteFromStart how many bytes to write, starting from the first one in
62 | * the array
63 | * @throws IOException if an error occurs while writing
64 | */
65 | fun write(bytes: ByteArray, lengthToWriteFromStart: Int) {
66 | internalWrite(bytes, lengthToWriteFromStart)
67 | flush()
68 | listener.onBytesWritten(lengthToWriteFromStart)
69 | }
70 |
71 | @Throws(IOException::class)
72 | abstract fun internalWrite(bytes: ByteArray)
73 |
74 | @Throws(IOException::class)
75 | abstract fun internalWrite(bytes: ByteArray, lengthToWriteFromStart: Int)
76 |
77 | /**
78 | * Ensures the bytes written to the body are all transmitted to the server and clears
79 | * the local buffer.
80 | * @throws IOException if an error occurs while flushing the buffer
81 | */
82 | @Throws(IOException::class)
83 | abstract fun flush()
84 | }
85 |
--------------------------------------------------------------------------------