Using Dropbox API to upload a file with Android - android

How can I upload a File (graphic, audio and video file) with Android using the Dropbox API to Dropbox? I followed the tutorial on the Dropbox SDK Android page and could get the sample to work. But now instead of a String I want to upload an actual File object and am struggling.
The sample code works without any problems and looks like this:
String fileContents = "Hello World!";
ByteArrayInputStream inputStream = new ByteArrayInputStream(fileContents.getBytes());
try {
Entry newEntry = mDBApi.putFile("/testing_123456.txt", inputStream, fileContents.length(), null, null);
} catch (DropboxUnlinkedException e) {
Log.e("DbExampleLog", "User has unlinked.");
} catch (DropboxException e) {
Log.e("DbExampleLog", "Something went wrong while uploading.");
}
But when I try to change it and upload an actual file with this code:
File tmpFile = new File(fullPath, "IMG_2012-03-12_10-22-09_thumb.jpg");
// convert File to byte[]
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(tmpFile);
bos.close();
oos.close();
byte[] bytes = bos.toByteArray();
ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
try {
Entry newEntry = mDBApi.putFile("/IMG_2012-03-12_10-22-09_thumb.jpg", inputStream, tmpFile.length(), null, null);
} catch (DropboxUnlinkedException e) {
Log.e("DbExampleLog", "User has unlinked.");
} catch (DropboxException e) {
Log.e("DbExampleLog", "Something went wrong while uploading.");
}
I have no success getting a DropboxException error. I think something where I try to convert the File object to the byte-stream must be wrong but this is just an assumption.
Other than the String example there is nothing else documented on the Dropbox page for Android.
Thanks for any help.

I found the solution - if anyone is interested here is the working code:
private DropboxAPI<AndroidAuthSession> mDBApi;//global variable
File tmpFile = new File(fullPath, "IMG_2012-03-12_10-22-09_thumb.jpg");
FileInputStream fis = new FileInputStream(tmpFile);
try {
DropboxAPI.Entry newEntry = mDBApi.putFileOverwrite("IMG_2012-03-12_10-22-09_thumb.jpg", fis, tmpFile.length(), null);
} catch (DropboxUnlinkedException e) {
Log.e("DbExampleLog", "User has unlinked.");
} catch (DropboxException e) {
Log.e("DbExampleLog", "Something went wrong while uploading.");
}

Here is another implementation of Dropbox API to upload and download a file.
This can be implemented for any type of file.
String file_name = "/my_file.txt";
String file_path = Environment.getExternalStorageDirectory()
.getAbsolutePath() + file_name;
AndroidAuthSession session;
public void initDropBox() {
AppKeyPair appKeys = new AppKeyPair(APP_KEY, APP_SECRET);
session = new AndroidAuthSession(appKeys);
mDBApi = new DropboxAPI<AndroidAuthSession>(session);
mDBApi.getSession().startOAuth2Authentication(MyActivity.this);
}
Entry response;
public void uploadFile() {
writeFileContent(file_path);
File file = new File(file_path);
FileInputStream inputStream = null;
try {
inputStream = new FileInputStream(file);
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
response = mDBApi.putFile("/my_file.txt", inputStream,
file.length(), null, null);
Log.i("DbExampleLog", "The uploaded file's rev is: " + response.rev);
} catch (DropboxException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void downloadFile() {
File file = new File(file_path);
FileOutputStream outputStream = null;
try {
outputStream = new FileOutputStream(file);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
DropboxFileInfo info = null;
try {
info = mDBApi.getFile("/my_file.txt", null, outputStream, null);
Log.i("DbExampleLog", "The file's rev is: "
+ info.getMetadata().rev);
} catch (DropboxException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
if (mDBApi.getSession().authenticationSuccessful()) {
try {
// Required to complete auth, sets the access token on the
// session
mDBApi.getSession().finishAuthentication();
String accessToken = mDBApi.getSession().getOAuth2AccessToken();
/**
* You'll need this token again after your app closes, so it's
* important to save it for future access (though it's not shown
* here). If you don't, the user will have to re-authenticate
* every time they use your app. A common way to implement
* storing keys is through Android's SharedPreferences API.
*/
} catch (IllegalStateException e) {
Log.i("DbAuthLog", "Error authenticating", e);
}
}
}
->Call uploadFile() and downLoadFile() method in child thread otherwise it will give you exception
->For that use AsyncTask and call these above method in doInBackground method.
Hope this will be helpful...Thanks

Here is another example which uses the Dropbox v2 API but a 3rd party SDK. It works exactly the same for Google Drive, OneDrive and Box.com by the way.
// CloudStorage cs = new Box(context, "[clientIdentifier]", "[clientSecret]");
// CloudStorage cs = new OneDrive(context, "[clientIdentifier]", "[clientSecret]");
// CloudStorage cs = new GoogleDrive(context, "[clientIdentifier]", "[clientSecret]");
CloudStorage cs = new Dropbox(context, "[clientIdentifier]", "[clientSecret]");
new Thread() {
#Override
public void run() {
cs.createFolder("/TestFolder"); // <---
InputStream stream = null;
try {
AssetManager assetManager = getAssets();
stream = assetManager.open("UserData.csv");
long size = assetManager.openFd("UserData.csv").getLength();
cs.upload("/TestFolder/Data.csv", stream, size, false); // <---
} catch (Exception e) {
// TODO: handle error
} finally {
// TODO: close stream
}
}
}.start();
It uses the CloudRail Android SDK

#e-nature's answer is more than correct...just thought I'd point everyone to Dropbox's official site that shows how to upload a file and much more.
Also, #e-nature's answer overwrites files with the same name, so if you don't want that behaviour simply use .putFile instead of .putFileOverwrite. .putFile has an extra argument, you can simply add null to to the end. More info.

According to the latest documentation of dropbox API V2:
// Create Dropbox client
val config = DbxRequestConfig.newBuilder("dropbox/java-tutorial").build()
client = DbxClientV2(config, getString(R.string.token))
// Uploading file
FileInputStream(file).use { item ->
val metadata = client.files().uploadBuilder("/${file.absolutePath.substringAfterLast("/")}")
.uploadAndFinish(item)
}
And if you want to overwrite file then add this to client:
.withMode(WriteMode.OVERWRITE)
.uploadAndFinish(item)

Related

Android Core API Download File

I am trying firstly to download the file and its content from Dropbox in Android app using Dropbox Core API but when i execute the following code the app crushes.
EDIT: I have used two functions downloadDropboxFile and copy functions. The problem is that i am getting blank data when i read the local file which is supposed to contain the dropbox file data.
Here is the code where i call the function
downloadDropboxFile("/userandpass.txt");
if (mDBApi.getSession().isLinked())
{
InputStream instream = new FileInputStream(String.valueOf(getExternalCacheDir()) + "/userandpass.txt");
InputStreamReader inputreader = new InputStreamReader(instream);
BufferedReader buffreader = new BufferedReader(inputreader);
mTestOutput.setText(buffreader.readLine());
}
Here is the functions
private boolean downloadDropboxFile(String fileSelected) {
File dir = new File(String.valueOf(getExternalCacheDir()));
if (!dir.exists())
dir.mkdirs();
try {
File localFile = new File(dir + fileSelected);
if (!localFile.exists()) {
localFile.createNewFile();
copy(fileSelected, localFile);
} else {
}
} catch (IOException e) {
e.printStackTrace();
}
return true;
}
private void copy(final String dbPath, final File localFile) {
new Thread(new Runnable() {
#Override
public void run() {
BufferedInputStream br = null;
BufferedOutputStream bw = null;
try {
DropboxAPI.DropboxInputStream fd = mDBApi.getFileStream(dbPath,null);
br = new BufferedInputStream(fd);
bw = new BufferedOutputStream(new FileOutputStream(localFile));
byte[] buffer = new byte[4096];
int read;
while (true) {
read = br.read(buffer);
if (read <= 0) {
break;
}
bw.write(buffer, 0, read);
}
} catch (DropboxException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (bw != null) {
try {
bw.close();
if (br != null) {
br.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}). start();
}
Dropbox Core API Implementation on Android Studio:
On app/libs i have the:
dropbox-android-sdk-1.6.3.jar
httpmime--4.0.3.jar
json_simple-1.1.jar
Your issue is here :
if (!localFile.exists()) {
localFile.createNewFile(); //otherwise dropbox client will fail silently
}
The exception is :
java.io.IOException: open failed: EROFS (Read-only file system)
This means you're trying to create a File on a location that is read only in the phone's memory, I'm guessing the internal storage. Have a look at this excellent answer by Mark Murphy on creating a File based on locations that can be written to.
Hoping this has been of some help, happy coding ;-)

Read a file, if it doesn't exist then create

Honestly, I've searched a lot do this task so I ended up trying various methods but nothing worked until I ended up on this code. It works for me perfectly like it should, so I do not want to change my code.
The help I need is to put this code in a such a way that it begins to read a file, but if it the file doesn't exist then it will create a new file.
Code for saving data:
String data = sharedData.getText().toString();
try {
fos = openFileOutput(FILENAME, MODE_PRIVATE);
fos.write(data.getBytes());
fos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Code for loading data:
FileInputStream fis = null;
String collected = null;
try {
fis = openFileInput(FILENAME);
byte[] dataArray = new byte [fis.available()];
while (fis.read(dataArray) != -1){
collected = new String(dataArray);
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
fis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
So If I add the saving data code in to the "FileNotFoundException" catch of the loading data part then could I achieve what I want?
Add
File file = new File(FILENAME);
if(!file.exists())
{
file.createNewFile()
// write code for saving data to the file
}
above
fis = openFileInput(FILENAME);
This will check if there exists a File for the given FILENAME and if it doesn't it will create a new one.
If you're working on Android, why don't you use the API's solution for saving files?
Quoting:
String filename = "myfile";
String string = "Hello world!";
FileOutputStream outputStream;
try {
outputStream = openFileOutput(filename, Context.MODE_PRIVATE);
outputStream.write(string.getBytes());
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
You should really read the whole document, they explain pretty well the basic ways of creating or accessing files, you can also check the different ways of storing data.
But regarding your original question:
So If I add the saving data code in to the "FileNotFoundException"
catch of the loading data part then could I achieve what I want?
Yes, you could achieve it.
Try this one:
public static void readData() throws IOException
{
File file = new File(path, filename);
if (!file.isFile() && !file.createNewFile()){
throw new IOException("Error creating new file: " + file.getAbsolutePath());
}
BufferedReader r = new BufferedReader(new FileReader(file));
try {
// ...
// read data
// ...
}finally{
r.close();
}
}
Ref: Java read a file, if it doesn't exist create it

Storing a file to internal storage and reading it

What I am trying to do is store a JSON file as a string in internal storage to access it later. The reasoning behind this is to not have to access the server on every request, as this data is constant. Once it is stored once, it doesn't have to be retrieved again unless there is some sort of update. File storage isn't something I've done before, and I was hoping someone could give me a hand. My current code is throwing a null pointer exception at this line:
File file = new File(getFilesDir(), fileName);
My code:
protected String doInBackground(String[] runeId) {
String url = "https://prod.api.pvp.net/api/lol/static-data/" + region + "/v1.2/rune/" + runeId[0] + "?api_key=" + api_key;
JSONParser jsonParser = new JSONParser();
JSONObject runeInfo = jsonParser.getJSONFromUrl(url);
String jsonString = runeInfo.toString();
String fileName = "runeInfo";
File file = new File(getFilesDir(), fileName);
String readJson = null;
if(!runesCached) {
Log.d("Cache", "Caching File");
try {
FileOutputStream os = new FileOutputStream(file);
os.write(jsonString.getBytes());
os.close();
Log.d("Cache", "Cache Complete");
runesCached = true;
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
String name = null;
try {
FileInputStream fis;
File storedRuneInfo = new File(getFilesDir(), fileName);
fis = new FileInputStream(storedRuneInfo);
fis.read(readJson.getBytes());
JSONObject storedJson = new JSONObject(readJson);
try {
name = storedJson.getString("name");
} catch (JSONException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (StreamCorruptedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
return name;
}
}
Try this, instead:
File file = new File(getFilesDir().toString(), fileName);
getFilesDir() returns a File, not a String, which the File class constructor takes as a parameter.
getFilesDir()toString() should return something like /data/data/com.your.app/
EDIT:
This gives the same error. How about:
try {
FileWriter fstream;
BufferedWriter out;
fstream = new FileWriter(getFilesDir() + "/" + "filename");
out = new BufferedWriter(fstream);
out.write(jsonString.getBytes());
out.close();
} catch (Exception e){}

Concatenate two audio files and play resulting file

I am really facing problem from last couple of days but I am not able to find the exact solution please help me.
I want to merge two .mp3 or any audio file and play final single one mp3 file. But when I am combine two file the final file size is ok but when I am trying to play it just play first file, I have tried this with SequenceInputStream or byte array but I am not able to get exact result please help me.
My code is the following:
public class MerginFileHere extends Activity {
public ArrayList<String> audNames;
byte fileContent[];
byte fileContent1[];
FileInputStream ins,ins1;
FileOutputStream fos = null;
String combined_file_stored_path = Environment
.getExternalStorageDirectory().getPath()
+ "/AudioRecorder/final.mp3";
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
audNames = new ArrayList<String>();
String file1 = Environment.getExternalStorageDirectory().getPath()
+ "/AudioRecorder/one.mp3";
String file2 = Environment.getExternalStorageDirectory().getPath()
+ "/AudioRecorder/two.mp3";
File file = new File(Environment.getExternalStorageDirectory()
.getPath() + "/AudioRecorder/" + "final.mp3");
try {
file.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
audNames.add(file1);
audNames.add(file2);
Button btn = (Button) findViewById(R.id.clickme);
btn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
createCombineRecFile();
}
});
}
public void createCombineRecFile() {
// String combined_file_stored_path = // File path in String to store
// recorded audio
try {
fos = new FileOutputStream(combined_file_stored_path, true);
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
File f = new File(audNames.get(0));
File f1 = new File(audNames.get(1));
Log.i("Record Message", "File Length=========>>>" + f.length()+"------------->"+f1.length());
fileContent = new byte[(int) f.length()];
ins = new FileInputStream(audNames.get(0));
int r = ins.read(fileContent);// Reads the file content as byte
fileContent1 = new byte[(int) f1.length()];
ins1 = new FileInputStream(audNames.get(1));
int r1 = ins1.read(fileContent1);// Reads the file content as byte
// from the list.
Log.i("Record Message", "Number Of Bytes Readed=====>>>" + r);
//fos.write(fileContent1);// Write the byte into the combine file.
byte[] combined = new byte[fileContent.length + fileContent1.length];
for (int i = 0; i < combined.length; ++i)
{
combined[i] = i < fileContent.length ? fileContent[i] : fileContent1[i - fileContent.length];
}
fos.write(combined);
//fos.write(fileContent1);*
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
fos.close();
Log.v("Record Message", "===== Combine File Closed =====");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
I already published an app with this function... try my method using SequenceInputStream, in my app I just merge 17 MP3 files in one and play it using the JNI Library MPG123, but I tested the file using MediaPlayer without problems.
This code isn't the best, but it works...
private void mergeSongs(File mergedFile,File...mp3Files){
FileInputStream fisToFinal = null;
FileOutputStream fos = null;
try {
fos = new FileOutputStream(mergedFile);
fisToFinal = new FileInputStream(mergedFile);
for(File mp3File:mp3Files){
if(!mp3File.exists())
continue;
FileInputStream fisSong = new FileInputStream(mp3File);
SequenceInputStream sis = new SequenceInputStream(fisToFinal, fisSong);
byte[] buf = new byte[1024];
try {
for (int readNum; (readNum = fisSong.read(buf)) != -1;)
fos.write(buf, 0, readNum);
} finally {
if(fisSong!=null){
fisSong.close();
}
if(sis!=null){
sis.close();
}
}
}
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
if(fos!=null){
fos.flush();
fos.close();
}
if(fisToFinal!=null){
fisToFinal.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Mp3 files are some frames.
You can concatenate these files by appending the streams to each other if and only if the bit rate and sample rate of your files are same.
If not, the first file plays because it has truly true encoding but the second file can not decode to an true mp3 file.
Suggestion: convert your files with some specific bit rate and sample rate, then use your function.

reading .key file android

I have problem when i try to read a .key file. This file is created by a normal java (J2SE) and i read it from android application. When i read this file from android it gives me nothing and i have done some debugging and i noticed that it can't read the file. Also i have checked if i can read the file (using file.canRead()) and it appears that i can't. Notice that i created normal java application (J2SE) with the same code and it worked successfully.
The code I have used is this:
public KeyPair LoadKeyPair(String algorithm, String publicFileName, String privateFileName) {
// Read Public Key.
PublicKey publicKey = null;
PrivateKey privateKey = null;
try {
File filePublicKey = new File(publicFileName);
FileInputStream fis = new FileInputStream(publicFileName); // The program stops here
byte[] encodedPublicKey = new byte[(int) filePublicKey.length()];
fis.read(encodedPublicKey);
fis.close();
// Read Private Key.
File filePrivateKey = new File(privateFileName);
fis = new FileInputStream(privateFileName);
byte[] encodedPrivateKey = new byte[(int) filePrivateKey.length()];
fis.read(encodedPrivateKey);
fis.close();
// Generate KeyPair.
KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(
encodedPublicKey);
publicKey = keyFactory.generatePublic(publicKeySpec);
PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(
encodedPrivateKey);
privateKey = keyFactory.generatePrivate(privateKeySpec);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvalidKeySpecException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return new KeyPair(publicKey, privateKey);
}
Is a .key file just like a .pem file?
If so, I just do something like this, because PemReader is in BouncyCastleProvider, and THAT is a mess! Too much code for too few things that I want to use
if(mKey==null){
BufferedReader pubFile = new BufferedReader(new InputStreamReader(mCtx.getResources().openRawResource(R.raw.public.pem)));
try {
String line = new String();
StringBuilder key = new StringBuilder();
while((line = pubFile.readLine())!= null){
if(!line.contains("----")){
key.append(line);
}
}
mKey = key.toString();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
pubFile.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
As you can see, I have my public.pem in the res/raw/ folder within my application. Of course, I dont have a .pem with the private key in it. I sign with my public key and verify that the info was signed with a public key made from the private key I keep on my server.
Hope that answers your question and is clear enough.
Did you add in the Manifest the following line?
<uses-permission android:name="android.permission.READ_INTERNAL_STORAGE"/>

Categories

Resources