Skip to content
Commits on Source (3)
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
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
}
});
}
}
/* 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
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
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