Attempt to update Dropbox API from 1.6 to 3.0

This commit is contained in:
Ender's Games 2018-10-02 01:20:11 -04:00
parent 4b24d22385
commit ae7bc65591
6 changed files with 550 additions and 353 deletions

View File

@ -39,8 +39,6 @@ android {
ndk {
moduleName "dc"
abiFilters 'armeabi-v7a', 'x86'
moduleName "sexplay"
abiFilters 'armeabi-v7a', 'x86'
}
}
@ -101,6 +99,7 @@ dependencies {
implementation 'org.bouncycastle:bcprov-jdk16:1.46'
implementation 'commons-io:commons-io:2.6'
implementation 'org.apache.commons:commons-lang3:3.7'
implementation 'com.dropbox.core:dropbox-core-sdk:3.0.9'
implementation ('com.googlecode.json-simple:json-simple:1.1.1') {
exclude module: 'junit'
}

View File

@ -1,350 +0,0 @@
package com.reicast.emulator;
/*
* File: CloudFragment.java
* Author: Luca D'Amico (Luca91)
* Last Edit: 11 May 2014
*
* Reference: http://forums.reicast.com/index.php?topic=160.msg422
*/
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.preference.PreferenceManager;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.Toast;
import com.dropbox.client2.DropboxAPI;
import com.dropbox.client2.DropboxAPI.Entry;
import com.dropbox.client2.android.AndroidAuthSession;
import com.dropbox.client2.exception.DropboxException;
import com.dropbox.client2.session.AccessTokenPair;
import com.dropbox.client2.session.AppKeyPair;
import com.dropbox.client2.session.TokenPair;
import com.reicast.emulator.config.Config;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.concurrent.ExecutionException;
public class CloudFragment extends Fragment {
Button uploadBtn;
Button downloadBtn;
AlertDialog.Builder confirmDialog = null;
boolean actionRequired=false;
public String task = "";
DropBoxClient client = null;
private String home_directory;
String[] vmus = {"vmu_save_A1.bin","vmu_save_A2.bin",
"vmu_save_B1.bin","vmu_save_B2.bin",
"vmu_save_C1.bin","vmu_save_C2.bin",
"vmu_save_D1.bin","vmu_save_D2.bin"};
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.cloud_fragment, container, false);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
SharedPreferences mPrefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
home_directory = mPrefs.getString(Config.pref_home,
Environment.getExternalStorageDirectory().getAbsolutePath());
buttonListener();
confirmDialog = new AlertDialog.Builder(getActivity());
setClient();
}
public void setClient(){
if(client==null)
client = new DropBoxClient(getActivity());
}
public void buttonListener() {
uploadBtn = (Button) getView().findViewById(R.id.uploadBtn);
uploadBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
confirmDialog.setMessage(R.string.uploadWarning);
confirmDialog.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
setClient();
task = "Upload";
client.startLogin();
actionRequired = true;
}
});
confirmDialog.setNegativeButton(R.string.cancel, null);
confirmDialog.show();
}
});
downloadBtn = (Button) getView().findViewById(R.id.downloadBtn);
downloadBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
confirmDialog.setMessage(R.string.downloadWarning);
confirmDialog.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
setClient();
task = "Download";
client.startLogin();
actionRequired = true;
}
});
confirmDialog.setNegativeButton(R.string.cancel, null);
confirmDialog.show();
}
});
}
@Override
public void onResume(){
super.onResume();
if (client.mDBApi != null) {
if (client.mDBApi.getSession().authenticationSuccessful()) {
try {
client.mDBApi.getSession().finishAuthentication();
TokenPair tokens = client.mDBApi.getSession(). getAccessTokenPair();
if(tokens == null)
Toast.makeText(getActivity(), "Failed to save session token!", Toast.LENGTH_SHORT).show();
else
client.storeKeys(tokens.key, tokens.secret);
} catch (IllegalStateException e) {
Log.i("Dropbox", "Error authenticating", e);
}
}
if(actionRequired){
for(int k=0;k<vmus.length;k++){
String result = "";
try {
String vmuPath = home_directory+"/"+vmus[k];
File vmu = new File(vmuPath);
if(vmu.exists() || task.equals("Download") ){
result = new netOperation(client, home_directory).execute(
task,vmuPath,vmus[k]).get();
}
else{
result = "Ok"; // The result is still ok, because the vmu bin doesn't exist ;)
Toast.makeText(getActivity(), vmus[k]+ " doesn't exist, skipping it!",
Toast.LENGTH_SHORT).show();
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
if(result.equals("Ok"))
Toast.makeText(getActivity(), "Task Completed!", Toast.LENGTH_SHORT).show();
else
Toast.makeText(getActivity(), "Task Failed!", Toast.LENGTH_SHORT).show();
}
}
actionRequired = false;
}
}
}
class DropBoxClient {
Context context;
final static private String APP_KEY = "7d7tw1t57sbzrj5";
final static private String APP_SECRET = "5xxqa2uctousyi2";
public DropboxAPI<AndroidAuthSession> mDBApi;
AndroidAuthSession session;
public DropBoxClient(Context context){
this.context = context;
session = buildSession();
mDBApi = new DropboxAPI<AndroidAuthSession>(session);
}
public void startLogin(){
mDBApi.getSession().startOAuth2Authentication(context);
}
public String[] getKeys() {
SharedPreferences prefs = context.getSharedPreferences("ReicastVMUUploader", 0);
String key = prefs.getString("DBoxKey", null);
String secret = prefs.getString("DBoxSecret", null);
if (key != null && secret != null) {
String[] ret = new String[2];
ret[0] = key;
ret[1] = secret;
return ret;
} else {
return null;
}
}
public void storeKeys(String key, String secret) {
SharedPreferences prefs = context.getSharedPreferences("ReicastVMUUploader", 0);
Editor edit = prefs.edit();
edit.putString("DBoxKey", key);
edit.putString("DBoxSecret", secret);
edit.apply();
}
private AndroidAuthSession buildSession() {
AppKeyPair appKeyPair = new AppKeyPair(APP_KEY, APP_SECRET);
AndroidAuthSession session;
String[] stored = getKeys();
if (stored != null) {
AccessTokenPair accessToken = new AccessTokenPair(stored[0], stored[1]);
session = new AndroidAuthSession(appKeyPair, accessToken);
} else {
session = new AndroidAuthSession(appKeyPair);
}
return session;
}
}
class netOperation extends AsyncTask<String, Void, String> {
DropBoxClient client = null;
private String home_directory;
public netOperation(DropBoxClient client, String home_directory){
this.client = client;
this.home_directory = home_directory;
}
public boolean uploadFile(String filePath, String fileName) {
File file = new File(filePath);
FileInputStream inputStream = null;
try {
inputStream = new FileInputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
DropboxAPI.Entry response = null;
try {
response = client.mDBApi.putFileOverwrite("/"+fileName, inputStream, file.length(), null);
} catch (DropboxException e) {
e.printStackTrace();
}
Log.i("FileInfos", "The uploaded file's rev is: "+ response);
return true;
}
public boolean downloadFile(String filePath, String fileName) {
DropboxAPI.DropboxFileInfo info = null;
try {
Entry remoteFile = client.mDBApi.metadata("/"+fileName, 1, null, false, null);
if((remoteFile.rev != null) && (remoteFile.bytes > 0)){ // Avoid to download 0 bytes vmus!
File file = new File(filePath);
if(file.exists())
createBackupOfVmu(fileName);
FileOutputStream out = null;
try {
out = new FileOutputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
info = client.mDBApi.getFile("/"+fileName,null,out,null);
}
} catch (DropboxException e) {
e.printStackTrace();
}
Log.i("FileInfos", "The downloaded file's rev is: "+ info);
return true;
}
@Override
protected void onPostExecute(String result) {
}
@Override
protected String doInBackground(String... strings) {
if(strings[0].equals("Upload")){
if(uploadFile(strings[1],strings[2]))
return "Ok";
else
return "No";
}
else if(strings[0].equals("Download")){
if(downloadFile(strings[1],strings[2]))
return "Ok";
else
return "No";
}
else
return "Unknown";
}
@Override
protected void onPreExecute() {}
@Override
protected void onProgressUpdate(Void... values) {}
void createBackupOfVmu(String vmuName){
File backupDir = new File(home_directory+"/VmuBackups/");
if(!backupDir.exists()) {
backupDir.mkdirs();
}
File source = new File(home_directory+"/"+vmuName);
File destination = new File(home_directory+"/VmuBackups/"+vmuName);
if(!destination.exists()) {
try {
destination.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
try {
InputStream in = new FileInputStream(source);
OutputStream out = new FileOutputStream(destination);
byte[] buffer = new byte[1024];
int length;
while ((length = in.read(buffer)) > 0){
out.write(buffer, 0, length);
}
in.close();
out.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}

View File

@ -20,7 +20,6 @@ import android.support.design.widget.NavigationView;
import android.support.design.widget.Snackbar;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.AppCompatActivity;
@ -41,6 +40,7 @@ import com.reicast.emulator.config.InputFragment;
import com.reicast.emulator.config.OptionsFragment;
import com.reicast.emulator.config.PGConfigFragment;
import com.reicast.emulator.debug.GenerateLogs;
import com.reicast.emulator.dropbox.CloudFragment;
import com.reicast.emulator.emu.JNIdc;
import java.lang.Thread.UncaughtExceptionHandler;

View File

@ -0,0 +1,422 @@
package com.reicast.emulator.dropbox;
/*
* Author: Luca D'Amico (Luca91)
* Rewrite: AbandonedCart
* Last Edit: 02 Oct 2018
* Reference: http://forums.reicast.com/index.php?topic=160.msg422
*/
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.DropBoxManager;
import android.os.Environment;
import android.preference.PreferenceManager;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.Toast;
import com.dropbox.core.DbxException;
import com.dropbox.core.DbxRequestConfig;
import com.dropbox.core.android.Auth;
import com.dropbox.core.http.OkHttp3Requestor;
import com.dropbox.core.v2.DbxClientV2;
import com.dropbox.core.v2.files.FileMetadata;
import com.dropbox.core.v2.files.ListFolderResult;
import com.dropbox.core.v2.files.Metadata;
import com.dropbox.core.v2.files.WriteMode;
import com.reicast.emulator.R;
import com.reicast.emulator.config.Config;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class CloudFragment extends Fragment {
final static private String APP_KEY = "7d7tw1t57sbzrj5";
final static private String APP_SECRET = "5xxqa2uctousyi2";
private String mPath = ""; // Dropbox Path
Button uploadBtn;
Button downloadBtn;
AlertDialog.Builder confirmDialog = null;
private String home_directory;
String[] vmus = {"vmu_save_A1.bin", "vmu_save_A2.bin",
"vmu_save_B1.bin", "vmu_save_B2.bin",
"vmu_save_C1.bin", "vmu_save_C2.bin",
"vmu_save_D1.bin", "vmu_save_D2.bin"};
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.cloud_fragment, container, false);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
SharedPreferences mPrefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
home_directory = mPrefs.getString(Config.pref_home,
Environment.getExternalStorageDirectory().getAbsolutePath());
buttonListener();
confirmDialog = new AlertDialog.Builder(getActivity());
Auth.startOAuth2Authentication(getActivity(), APP_KEY);
}
public void buttonListener() {
uploadBtn = (Button) getView().findViewById(R.id.uploadBtn);
uploadBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
confirmDialog.setMessage(R.string.uploadWarning);
confirmDialog.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
getUriForFiles("Upload");
}
});
confirmDialog.setNegativeButton(R.string.cancel, null);
confirmDialog.show();
}
});
downloadBtn = (Button) getView().findViewById(R.id.downloadBtn);
downloadBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
confirmDialog.setMessage(R.string.downloadWarning);
confirmDialog.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
getUriForFiles("Download");
}
});
confirmDialog.setNegativeButton(R.string.cancel, null);
confirmDialog.show();
}
});
}
private void retrieveFiles(final String vmu) {
final ProgressDialog dialog = new ProgressDialog(getActivity());
dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
dialog.setCancelable(false);
dialog.setMessage("Loading");
dialog.show();
new ListFolderTask(DropboxClientFactory.getClient(), new ListFolderTask.Callback() {
@Override
public void onDataLoaded(ListFolderResult result) {
dialog.dismiss();
for (Metadata item : result.getEntries()) {
if (item.getName().equals(vmu)) {
if (item instanceof FileMetadata) {
downloadFile((FileMetadata) item);
}
}
}
}
@Override
public void onError(Exception e) {
dialog.dismiss();
Log.e(getActivity().getLocalClassName(), "Failed to list folder.", e);
Toast.makeText(getActivity(),
"An error has occurred", Toast.LENGTH_SHORT).show();
}
}).execute(mPath);
}
private void uploadFile(String fileUri) {
final ProgressDialog dialog = new ProgressDialog(getActivity());
dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
dialog.setCancelable(false);
dialog.setMessage("Uploading");
dialog.show();
new UploadFileTask(getActivity(), DropboxClientFactory.getClient(), new UploadFileTask.Callback() {
@Override
public void onUploadComplete(FileMetadata result) {
dialog.dismiss();
}
@Override
public void onError(Exception e) {
dialog.dismiss();
Log.e(getActivity().getLocalClassName(), "Failed to upload file.", e);
Toast.makeText(getActivity(),
"An error has occurred", Toast.LENGTH_SHORT).show();
}
}).execute(fileUri, mPath);
}
private void downloadFile(FileMetadata file) {
final ProgressDialog dialog = new ProgressDialog(getActivity());
dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
dialog.setCancelable(false);
dialog.setMessage("Downloading");
dialog.show();
new DownloadFileTask(getActivity(), DropboxClientFactory.getClient(), new DownloadFileTask.Callback() {
@Override
public void onDownloadComplete(File result) {
dialog.dismiss();
}
@Override
public void onError(Exception e) {
dialog.dismiss();
Log.e(getActivity().getLocalClassName(), "Failed to download file.", e);
Toast.makeText(getActivity(),
"An error has occurred", Toast.LENGTH_SHORT).show();
}
}).execute(file);
}
static class ListFolderTask extends AsyncTask<String, Void, ListFolderResult> {
private final DbxClientV2 mDbxClient;
private final Callback mCallback;
private Exception mException;
public interface Callback {
void onDataLoaded(ListFolderResult result);
void onError(Exception e);
}
public ListFolderTask(DbxClientV2 dbxClient, Callback callback) {
mDbxClient = dbxClient;
mCallback = callback;
}
@Override
protected void onPostExecute(ListFolderResult result) {
super.onPostExecute(result);
if (mException != null) {
mCallback.onError(mException);
} else {
mCallback.onDataLoaded(result);
}
}
@Override
protected ListFolderResult doInBackground(String... params) {
try {
return mDbxClient.files().listFolder(params[0]);
} catch (DbxException e) {
mException = e;
}
return null;
}
}
static class UploadFileTask extends AsyncTask<String, Void, FileMetadata> {
private final Context mContext;
private final DbxClientV2 mDbxClient;
private final Callback mCallback;
private Exception mException;
public interface Callback {
void onUploadComplete(FileMetadata result);
void onError(Exception e);
}
UploadFileTask(Context context, DbxClientV2 dbxClient, Callback callback) {
mContext = context;
mDbxClient = dbxClient;
mCallback = callback;
}
@Override
protected void onPostExecute(FileMetadata result) {
super.onPostExecute(result);
if (mException != null) {
mCallback.onError(mException);
} else if (result == null) {
mCallback.onError(null);
} else {
mCallback.onUploadComplete(result);
}
}
@Override
protected FileMetadata doInBackground(String... params) {
String localUri = params[0];
File localFile = UriHelpers.getFileForUri(mContext, Uri.parse(localUri));
if (localFile != null) {
String remoteFolderPath = params[1];
// Note - this is not ensuring the name is a valid dropbox file name
String remoteFileName = localFile.getName();
try {
InputStream inputStream = new FileInputStream(localFile);
return mDbxClient.files().uploadBuilder(
remoteFolderPath + "/" + remoteFileName)
.withMode(WriteMode.OVERWRITE)
.uploadAndFinish(inputStream);
} catch (DbxException | IOException e) {
mException = e;
}
}
return null;
}
}
static class DownloadFileTask extends AsyncTask<FileMetadata, Void, File> {
private final Context mContext;
private final DbxClientV2 mDbxClient;
private final Callback mCallback;
private Exception mException;
public interface Callback {
void onDownloadComplete(File result);
void onError(Exception e);
}
DownloadFileTask(Context context, DbxClientV2 dbxClient, Callback callback) {
mContext = context;
mDbxClient = dbxClient;
mCallback = callback;
}
@Override
protected void onPostExecute(File result) {
super.onPostExecute(result);
if (mException != null) {
mCallback.onError(mException);
} else {
mCallback.onDownloadComplete(result);
}
}
@Override
protected File doInBackground(FileMetadata... params) {
FileMetadata metadata = params[0];
try {
File path = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DOWNLOADS);
File file = new File(path, metadata.getName());
// Make sure the Downloads directory exists.
if (!path.exists()) {
if (!path.mkdirs()) {
mException = new RuntimeException("Unable to create directory: " + path);
}
} else if (!path.isDirectory()) {
mException = new IllegalStateException("Download path is not a directory: " + path);
return null;
}
// Download the file.
OutputStream outputStream = new FileOutputStream(file);
mDbxClient.files().download(metadata.getPathLower(), metadata.getRev())
.download(outputStream);
// Tell android about the file
Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
intent.setData(Uri.fromFile(file));
mContext.sendBroadcast(intent);
return file;
} catch (DbxException | IOException e) {
mException = e;
}
return null;
}
}
static class DropboxClientFactory {
private static DbxClientV2 sDbxClient;
public static void init(String accessToken) {
if (sDbxClient == null) {
DbxRequestConfig requestConfig = DbxRequestConfig.newBuilder("examples-v2-demo")
.withHttpRequestor(new OkHttp3Requestor(OkHttp3Requestor.defaultOkHttpClient()))
.build();
sDbxClient = new DbxClientV2(requestConfig, accessToken);
}
}
public static DbxClientV2 getClient() {
if (sDbxClient == null) {
throw new IllegalStateException("Client not initialized.");
}
return sDbxClient;
}
}
private void getUriForFiles(String task) {
for (String vmu : vmus) {
File vmuFile = new File(home_directory, vmu);
if (task.equals("Download")) {
if (vmuFile.exists())
createBackupOfVmu(vmuFile.getName());
retrieveFiles(vmuFile.getName());
}
if (task.equals("Upload")) {
uploadFile(Uri.parse(vmuFile.toString()).toString());
}
}
}
void createBackupOfVmu(String vmuName) {
File backupDir = new File(home_directory, "VmuBackups");
if (!backupDir.exists()) {
backupDir.mkdirs();
}
File source = new File(home_directory, vmuName);
File destination = new File(home_directory, "VmuBackups/" + vmuName);
if (!destination.exists()) {
try {
destination.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
try {
InputStream in = new FileInputStream(source);
OutputStream out = new FileOutputStream(destination);
byte[] buffer = new byte[1024];
int length;
while ((length = in.read(buffer)) > 0) {
out.write(buffer, 0, length);
}
in.close();
out.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,126 @@
package com.reicast.emulator.dropbox;
import android.annotation.TargetApi;
import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import java.io.File;
import java.lang.annotation.Target;
/**
* Utility functions to support Uri conversion and processing.
*/
public final class UriHelpers {
private UriHelpers() {}
/**
* Get the file path for a uri. This is a convoluted way to get the path for an Uri created using the
* StorageAccessFramework. This in no way is the official way to do this but there does not seem to be a better
* way to do this at this point. It is taken from https://github.com/iPaulPro/aFileChooser.
*
* @param context The context of the application
* @param uri The uri of the saved file
* @return The file with path pointing to the saved file. It can return null if we can't resolve the uri properly.
*/
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public static File getFileForUri(final Context context, final Uri uri) {
String path = null;
// DocumentProvider
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN
&& DocumentsContract.isDocumentUri(context, uri)) {
// ExternalStorageProvider
if (isExternalStorageDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
if ("primary".equalsIgnoreCase(type)) {
path = Environment.getExternalStorageDirectory() + "/" + split[1];
}
} else if (isDownloadsDocument(uri)) {
// DownloadsProvider
final String id = DocumentsContract.getDocumentId(uri);
final Uri contentUri = ContentUris
.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
path = getDataColumn(context, contentUri, null, null);
} else if (isMediaDocument(uri)) {
// MediaProvider
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
Uri contentUri = null;
if ("image".equals(type)) {
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
} else if ("video".equals(type)) {
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
} else if ("audio".equals(type)) {
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
}
final String selection = "_id=?";
final String[] selectionArgs = new String[] {
split[1]
};
path = getDataColumn(context, contentUri, selection, selectionArgs);
}
} else if ("content".equalsIgnoreCase(uri.getScheme())) {
// MediaStore (and general)
path = getDataColumn(context, uri, null, null);
} else if ("file".equalsIgnoreCase(uri.getScheme())) {
// File
path = uri.getPath();
}
if (path != null) {
return new File(path);
}
return null;
}
private static String getDataColumn(Context context, Uri uri, String selection,
String[] selectionArgs) {
Cursor cursor = null;
final String column = "_data";
final String[] projection = {
column
};
try {
cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
null);
if (cursor != null && cursor.moveToFirst()) {
final int column_index = cursor.getColumnIndexOrThrow(column);
return cursor.getString(column_index);
}
} finally {
if (cursor != null) {
cursor.close();
}
}
return null;
}
private static boolean isExternalStorageDocument(Uri uri) {
return "com.android.externalstorage.documents".equals(uri.getAuthority());
}
private static boolean isDownloadsDocument(Uri uri) {
return "com.android.providers.downloads.documents".equals(uri.getAuthority());
}
private static boolean isMediaDocument(Uri uri) {
return "com.android.providers.media.documents".equals(uri.getAuthority());
}
}