cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Announcements
Share your feedback on the Document Scanning Experience in the Dropbox App right here.

Dropbox API Support & Feedback

Find help with the Dropbox API from other developers.

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Re: my android app not uploading photo directly to Dropbox app folder using API

my android app not uploading photo directly to Dropbox app folder using API

Ghost Mjrm
Explorer | Level 4

i have created android app and i add the API and the SDK to it to contact with my Dropbox app folder to automatically uploading photo

but its tell me that the photo uploaded successfully but when i check the Dropbox app i cannot find any photo

this is my app code included the authentication method that i used

package com.example.decamera;

import android.Manifest;
import android.content.pm.PackageManager;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;
import android.net.Uri;
import android.util.Log;



import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
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.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.lifecycle.LifecycleOwner;

import com.dropbox.core.DbxRequestConfig;
import com.dropbox.core.v2.files.FileMetadata;
import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.common.util.concurrent.ListenableFuture;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

private static final int CAMERA_PERMISSION_REQUEST = 100;
private static final int LOCATION_PERMISSION_REQUEST = 101;
private static final String[] REQUIRED_CAMERA_PERMISSIONS = new String[]{Manifest.permission.CAMERA};
private static final String[] REQUIRED_LOCATION_PERMISSIONS = new String[]{Manifest.permission.ACCESS_FINE_LOCATION};

private PreviewView previewView;
private ImageCapture imageCapture;
private TextView addressTextView;

private ExecutorService cameraExecutor = Executors.newSingleThreadExecutor();
private FusedLocationProviderClient fusedLocationProviderClient;
private Geocoder geocoder;

// Dropbox variables
private static final String ACCESS_TOKEN = "my access token";

private DbxRequestConfig config;
private com.dropbox.core.v2.DbxClientV2 dropboxClient;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

previewView = findViewById(R.id.previewView);
ImageButton captureButton = findViewById(R.id.captureButton);
addressTextView = findViewById(R.id.addressTextView);

fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);
geocoder = new Geocoder(this, Locale.getDefault());

// Initialize Dropbox variables
config = DbxRequestConfig.newBuilder("de_camera_app").build();
dropboxClient = new com.dropbox.core.v2.DbxClientV2(config, ACCESS_TOKEN);

captureButton.setOnClickListener(this);

if (allPermissionsGranted()) {
startCamera();
getLastLocation();
} else {
ActivityCompat.requestPermissions(this, REQUIRED_CAMERA_PERMISSIONS, CAMERA_PERMISSION_REQUEST);
}
}

private void startCamera() {
ListenableFuture<ProcessCameraProvider> cameraProviderFuture = ProcessCameraProvider.getInstance(this);

cameraProviderFuture.addListener(() -> {
try {
ProcessCameraProvider cameraProvider = cameraProviderFuture.get();
bindPreview(cameraProvider);

} catch (Exception e) {
e.printStackTrace();
}
}, ContextCompat.getMainExecutor(this));
}

private void bindPreview(ProcessCameraProvider cameraProvider) {
Preview preview = new Preview.Builder().build();

CameraSelector cameraSelector = new CameraSelector.Builder()
.requireLensFacing(CameraSelector.LENS_FACING_BACK)
.build();

Camera camera = cameraProvider.bindToLifecycle((LifecycleOwner) this, cameraSelector, preview);

preview.setSurfaceProvider(previewView.getSurfaceProvider());

imageCapture = new ImageCapture.Builder()
.setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
.setTargetRotation(previewView.getDisplay().getRotation()) // Add this line
.build();

// Re-bind use cases to the camera
cameraProvider.unbindAll();
cameraProvider.bindToLifecycle((LifecycleOwner) this, cameraSelector, preview, imageCapture);
}

private void getLastLocation() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
fusedLocationProviderClient.getLastLocation()
.addOnSuccessListener(this, new OnSuccessListener<Location>() {
@Override
public void onSuccess(Location location) {
if (location != null) {
updateAddress(location);
}
}
});
} else {
// Request location permission
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, LOCATION_PERMISSION_REQUEST);
}
}

private void updateAddress(Location location) {
try {
List<Address> addresses = geocoder.getFromLocation(location.getLatitude(), location.getLongitude(), 1);
if (addresses != null && addresses.size() > 0) {
Address address = addresses.get(0);
String fullAddress = address.getAddressLine(0);
addressTextView.setText(fullAddress);
}
} catch (IOException e) {
e.printStackTrace();
}
}

@Override
public void onClick(View v) {
if (v.getId() == R.id.captureButton) {
captureAndUploadToDropbox(); // Call the new method
}
}

private void captureAndUploadToDropbox() {
// Capture the image and directly upload it to Dropbox
ImageCapture.OutputFileOptions outputFileOptions =
new ImageCapture.OutputFileOptions.Builder(createImageFile()).build();

imageCapture.takePicture(outputFileOptions, ContextCompat.getMainExecutor(this), new ImageCapture.OnImageSavedCallback() {
@Override
public void onImageSaved(@Nullable ImageCapture.OutputFileResults outputFileResults) {
Uri savedUri = outputFileResults.getSavedUri();

if (savedUri != null) {
File savedPhoto = new File(savedUri.getPath());

// Upload the photo to Dropbox
uploadToDropbox(savedPhoto);

// Notify the user
runOnUiThread(() -> Toast.makeText(MainActivity.this, "Photo saved and uploaded successfully", Toast.LENGTH_SHORT).show());
} else {
runOnUiThread(() -> Toast.makeText(MainActivity.this, "Error getting saved file URI", Toast.LENGTH_SHORT).show());
}
}

@Override
public void onError(@NonNull ImageCaptureException exception) {
runOnUiThread(() -> Toast.makeText(MainActivity.this, "Error capturing image: " + exception.getMessage(), Toast.LENGTH_SHORT).show());
}
});
}


private void uploadToDropbox(File photoFile) {
try {
// Get the file name
String fileName = photoFile.getName();

// Log the file path before upload
Log.d("DropboxUpload", "Uploading file: " + photoFile.getAbsolutePath());

// Open the photo file
FileInputStream fis = new FileInputStream(photoFile);

// Specify the remote path on Dropbox where you want to upload the file
String remotePath = "/Apps/Bau" + fileName; // Replace "Bau" with your desired folder name

// Upload the photo file
FileMetadata metadata = dropboxClient.files().uploadBuilder(remotePath)
.uploadAndFinish(fis);

// You can handle the metadata response if needed
// metadata.getName(), metadata.getSize(), etc.

runOnUiThread(() -> Toast.makeText(MainActivity.this, "Photo uploaded to Dropbox successfully", Toast.LENGTH_SHORT).show());
} catch (Exception e) {
e.printStackTrace();
runOnUiThread(() -> Toast.makeText(MainActivity.this, "Error uploading to Dropbox: " + e.getMessage(), Toast.LENGTH_SHORT).show());
}
}


private File createImageFile() {
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);

try {
if (storageDir != null) {
return File.createTempFile(imageFileName, ".jpg", storageDir);
} else {
runOnUiThread(() -> Toast.makeText(MainActivity.this, "Error creating storage directory", Toast.LENGTH_SHORT).show());
}
} catch (IOException e) {
e.printStackTrace();
runOnUiThread(() -> Toast.makeText(MainActivity.this, "Error creating photo file", Toast.LENGTH_SHORT).show());
}

return null;
}

private boolean allPermissionsGranted() {
for (String permission : REQUIRED_CAMERA_PERMISSIONS) {
if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {
return false;
}
}
return true;
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);

if (requestCode == CAMERA_PERMISSION_REQUEST) {
if (allPermissionsGranted()) {
startCamera();
getLastLocation();
} else {
runOnUiThread(() -> Toast.makeText(this, "Camera permissions not granted.", Toast.LENGTH_SHORT).show());
finish();
}
} else if (requestCode == LOCATION_PERMISSION_REQUEST) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
getLastLocation();
} else {
runOnUiThread(() -> Toast.makeText(this, "Location permissions not granted.", Toast.LENGTH_SHORT).show());
}
}
}
}

 

16 Replies 16

Ghost Mjrm
Explorer | Level 4

one more thing i got error upload to Dropbox:null and i didn't find the solution yet so i considered that if i make the refresh token doesn't expire it could fix my problem

Здравко
Legendary | Level 20

More details about that error would be useful. It's not clear what doesn't work for you actually. The refresh token will just 'extend' your authentication 'life' (if could be said so), nothing more.

Greg-DB
Dropbox Staff

@Ghost Mjrm As Здравко said, it's unclear what the issue is from the information you've provided. If you're having trouble with the Dropbox API, please troubleshoot the issue in your environment and if you need help, share the relevant specific details.

 

For example, I see you are calling uploadAndFinish to upload a file. I suggest adding some more logging and/or stepping through with a debugger to inspect what is happening. For example, check if uploadAndFinish is returning a value, and if so, what it is, or if it's raising an exception, and if so, what it is.

Ghost Mjrm
Explorer | Level 4

using logcat i got this system error

W/System.err: android.os.NetworkOnMainThreadException
at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1513)
at java.net.Inet6AddressImpl.lookupHostByName(Inet6AddressImpl.java:117)
at java.net.Inet6AddressImpl.lookupAllHostAddr(Inet6AddressImpl.java:105)
at java.net.InetAddress.getAllByName(InetAddress.java:1154)
at com.android.okhttp.Dns$1.lookup(Dns.java:39)
at com.android.okhttp.internal.http.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:196)
at com.android.okhttp.internal.http.RouteSelector.nextProxy(RouteSelector.java:144)
at com.android.okhttp.internal.http.RouteSelector.next(RouteSelector.java:89)
at com.android.okhttp.internal.http.StreamAllocation.findConnection(StreamAllocation.java:190)
at com.android.okhttp.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:142)
at com.android.okhttp.internal.http.StreamAllocation.newStream(StreamAllocation.java:104)
at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:392)
at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:325)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:488)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:131)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getOutputStream(HttpURLConnectionImpl.java:262)
at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getOutputStream(DelegatingHttpsURLConnection.java:218)
at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:26)
at com.dropbox.core.http.StandardHttpRequestor.getOutputStream(StandardHttpRequestor.java:132)
at com.dropbox.core.http.StandardHttpRequestor.access$000(StandardHttpRequestor.java:29)
at com.dropbox.core.http.StandardHttpRequestor$Uploader.<init>(StandardHttpRequestor.java:141)
at com.dropbox.core.http.StandardHttpRequestor.startPostInStreamingMode(StandardHttpRequestor.java:81)
at com.dropbox.core.http.StandardHttpRequestor.startPostInStreamingMode(StandardHttpRequestor.java:29)
at com.dropbox.core.v2.DbxRawClientV2.uploadStyle(DbxRawClientV2.java:286)
at com.dropbox.core.v2.files.DbxUserFilesRequests.upload(DbxUserFilesRequests.java:3795)
at com.dropbox.core.v2.files.UploadBuilder.start(UploadBuilder.java:154)
at com.dropbox.core.v2.files.UploadBuilder.start(UploadBuilder.java:20)
at com.dropbox.core.v2.DbxUploadStyleBuilder.uploadAndFinish(DbxUploadStyleBuilder.java:92)
at com.example.decamera.MainActivity.uploadToDropbox(MainActivity.java:277)
at com.example.decamera.MainActivity.access$300(MainActivity.java:57)
at com.example.decamera.MainActivity$2.onImageSaved(MainActivity.java:173)
at androidx.camera.core.imagecapture.TakePictureRequest.lambda$onResult$1$androidx-camera-core-imagecapture-TakePictureRequest(TakePictureRequest.java:192)
at androidx.camera.core.imagecapture.TakePictureRequest$$ExternalSyntheticLambda0.run(Unknown Source:4)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7078)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:964)

Ghost Mjrm
Explorer | Level 4

NetworkOnMainThreadException. I've added an AsyncTask for Dropbox upload and the problem got fixed 

thanks

now i want to add offline access token that doesn´t expire

Greg-DB
Dropbox Staff

I'm glad to hear you've sorted out the issue with the NetworkOnMainThreadException.

 

For information on using refresh tokens, please refer to the resources in my earlier response.

Ghost Mjrm
Explorer | Level 4
Need more support?