我创建了一个应用程序,为用户提供上传和下载Dropbox应用程序的选项。我给我的应用程序秘密和应用程序密钥。问题是,当其他人使用我的应用程序时,他们需要输入他们的应用程序密钥和应用程序密钥吗? 如果有,为什么?如果没有,那么应用秘密和app密钥的实际目的是什么。我也在分享代码:
上传文件:
import com.dropbox.client2.DropboxAPI;
import com.dropbox.client2.DropboxAPI.UploadRequest;
import com.dropbox.client2.ProgressListener;
import com.dropbox.client2.exception.DropboxException;
import com.dropbox.client2.exception.DropboxFileSizeException;
import com.dropbox.client2.exception.DropboxIOException;
import com.dropbox.client2.exception.DropboxParseException;
import com.dropbox.client2.exception.DropboxPartialFileException;
import com.dropbox.client2.exception.DropboxServerException;
import com.dropbox.client2.exception.DropboxUnlinkedException;
/**
* Here we show uploading a file in a background thread, trying to show
* typical exception handling and flow of control for an app that uploads a
* file from Dropbox.
*/
public class UploadFile extends AsyncTask<Void, Long, Boolean> {
private DropboxAPI<?> mApi;
private String mPath;
private File mFile;
private long mFileLen;
private UploadRequest mRequest;
private Context mContext;
private final ProgressDialog mDialog;
private String mErrorMsg;
public UploadFile(Context context, DropboxAPI<?> api, String dropboxPath,
File file) {
// We set the context this way so we don't accidentally leak activities
mContext = context.getApplicationContext();
mFileLen = file.length();
mApi = api;
mPath = dropboxPath;
mFile = file;
mDialog = new ProgressDialog(context);
mDialog.setMax(100);
mDialog.setMessage("Uploading " + file.getName());
mDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
mDialog.setProgress(0);
mDialog.setButton(ProgressDialog.BUTTON_POSITIVE, "Cancel", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// This will cancel the putFile operation
mRequest.abort();
}
});
mDialog.show();
}
@Override
protected Boolean doInBackground(Void... params) {
try {
// By creating a request, we get a handle to the putFile operation,
// so we can cancel it later if we want to
FileInputStream fis = new FileInputStream(mFile);
String path = mPath + mFile.getName();
mRequest = mApi.putFileOverwriteRequest(path, fis, mFile.length(),
new ProgressListener() {
@Override
public long progressInterval() {
// Update the progress bar every half-second or so
return 500;
}
@Override
public void onProgress(long bytes, long total) {
publishProgress(bytes);
}
});
if (mRequest != null) {
mRequest.upload();
return true;
}
} catch (DropboxUnlinkedException e) {
// This session wasn't authenticated properly or user unlinked
mErrorMsg = "This app wasn't authenticated properly.";
} catch (DropboxFileSizeException e) {
// File size too big to upload via the API
mErrorMsg = "This file is too big to upload";
} catch (DropboxPartialFileException e) {
// We canceled the operation
mErrorMsg = "Upload canceled";
} catch (DropboxServerException e) {
// Server-side exception. These are examples of what could happen,
// but we don't do anything special with them here.
if (e.error == DropboxServerException._401_UNAUTHORIZED) {
// Unauthorized, so we should unlink them. You may want to
// automatically log the user out in this case.
} else if (e.error == DropboxServerException._403_FORBIDDEN) {
// Not allowed to access this
} else if (e.error == DropboxServerException._404_NOT_FOUND) {
// path not found (or if it was the thumbnail, can't be
// thumbnailed)
} else if (e.error == DropboxServerException._507_INSUFFICIENT_STORAGE) {
// user is over quota
} else {
// Something else
}
// This gets the Dropbox error, translated into the user's language
mErrorMsg = e.body.userError;
if (mErrorMsg == null) {
mErrorMsg = e.body.error;
}
} catch (DropboxIOException e) {
// Happens all the time, probably want to retry automatically.
mErrorMsg = "Network error. Try again.";
} catch (DropboxParseException e) {
// Probably due to Dropbox server restarting, should retry
mErrorMsg = "Dropbox error. Try again.";
} catch (DropboxException e) {
// Unknown error
mErrorMsg = "Unknown error. Try again.";
} catch (FileNotFoundException e) {
}
return false;
}
@Override
protected void onProgressUpdate(Long... progress) {
int percent = (int)(100.0*(double)progress[0]/mFileLen + 0.5);
mDialog.setProgress(percent);
}
@Override
protected void onPostExecute(Boolean result) {
mDialog.dismiss();
if (result) {
showToast("File successfully uploaded");
} else {
showToast(mErrorMsg);
}
}
private void showToast(String msg) {
Toast error = Toast.makeText(mContext, msg, Toast.LENGTH_LONG);
error.show();
}
}
下载文件:
/**
* Here we show getting metadata for a directory and downloading a file in a
* background thread, trying to show typical exception handling and flow of
* control for an app that downloads a file from Dropbox.
*/
public class DownloadFile extends AsyncTask<Void, Long, Boolean> {
private Context mContext;
private final ProgressDialog mDialog;
private DropboxAPI<?> mApi;
private String mPath;
private ImageView mView;
private Drawable mDrawable;
private FileOutputStream mFos;
private boolean mCanceled;
private Long mFileLen;
private String mErrorMsg;
// Note that, since we use a single file name here for simplicity, you
// won't be able to use this code for two simultaneous downloads.
private final static String IMAGE_FILE_NAME = "dbroulette.png";
private String localFilePath;
private String dropboxPath;
public DownloadFile(Context context, DropboxAPI<?> api,
String dropboxPath, String localFilePath) {
// We set the context this way so we don't accidentally leak activities
mContext = context.getApplicationContext();
this.localFilePath = localFilePath;
this.dropboxPath= dropboxPath;
mApi = api;
mPath = dropboxPath;
mDialog = new ProgressDialog(context);
mDialog.setMessage("Downloading File");
mDialog.setButton("Cancel", new OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
mCanceled = true;
mErrorMsg = "Canceled";
// This will cancel the getThumbnail operation by closing
// its stream
if (mFos != null) {
try {
mFos.close();
} catch (IOException e) {
}
}
}
});
mDialog.show();
}
@Override
protected Boolean doInBackground(Void... params) {
try{
File localFile = new File(localFilePath);
File fileSelected = new File(dropboxPath);
if (!localFile.exists()) {
localFile.createNewFile();
} else {
//copy(fileSelected, localFile);
//mApi.copy("/Test/test.png", "/sdcard/testfile.png");
BufferedInputStream br = null;
BufferedOutputStream bw = null;
DropboxInputStream fd;
try {
fd = mApi.getFileStream(fileSelected.getPath(), 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();
}
}
}
}/*
else {
showToast("File already exists");
}*/
}
catch (IOException e) {
showToast("Exception");
e.printStackTrace();
}
catch (Exception e) {
showToast("Exception");
e.printStackTrace();
}
return false;
}
@Override
protected void onProgressUpdate(Long... progress) {
int percent = (int)(100.0*(double)progress[0]/mFileLen + 0.5);
mDialog.setProgress(percent);
}
@Override
protected void onPostExecute(Boolean result) {
mDialog.dismiss();
if (result) {
// Set the image now that we have it
//mView.setImageDrawable(mDrawable);
showToast("Successful download");
} else {
// Couldn't download it, so show an error
showToast(mErrorMsg);
}
}
private void showToast(String msg) {
Toast error = Toast.makeText(mContext, msg, Toast.LENGTH_LONG);
error.show();
}
}
主要活动:
public class MainActivity extends Activity {
// Replace this with your app key and secret assigned by Dropbox.
// Note that this is a really insecure way to do this, and you shouldn't
// ship code which contains your key & secret in such an obvious way.
// Obfuscation is good.
final static private String APP_KEY = "";
final static private String APP_SECRET = "";
// You don't need to change these, leave them alone.
final static private String ACCOUNT_PREFS_NAME = "prefs";
final static private String ACCESS_KEY_NAME = "ACCESS_KEY";
final static private String ACCESS_SECRET_NAME = "ACCESS_SECRET";
private static final boolean USE_OAUTH1 = false;
DropboxAPI<AndroidAuthSession> mApi;
private boolean mLoggedIn;
private Button mSubmit;
private Button btnUpload;
private Button btnDownload;
private LinearLayout mDisplay;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// We create a new AuthSession so that we can use the Dropbox API.
AndroidAuthSession session = buildSession();
mApi = new DropboxAPI<AndroidAuthSession>(session);
setContentView(R.layout.main);
mSubmit = (Button)findViewById(R.id.auth_button);
btnDownload = (Button)findViewById(R.id.roulette_button);
btnUpload = (Button)findViewById(R.id.photo_button);
mDisplay = (LinearLayout)findViewById(R.id.logged_in_display);
mSubmit.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
if (mLoggedIn) {
logOut();
} else {
// Start the remote authentication
if (USE_OAUTH1) {
mApi.getSession().startAuthentication(MainActivity.this);
} else {
mApi.getSession().startOAuth2Authentication(MainActivity.this);
}
}
}
});
// Upload File
String testFile = "DeviceAdmin.apk";
String outPath = new File(Environment.getExternalStorageDirectory(), testFile).getPath();
Toast.makeText(MainActivity.this, outPath, Toast.LENGTH_LONG).show();
final File outFile = new File(outPath);
btnUpload.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
try{
UploadFile upload = new UploadFile(MainActivity.this, mApi, "/Test/", outFile);
upload.execute();
} catch (Exception e) {
Toast.makeText(MainActivity.this, "File not found", Toast.LENGTH_LONG).show();
}
}
});
// Download File
final String localFilePath = "/sdcard/testfile.txt";
final String dropboxPath= "/abc.txt";
btnDownload.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
DownloadFile download = new DownloadFile(MainActivity.this, mApi, dropboxPath, localFilePath);
download.execute();
}
});
setLoggedIn(mApi.getSession().isLinked());
}
private void setLoggedIn(boolean loggedIn) {
mLoggedIn = loggedIn;
if (loggedIn) {
Toast.makeText(MainActivity.this, "Successful login", Toast.LENGTH_LONG).show();
mDisplay.setVisibility(View.VISIBLE);
} else {
Toast.makeText(MainActivity.this, "logged out", Toast.LENGTH_LONG).show();
mDisplay.setVisibility(View.GONE);
}
}
private AndroidAuthSession buildSession() {
AppKeyPair appKeyPair = new AppKeyPair(APP_KEY, APP_SECRET);
AndroidAuthSession session = new AndroidAuthSession(appKeyPair);
loadAuth(session);
return session;
}
/**
* Shows keeping the access keys returned from Trusted Authenticator in a local
* store, rather than storing user name & password, and re-authenticating each
* time (which is not to be done, ever).
*/
private void loadAuth(AndroidAuthSession session) {
SharedPreferences prefs = getSharedPreferences(ACCOUNT_PREFS_NAME, 0);
String key = prefs.getString(ACCESS_KEY_NAME, null);
String secret = prefs.getString(ACCESS_SECRET_NAME, null);
if (key == null || secret == null || key.length() == 0 || secret.length() == 0) return;
if (key.equals("oauth2:")) {
// If the key is set to "oauth2:", then we can assume the token is for OAuth 2.
session.setOAuth2AccessToken(secret);
} else {
// Still support using old OAuth 1 tokens.
session.setAccessTokenPair(new AccessTokenPair(key, secret));
}
}
@Override
protected void onResume() {
super.onResume();
AndroidAuthSession session = mApi.getSession();
// The next part must be inserted in the onResume() method of the
// activity from which session.startAuthentication() was called, so
// that Dropbox authentication completes properly.
if (session.authenticationSuccessful()) {
try {
// Mandatory call to complete the auth
session.finishAuthentication();
// Store it locally in our app for later use
storeAuth(session);
setLoggedIn(true);
} catch (IllegalStateException e) {
Toast.makeText(MainActivity.this, "Couldn't authenticate with Dropbox:" + e.getLocalizedMessage(), Toast.LENGTH_LONG).show();
Log.i("Exception: ", "Error authenticating", e);
}
}
}
/**
* Shows keeping the access keys returned from Trusted Authenticator in a local
* store, rather than storing user name & password, and re-authenticating each
* time (which is not to be done, ever).
*/
private void storeAuth(AndroidAuthSession session) {
// Store the OAuth 2 access token, if there is one.
String oauth2AccessToken = session.getOAuth2AccessToken();
if (oauth2AccessToken != null) {
SharedPreferences prefs = getSharedPreferences(ACCOUNT_PREFS_NAME, 0);
Editor edit = prefs.edit();
edit.putString(ACCESS_KEY_NAME, "oauth2:");
edit.putString(ACCESS_SECRET_NAME, oauth2AccessToken);
edit.commit();
return;
}
// Store the OAuth 1 access token, if there is one. This is only necessary if
// you're still using OAuth 1.
AccessTokenPair oauth1AccessToken = session.getAccessTokenPair();
if (oauth1AccessToken != null) {
SharedPreferences prefs = getSharedPreferences(ACCOUNT_PREFS_NAME, 0);
Editor edit = prefs.edit();
edit.putString(ACCESS_KEY_NAME, oauth1AccessToken.key);
edit.putString(ACCESS_SECRET_NAME, oauth1AccessToken.secret);
edit.commit();
return;
}
}
private void clearKeys() {
SharedPreferences prefs = getSharedPreferences(ACCOUNT_PREFS_NAME, 0);
Editor edit = prefs.edit();
edit.clear();
edit.commit();
}
private void logOut() {
// Remove credentials from the session
mApi.getSession().unlink();
// Clear our stored keys
clearKeys();
// Change UI state to display logged out version
setLoggedIn(false);
}
}
这是参考的代码,请看一下并给出一些建议。我的主要任务是检索文件,加密并上传到Dropbox。
答案 0 :(得分:0)
不,用户无需输入其他应用密钥和密码。应用密钥和密钥标识您的应用。例如,当用户授权您的应用时,他们会看到他们授权的应用的名称。这来自app键。