Skip to content
GitLab
Explore
Sign in
Commits on Source (3)
App name changed, decreased camera resolution, UI change
· ecec1520
Ondra Velínský
authored
Dec 30, 2022
ecec1520
package renamed
· 82988ceb
Ondra Velínský
authored
Dec 30, 2022
82988ceb
Merge branch 'master' into 'main'
· 45697998
Ondra Velínský
authored
Dec 30, 2022
Master See merge request
!2
45697998
Hide whitespace changes
Inline
Side-by-side
app/src/androidTest/java/com/example/dilnacam/ExampleInstrumentedTest.java
0 → 100644
View file @
45697998
package
com.example.webcamupload
;
import
android.content.Context
;
import
androidx.test.platform.app.InstrumentationRegistry
;
import
androidx.test.ext.junit.runners.AndroidJUnit4
;
import
org.junit.Test
;
import
org.junit.runner.RunWith
;
import
static
org
.
junit
.
Assert
.*;
/**
* Instrumented test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith
(
AndroidJUnit4
.
class
)
public
class
ExampleInstrumentedTest
{
@Test
public
void
useAppContext
()
{
// Context of the app under test.
Context
appContext
=
InstrumentationRegistry
.
getInstrumentation
().
getTargetContext
();
assertEquals
(
"com.example.webcamupload"
,
appContext
.
getPackageName
());
}
}
\ No newline at end of file
app/src/main/java/com/example/dilnacam/CameraActivity.java
0 → 100644
View file @
45697998
package
com.example.webcamupload
;
import
static
androidx
.
core
.
content
.
PackageManagerCompat
.
LOG_TAG
;
import
android.annotation.SuppressLint
;
import
android.content.Intent
;
import
android.icu.text.SimpleDateFormat
;
import
android.net.Uri
;
import
android.os.Bundle
;
import
android.os.Environment
;
import
android.os.Handler
;
import
android.util.Log
;
import
android.util.Size
;
import
android.view.Surface
;
import
android.widget.Button
;
import
android.widget.ListView
;
import
android.widget.TextView
;
import
androidx.annotation.NonNull
;
import
androidx.annotation.Nullable
;
import
android.widget.Toast
;
import
androidx.appcompat.app.AppCompatActivity
;
import
androidx.camera.core.Camera
;
import
androidx.camera.core.CameraSelector
;
import
androidx.camera.core.ImageCapture
;
import
androidx.camera.core.ImageCaptureException
;
import
androidx.camera.core.Preview
;
import
androidx.camera.lifecycle.ProcessCameraProvider
;
import
androidx.camera.view.PreviewView
;
import
androidx.core.content.ContextCompat
;
import
androidx.lifecycle.LifecycleOwner
;
import
com.google.common.util.concurrent.ListenableFuture
;
import
com.owncloud.android.lib.common.OwnCloudClient
;
import
com.owncloud.android.lib.common.OwnCloudClientFactory
;
import
com.owncloud.android.lib.common.OwnCloudCredentialsFactory
;
import
com.owncloud.android.lib.common.network.OnDatatransferProgressListener
;
import
com.owncloud.android.lib.common.operations.OnRemoteOperationListener
;
import
com.owncloud.android.lib.common.operations.RemoteOperation
;
import
com.owncloud.android.lib.common.operations.RemoteOperationResult
;
import
com.owncloud.android.lib.resources.files.ReadFolderRemoteOperation
;
import
com.owncloud.android.lib.resources.files.UploadFileRemoteOperation
;
import
com.owncloud.android.lib.resources.files.model.RemoteFile
;
import
java.io.File
;
import
java.util.ArrayList
;
import
java.util.Date
;
import
java.util.Iterator
;
import
java.util.List
;
import
java.util.Locale
;
import
java.util.concurrent.ExecutionException
;
import
java.util.concurrent.Executor
;
import
java.util.concurrent.Executors
;
public
class
CameraActivity
extends
AppCompatActivity
implements
OnRemoteOperationListener
,
OnDatatransferProgressListener
{
private
PreviewView
previewView
;
private
TextView
textView1
;
private
TextView
textView2
;
private
TextView
textView3
;
private
FilesArrayAdapter
mFilesAdapter
;
private
OwnCloudClient
mClient
;
private
Handler
taskHandler
;
private
ImageCapture
imageCapture
;
private
String
lastTimeStamp
;
private
File
imageFile
;
private
final
long
CAPTURE_INTERVAL
=
60000
;
private
final
Executor
executor
=
Executors
.
newSingleThreadExecutor
();
private
final
Runnable
repetitiveTaskRunnable
=
new
Runnable
()
{
public
void
run
()
{
//DO YOUR THINGS
SimpleDateFormat
mDateFormat
=
new
SimpleDateFormat
(
"yyyy-MM-dd-HHmmss"
,
Locale
.
getDefault
());
lastTimeStamp
=
mDateFormat
.
format
(
new
Date
());
textView1
.
setText
(
lastTimeStamp
);
imageFile
=
new
File
(
getBatchDirectoryName
(),
lastTimeStamp
+
".jpg"
);
ImageCapture
.
OutputFileOptions
outputFileOptions
=
new
ImageCapture
.
OutputFileOptions
.
Builder
(
imageFile
).
build
();
imageCapture
.
takePicture
(
outputFileOptions
,
executor
,
new
ImageCapture
.
OnImageSavedCallback
()
{
@Override
public
void
onImageSaved
(
@NonNull
ImageCapture
.
OutputFileResults
outputFileResults
)
{
taskHandler
.
post
(
new
Runnable
()
{
@Override
public
void
run
()
{
Toast
.
makeText
(
getApplicationContext
(),
"Image Saved successfully"
,
Toast
.
LENGTH_SHORT
).
show
();
String
remotePath
=
getString
(
R
.
string
.
remote_folder_path
)
+
"/"
+
imageFile
.
getName
();
startUpload
(
imageFile
,
remotePath
,
getString
(
R
.
string
.
image_mime_type
));
}
});
}
@Override
public
void
onError
(
@NonNull
ImageCaptureException
error
)
{
error
.
printStackTrace
();
}
});
taskHandler
.
postDelayed
(
repetitiveTaskRunnable
,
CAPTURE_INTERVAL
);
}
};
/* https://stackoverflow.com/questions/6242268/repeat-a-task-with-a-time-delay/6242292#6242292
https://stackoverflow.com/questions/1921514/how-to-run-a-runnable-thread-in-android-at-defined-intervals*/
@Override
protected
void
onCreate
(
@Nullable
Bundle
savedInstanceState
)
{
super
.
onCreate
(
savedInstanceState
);
setContentView
(
R
.
layout
.
activity_camera
);
previewView
=
findViewById
(
R
.
id
.
viewFinder
);
textView1
=
findViewById
(
R
.
id
.
textBox1
);
textView2
=
findViewById
(
R
.
id
.
textBox2
);
textView3
=
findViewById
(
R
.
id
.
textBox3
);
mFilesAdapter
=
new
FilesArrayAdapter
(
this
,
R
.
layout
.
file_in_list
);
((
ListView
)
findViewById
(
R
.
id
.
list_view
)).
setAdapter
(
mFilesAdapter
);
taskHandler
=
new
Handler
();
createNextcloudClient
();
startCamera
();
taskHandler
.
postDelayed
(
repetitiveTaskRunnable
,
CAPTURE_INTERVAL
);
startRefresh
();
}
@Override
public
void
onDestroy
()
{
super
.
onDestroy
();
taskHandler
.
removeCallbacks
(
repetitiveTaskRunnable
);
}
private
void
createNextcloudClient
(){
Intent
i
=
getIntent
();
String
usr
=
i
.
getStringExtra
(
"usr"
);
String
psw
=
i
.
getStringExtra
(
"psw"
);
Uri
serverUri
=
Uri
.
parse
(
i
.
getStringExtra
(
"uri"
));
mClient
=
OwnCloudClientFactory
.
createOwnCloudClient
(
serverUri
,
this
,
true
);
mClient
.
setCredentials
(
OwnCloudCredentialsFactory
.
newBasicCredentials
(
usr
,
psw
));
mClient
.
setUserId
(
usr
);
}
private
File
getLastImageFile
()
{
String
localPath
=
Environment
.
getExternalStorageDirectory
().
toString
()
+
"/images/"
+
lastTimeStamp
+
".jpg"
;
return
new
File
(
localPath
);
}
private
void
startCamera
()
{
final
ListenableFuture
<
ProcessCameraProvider
>
cameraProviderFuture
=
ProcessCameraProvider
.
getInstance
(
this
);
cameraProviderFuture
.
addListener
(
new
Runnable
()
{
@Override
public
void
run
()
{
try
{
ProcessCameraProvider
cameraProvider
=
cameraProviderFuture
.
get
();
bindPreview
(
cameraProvider
);
}
catch
(
ExecutionException
|
InterruptedException
e
)
{
// No errors need to be handled for this Future.
// This should never be reached.
}
}
},
ContextCompat
.
getMainExecutor
(
this
));
}
void
bindPreview
(
@NonNull
ProcessCameraProvider
cameraProvider
)
{
Preview
preview
=
new
Preview
.
Builder
().
build
();
CameraSelector
cameraSelector
=
new
CameraSelector
.
Builder
()
.
requireLensFacing
(
CameraSelector
.
LENS_FACING_BACK
)
.
build
();
ImageCapture
.
Builder
builder
=
new
ImageCapture
.
Builder
();
imageCapture
=
builder
.
setTargetRotation
(
Surface
.
ROTATION_90
)
.
setJpegQuality
(
30
)
.
setTargetResolution
(
new
Size
(
1280
,
720
))
.
build
();
preview
.
setSurfaceProvider
(
previewView
.
getSurfaceProvider
());
Camera
camera
=
cameraProvider
.
bindToLifecycle
((
LifecycleOwner
)
this
,
cameraSelector
,
preview
,
imageCapture
);
}
public
String
getBatchDirectoryName
()
{
String
app_folder_path
=
Environment
.
getExternalStorageDirectory
().
toString
()
+
"/images"
;
File
dir
=
new
File
(
app_folder_path
);
if
(!
dir
.
exists
()
&&
!
dir
.
mkdirs
())
{
}
return
app_folder_path
;
}
private
void
startRefresh
()
{
ReadFolderRemoteOperation
refreshOperation
=
new
ReadFolderRemoteOperation
(
""
);
refreshOperation
.
execute
(
mClient
,
this
,
taskHandler
);
}
private
void
startUpload
(
File
fileToUpload
,
String
remotePath
,
String
mimeType
)
{
long
timeStampLong
=
fileToUpload
.
lastModified
()
/
1000
;
String
lastModifiedTimestamp
=
Long
.
toString
(
timeStampLong
);
UploadFileRemoteOperation
uploadOperation
=
new
UploadFileRemoteOperation
(
fileToUpload
.
getAbsolutePath
(),
remotePath
,
mimeType
,
lastModifiedTimestamp
);
uploadOperation
.
addDataTransferProgressListener
(
this
);
uploadOperation
.
execute
(
mClient
,
this
,
taskHandler
);
}
@SuppressLint
(
"RestrictedApi"
)
public
void
onRemoteOperationFinish
(
RemoteOperation
operation
,
RemoteOperationResult
result
)
{
if
(!
result
.
isSuccess
())
{
if
(
operation
instanceof
ReadFolderRemoteOperation
){
Toast
.
makeText
(
this
,
getString
(
R
.
string
.
refresh_failed
),
Toast
.
LENGTH_SHORT
).
show
();
finish
();
}
else
{
Toast
.
makeText
(
this
,
R
.
string
.
todo_operation_finished_in_fail
,
Toast
.
LENGTH_SHORT
).
show
();
Log
.
e
(
LOG_TAG
,
result
.
getLogMessage
(),
result
.
getException
());
}
}
else
if
(
operation
instanceof
ReadFolderRemoteOperation
)
{
Toast
.
makeText
(
this
,
getString
(
R
.
string
.
refresh_successful
),
Toast
.
LENGTH_SHORT
).
show
();
textView3
.
setText
(
"Upload dir: "
+
getString
(
R
.
string
.
remote_folder_path
));
}
else
if
(
operation
instanceof
UploadFileRemoteOperation
)
{
textView2
.
setText
(
lastTimeStamp
+
" Uploaded"
);
imageFile
.
delete
();
}
}
public
void
onTransferProgress
(
long
progressRate
,
long
totalTransferredSoFar
,
long
totalToTransfer
,
String
fileName
)
{
taskHandler
.
post
(
new
Runnable
()
{
@Override
public
void
run
()
{
textView2
.
setText
(
"Uploading: "
+
Long
.
toString
(
totalTransferredSoFar
/
1000
)+
" kB"
);
// do your UI updates about progress here
}
});
}
}
app/src/main/java/com/example/dilnacam/FilesArrayAdapter.java
0 → 100644
View file @
45697998
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2015 ownCloud Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package
com.example.webcamupload
;
import
android.content.Context
;
import
android.view.View
;
import
android.view.ViewGroup
;
import
android.widget.ArrayAdapter
;
import
android.widget.TextView
;
import
com.owncloud.android.lib.resources.files.model.RemoteFile
;
public
class
FilesArrayAdapter
extends
ArrayAdapter
<
RemoteFile
>
{
public
FilesArrayAdapter
(
Context
context
,
int
resource
)
{
super
(
context
,
resource
);
}
public
View
getView
(
int
position
,
View
convertView
,
ViewGroup
parent
)
{
TextView
textView
=
(
TextView
)
super
.
getView
(
position
,
convertView
,
parent
);
textView
.
setText
(
getItem
(
position
).
getRemotePath
());
return
textView
;
}
}
\ No newline at end of file
app/src/main/java/com/example/dilnacam/MainActivity.java
0 → 100644
View file @
45697998
package
com.example.webcamupload
;
import
android.Manifest
;
import
android.content.Context
;
import
android.content.Intent
;
import
android.content.pm.PackageManager
;
import
android.os.Bundle
;
import
android.view.View
;
import
android.widget.Button
;
import
android.widget.EditText
;
import
android.widget.Toast
;
import
androidx.appcompat.app.AppCompatActivity
;
import
androidx.core.app.ActivityCompat
;
import
androidx.core.content.ContextCompat
;
public
class
MainActivity
extends
AppCompatActivity
{
private
static
final
String
[]
CAMERA_PERMISSION
=
new
String
[]{
Manifest
.
permission
.
CAMERA
};
private
static
final
int
CAMERA_REQUEST_CODE
=
10
;
private
static
final
String
[]
STORAGE_PERMISSION
=
new
String
[]{
Manifest
.
permission
.
READ_EXTERNAL_STORAGE
};
int
STORAGE_REQUEST_CODE
=
1
;
private
String
psw
;
private
String
usr
;
private
String
uri
;
@Override
protected
void
onCreate
(
Bundle
savedInstanceState
)
{
super
.
onCreate
(
savedInstanceState
);
setContentView
(
R
.
layout
.
activity_main
);
Button
enableCamera
=
findViewById
(
R
.
id
.
enableCamera
);
enableCamera
.
setOnClickListener
(
new
View
.
OnClickListener
()
{
@Override
public
void
onClick
(
View
v
)
{
EditText
editTextUsr
=
(
EditText
)
findViewById
(
R
.
id
.
editTextUsr
);
EditText
editTextPsw
=
(
EditText
)
findViewById
(
R
.
id
.
editTextPsw
);
usr
=
editTextUsr
.
getText
().
toString
();
psw
=
editTextPsw
.
getText
().
toString
();
uri
=
getString
(
R
.
string
.
server_base_url
);
if
(!
hasCameraPermission
())
{
requestCameraPermission
();
}
else
if
(!
hasStoragePermission
())
{
requestStoragePermission
();
//} else if (!validateCredentials(usr, psw)) {
// showInvalidCredentialsToast();
}
else
{
enableCamera
();
}
}
});
}
private
void
enableCamera
()
{
Intent
i
=
new
Intent
(
this
,
CameraActivity
.
class
);
i
.
putExtra
(
"usr"
,
usr
);
i
.
putExtra
(
"psw"
,
psw
);
i
.
putExtra
(
"uri"
,
uri
);
startActivity
(
i
);
}
private
boolean
hasCameraPermission
()
{
return
ContextCompat
.
checkSelfPermission
(
this
,
Manifest
.
permission
.
CAMERA
)
==
PackageManager
.
PERMISSION_GRANTED
;
}
private
boolean
hasStoragePermission
()
{
return
ContextCompat
.
checkSelfPermission
(
this
,
Manifest
.
permission
.
READ_EXTERNAL_STORAGE
)
==
PackageManager
.
PERMISSION_GRANTED
;
}
private
void
requestCameraPermission
()
{
ActivityCompat
.
requestPermissions
(
this
,
CAMERA_PERMISSION
,
CAMERA_REQUEST_CODE
);
}
private
void
requestStoragePermission
()
{
ActivityCompat
.
requestPermissions
(
this
,
STORAGE_PERMISSION
,
STORAGE_REQUEST_CODE
);
}
private
void
showInvalidCredentialsToast
(){
Context
context
=
getApplicationContext
();
CharSequence
text
=
"Empty credentials"
;
int
duration
=
Toast
.
LENGTH_SHORT
;
Toast
toast
=
Toast
.
makeText
(
context
,
text
,
duration
);
toast
.
show
();
}
private
boolean
validateCredentials
(
String
usr
,
String
psw
)
{
return
usr
!=
null
&&
!
usr
.
trim
().
isEmpty
()
&&
psw
!=
null
&&
!
psw
.
trim
().
isEmpty
();
}
}
\ No newline at end of file
app/src/main/res/drawable/hat.png
0 → 100644
View file @
45697998
169 KiB
app/src/test/java/com/example/dilnacam/ExampleUnitTest.java
0 → 100644
View file @
45697998
package
com.example.webcamupload
;
import
org.junit.Test
;
import
static
org
.
junit
.
Assert
.*;
/**
* Example local unit test, which will execute on the development machine (host).
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
public
class
ExampleUnitTest
{
@Test
public
void
addition_isCorrect
()
{
assertEquals
(
4
,
2
+
2
);
}
}
\ No newline at end of file