Need to see if your shared folder is taking up space on your dropbox 👨💻? Find out how to check here.
Forum Discussion
Ghost Mjrm
3 years agoExplorer | Level 4
How can i get lifetime Access Token
i have android app connected to my Dropbox folder using access token but every 4 hour should i edit my code and input the new access token is there any method to make the app working 24h without any interact from me
and fix the message that show access token error uploading to Dropbox: expired access token
private void uploadToDropbox(File photoFile) {
if (photoFile == null || !photoFile.exists()) {
runOnUiThread(() -> Toast.makeText(MainActivity.this, "Error: Photo file does not exist", Toast.LENGTH_SHORT).show());
return;
}
DbxRequestConfig config = DbxRequestConfig.newBuilder("Decamera").build();
DbxClientV2 client = new DbxClientV2(config, DROPBOX_ACCESS_TOKEN);
try {
String remotePath = "/Decamera/" + photoFile.getName();
try (InputStream in = new FileInputStream(photoFile)) {
client.files().uploadBuilder(remotePath)
.withMode(WriteMode.ADD)
.uploadAndFinish(in);
runOnUiThread(() -> Toast.makeText(MainActivity.this, "Photo uploaded to Dropbox", 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 static final String DROPBOX_ACCESS_TOKEN = my access token
Ghost Mjrm, Be more careful when inspecting the code.
Ghost Mjrm wrote:
... there is no offline ...Hm..🤔 Let's see where the OAuth starts here and what actually gets executed here. 🧐 Are you still thinking "there is no offline"? 🙂
Ghost Mjrm wrote:
... or refresh token exampleLet's see where OAuth finish here and what actually it executes here. Ahhh... where was this refresh token... 😉
Keep more attention on code reading.
41 Replies
Replies have been turned off for this discussion
- Здравко2 years agoLegendary | Level 20
Ghost Mjrm wrote:...
error 400 invalid redirect_uri. when response_type=code without PKCE,redirect_uri must start with "https://", unless its a localhost URI
Ghost Mjrm, you posted already the answer of your question (part of error message). To be able set scheme different than "https" (or similar) you need PKCE auth flow (something you skipped). 😉 That's it - forget about app secret; focus on code challenge and code verifier (parts of PKCE).
PS: Why don't you use the SDK as is (including authentication) and skip re-implementing something already existing there? 🤷
- Ghost Mjrm2 years agoExplorer | Level 4
yeah i have noticed it but honestly i don't know what PKCE mean but i will search about it
but im little bit confuse should i create a input key that can the user insert in it the obtained access token to success the upload to dropbox operation or is there another way that the app automatically read it form the browser and use it
i already have this mechanism in my code but it dont know if it work
i told you im little bit confused and i don't get the complete idea or redirected url so i used ChatGPT To make to me this mechanism so can you please check my code if it good? >:
i just want when the user click on the corner button to start oAuth 2 operation and get access token then my app use this access token to upload the photo to dropbox
Best Regards
- Здравко2 years agoLegendary | Level 20
Ghost Mjrm wrote:...
i just want when the user click on the corner button to start oAuth 2 operation and get access token then my app use this access token to upload the photo to dropbox
...
If you get access token directly then this token will expire in 4 hours or so. So you go beck at the beginning.
Ghost Mjrm wrote:yeah i have noticed it but honestly i don't know what PKCE mean but i will search about it
...
PKCE is an alternative way to perform OAuth flow, nothing more. Instead of using app secret, dynamic pair of keys is used (code challenge and code verifier). One is passed in OAuth initiation and other in token receiving (something that guarantees avoid "man in middle" - the same thing what app secret does - just more secure way). 🤫 That's it.
As the message shows, your code is erroneous. You don't need any additional "input key" (whatever it means). Don't rely on AI, but rather on your own intelligence and don't be lazy in reading documentation. 😉😁 AI (of any kind) is NOT so intelligent yet (might become some day but not now).
- Ghost Mjrm2 years agoExplorer | Level 4Ok bro thanks a lot
- Ghost Mjrm2 years agoExplorer | Level 4
there is my main code
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private static final int CAMERA_PERMISSION_REQUEST = 100;
private static final String[] REQUIRED_CAMERA_PERMISSIONS = new String[]{Manifest.permission.CAMERA};
private static final String DROPBOX_APP_KEY = "hc2p6uj44p9pyoc";
private static final String DROPBOX_APP_SECRET = "i cannot show this";
private static final String DROPBOX_REDIRECT_URI = "https://auth-finish";
private String DROPBOX_ACCESS_TOKEN = null;
private PreviewView previewView;
private ImageCapture imageCapture;
private TextView addressTextView;
private ExecutorService cameraExecutor = Executors.newSingleThreadExecutor();
private FusedLocationProviderClient fusedLocationProviderClient;
private Geocoder geocoder;
// Add latitude and longitude variables
private double latitudeValue;
private double longitudeValue;
@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);
ImageButton leftCornerButton = findViewById(R.id.leftCornerButton);
addressTextView = findViewById(R.id.addressTextView);
fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);
geocoder = new Geocoder(this, Locale.getDefault());
captureButton.setOnClickListener(this);
leftCornerButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
initiateDropboxAuthorization();
}
});
addressTextView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showEditAddressDialog();
}
});
if (allPermissionsGranted()) {
startCamera();
getLastLocation();
} else {
ActivityCompat.requestPermissions(this, REQUIRED_CAMERA_PERMISSIONS, CAMERA_PERMISSION_REQUEST);
}
// Initialize Dropbox access token if available
SharedPreferences prefs = getPreferences(Context.MODE_PRIVATE);
DROPBOX_ACCESS_TOKEN = prefs.getString("dropboxAccessToken", null);
// Check if the app was opened with a Dropbox authorization callback
handleDropboxAuthorizationCallback(getIntent());
}
// Override onNewIntent to handle the Dropbox authorization callback
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
// Log the received intent data for debugging
Log.d("Dropbox", "Received new intent: " + intent);
// Extract and log the data URI
Uri data = intent.getData();
Log.d("Dropbox", "Intent data URI: " + data);
if (data != null && data.toString().startsWith(DROPBOX_REDIRECT_URI)) {
// Authorization successful, extract the authorization code
String code = data.getQueryParameter("code");
// Log the authorization code for debugging
Log.d("Dropbox", "Authorization Code: " + code);
// Now, exchange the authorization code for an access token and refresh token
exchangeAuthorizationCodeForTokens(code);
}
}
private void initiateDropboxAuthorization() {
// Construct the Dropbox authorization URL
String authorizationUrl = "https://www.dropbox.com/oauth2/authorize" +
"?client_id=" + DROPBOX_APP_KEY +
"&response_type=code" +
"&token_access_type=offline" +
"&state=myState" + // Replace with your own state
"&redirect_uri=" + DROPBOX_REDIRECT_URI;
// Open the authorization URL in a web browser or WebView
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(authorizationUrl));
startActivity(browserIntent);
}
private String performPostRequest(String requestUrl, String urlParameters) {
try {
URL url = new URL(requestUrl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.setRequestProperty("Content-Length", Integer.toString(urlParameters.getBytes().length));
connection.setDoOutput(true);
// Log the request details
Log.d("Dropbox", "POST Request URL: " + requestUrl);
Log.d("Dropbox", "POST Request Body: " + urlParameters);
// Write the request body
try (DataOutputStream wr = new DataOutputStream(connection.getOutputStream())) {
wr.writeBytes(urlParameters);
wr.flush();
}
// Get the response
try (InputStream is = connection.getInputStream();
BufferedReader rd = new BufferedReader(new InputStreamReader(is))) {
StringBuilder response = new StringBuilder();
String line;
while ((line = rd.readLine()) != null) {
response.append(line);
response.append('\r');
}
// Log the response
Log.d("Dropbox", "POST Response: " + response.toString());
return response.toString();
}
} catch (Exception e) {
// Log any exceptions
Log.e("Dropbox", "Error in HTTP request: " + e.getMessage());
return null;
}
}
private void handleDropboxAuthorizationCallback(Intent intent) {
// Log the received intent for debugging
Log.d("Dropbox", "Handling Dropbox Authorization Callback Intent: " + intent);
Uri data = intent.getData();
if (data != null && data.toString().startsWith(DROPBOX_REDIRECT_URI)) {
// Authorization successful, extract the authorization code
String code = data.getQueryParameter("code");
// Log the authorization code for debugging
Log.d("Dropbox", "Authorization Code: " + code);
// Now, exchange the authorization code for an access token and refresh token
exchangeAuthorizationCodeForTokens(code);
} else {
// Log a message if the intent data is unexpected
Log.d("Dropbox", "Invalid Dropbox Authorization Callback Intent Data: " + data);
}
}
private void exchangeAuthorizationCodeForTokens(String code) {
new AsyncTask<String, Void, Void>() {
@Override
protected Void doInBackground(String... params) {
try {
String url = "https://api.dropbox.com/oauth2/token";
String requestBody = "code=" + params[0] +
"&grant_type=authorization_code" +
"&client_id=" + DROPBOX_APP_KEY +
"&client_secret=" + DROPBOX_APP_SECRET +
"&redirect_uri=" + DROPBOX_REDIRECT_URI;
// Log the request details
Log.d("Dropbox", "Token Exchange Request URL: " + url);
Log.d("Dropbox", "Token Exchange Request Body: " + requestBody);
// Perform the POST request and obtain the JSON response
String jsonResponse = performPostRequest(url, requestBody);
// Log the response
Log.d("Dropbox", "Token Exchange Response: " + jsonResponse);
// Parse the JSON response to extract access and refresh tokens
JSONObject jsonObject = new JSONObject(jsonResponse);
DROPBOX_ACCESS_TOKEN = jsonObject.getString("access_token");
// Log the obtained access token
Log.d("Dropbox", "Access Token Obtained: " + DROPBOX_ACCESS_TOKEN);
// Save the Dropbox access token
SharedPreferences prefs = getPreferences(Context.MODE_PRIVATE);
prefs.edit().putString("dropboxAccessToken", DROPBOX_ACCESS_TOKEN).apply();
} catch (Exception e) {
// Log any exceptions
Log.e("Dropbox", "Error in token exchange: " + e.getMessage());
}
return null;
}
}.execute(code);
}private void uploadToDropbox(File photoFile) {
if (photoFile == null || !photoFile.exists()) {
runOnUiThread(() -> Toast.makeText(MainActivity.this, "Error: Photo file does not exist", Toast.LENGTH_SHORT).show());
return;
}
if (DROPBOX_ACCESS_TOKEN == null) {
runOnUiThread(() -> Toast.makeText(MainActivity.this, "Error: Dropbox access token is null", Toast.LENGTH_SHORT).show());
return;
}
DbxRequestConfig config = DbxRequestConfig.newBuilder("Decamera").build();
DbxClientV2 client = new DbxClientV2(config, DROPBOX_ACCESS_TOKEN);
try {
String remotePath = "/Decamera/" + photoFile.getName();
try (InputStream in = new FileInputStream(photoFile)) {
FileMetadata metadata = client.files().uploadBuilder(remotePath)
.withMode(WriteMode.ADD)
.uploadAndFinish(in);
runOnUiThread(() -> {
Toast.makeText(MainActivity.this, "Photo uploaded to Dropbox", Toast.LENGTH_SHORT).show();
// Log metadata information
Log.d("Dropbox", "File uploaded. Metadata: " + metadata.toString());
});
}
} catch (Exception e) {
e.printStackTrace();
runOnUiThread(() -> Toast.makeText(MainActivity.this, "Error uploading to Dropbox: " + e.getMessage(), Toast.LENGTH_SHORT).show());
}
} - Здравко2 years agoLegendary | Level 20
Hm..🤔 Are you still trying some sort of AI? 🧐 Ghost Mjrm, come on... 😁 I believe you have your own; use it! 😉
- Ghost Mjrm2 years agoExplorer | Level 4
im not using ai just to copy paste its help to understand the main code to how to exchange authorized code with access token using the app key and app secret and teach me to constructor the link and make post and request method im not using it blindly and its help to create log statments to dedicate the error in the logcat its a powerful but at the end i got upload to dropbox success message but and im 100% sure that the Decamera folder name is correct and app key app secret correct so where is the problem i cannot find it
- Здравко2 years agoLegendary | Level 20
Ghost Mjrm wrote:... so where is the problem i cannot find it
Ah..🙋 If that's fine for you, you can use it in such a way, of course. In such a case you can remove the "offline" declaration for the access type since you're not using it in fact. So big part of entire discussion seems meaningless - you don't need long term access since the posted cover your demands. 🙂 Ok, all done.
- Ghost Mjrm2 years agoExplorer | Level 4Thank you for your support
- Ghost Mjrm2 years agoExplorer | Level 4
i have remove the offline access type and same problem successfully upload to dropbox but there is no nothing in the dropbox app
private void initiateDropboxAuthorization() {
// Construct the Dropbox authorization URL
String authorizationUrl = "https://www.dropbox.com/oauth2/authorize" +
"?client_id=" + DROPBOX_APP_KEY +
"&response_type=code" +
"&state=myState" + // Replace with your own state
"&redirect_uri=" + DROPBOX_REDIRECT_URI;
// Open the authorization URL in a web browser or WebView
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(authorizationUrl));
startActivity(browserIntent);
}
About Dropbox API Support & Feedback
Find help with the Dropbox API from other developers.
The Dropbox Community team is active from Monday to Friday. We try to respond to you as soon as we can, usually within 2 hours.
If you need more help you can view your support options (expected response time for an email or ticket is 24 hours), or contact us on X, Facebook or Instagram.
For more info on available support options for your Dropbox plan, see this article.
If you found the answer to your question in this Community thread, please 'like' the post to say thanks and to let us know it was useful!