Как отобразить файлы Dropbox в виде списка в Android?
Я просматривал здесь ответы некоторое время и использовал большинство ответов в своем коде, но он все еще не работает. Я просто хочу отобразить список содержимого в учетной записи Dropbox, а также дать пользователю возможность загрузить файл / папку. Моя функция MainActivity имела сбой сразу после его открытия, и окружение моего содержимого onPostExecute оператором try / catch, обработавшим исключение NullPointerException, решило проблему сбоя. Но приложение по-прежнему не отображает содержимое в Dropbox. Как сделать эту работу на самом базовом этапе с использованием только классов MainActivity и DLFiles (AsyncTask)? Я был в этом в течение нескольких дней, пожалуйста, помогите! Заранее спасибо.
MainActivity.java
public class MainActivity extends Activity {
final static private String APP_KEY = "app_key_here";
final static private String APP_SECRET = "app_secret_here";
final static private AccessType ACCESS_TYPE = AccessType.DROPBOX;
private static final boolean USE_OAUTH1 = false;
// 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";
// In the class declaration section:
private DropboxAPI<AndroidAuthSession> mDBApi;
private boolean mLoggedIn;
private final String FILE_DIR = "/";
private String[] mfnames;
private ListView mListView;
private Button listEm;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// And later in some initialization function:
AppKeyPair appKeys = new AppKeyPair(APP_KEY, APP_SECRET);
AndroidAuthSession session = new AndroidAuthSession(appKeys, ACCESS_TYPE);
mDBApi = new DropboxAPI<AndroidAuthSession>(session);
if (!mLoggedIn){
if (USE_OAUTH1){
mDBApi.getSession().startAuthentication(MainActivity.this);
} else{
mDBApi.getSession().startOAuth2Authentication(MainActivity.this);
}
}
mListView = (ListView) findViewById(R.id.list);
listEm = (Button) findViewById(R.id.listit);
listEm.setOnClickListener(new OnClickListener(){
public void onClick(View v){
DLFiles dlf = new DLFiles(MainActivity.this,mDBApi,
FILE_DIR, mfnames,mListView );
dlf.execute();
}
});
checkLoggedIn(mDBApi.getSession().isLinked());
}
private void checkLoggedIn(boolean loggedIn){
mLoggedIn = loggedIn;
}
protected void onResume() {
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();
} catch (IllegalStateException e) {
Log.i("DbAuthLog", "Error authenticating", e);
}
}
}
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));
}
}
/**
* 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 AndroidAuthSession buildSession() {
AppKeyPair appKeyPair = new AppKeyPair(MainActivity.APP_KEY, MainActivity.APP_SECRET);
AndroidAuthSession session = new AndroidAuthSession(appKeyPair);
loadAuth(session);
return session;
}
}
DLFiles.java
public class DLFiles extends AsyncTask<Void, Long, String[]> {
private Context mContext;
private final ProgressDialog mDialog;
private DropboxAPI<?> mApi;
private String mPath;
private FileOutputStream mFos;
private boolean mCanceled;
private Long mFileLen;
private String mErrorMsg;
private String[] fnames;
public DLFiles( Context context, DropboxAPI<?> api,
String dropboxPath,String[] efnames, ListView listView){
// We set the context this way so we don't accidentally leak activities
mContext = context.getApplicationContext();
fnames = efnames;
mApi = api;
mPath = dropboxPath;
mDialog = new ProgressDialog(context);
mDialog.setMessage("Opening Directory");
mDialog.show();
}
@Override
protected String[] doInBackground(Void... params){
// Get the metadata for a directory
try{
ArrayList<String> filenames = new ArrayList<String>();
Entry dirent = mApi.metadata(mPath, 1000, null, true, null);
for (Entry ent: dirent.contents){
if(ent.isDir){
//Add it to the list of thumbs we can choose from
filenames.add("<dir>" + ent.path);}
else{
filenames.add(ent.fileName());
}
}
fnames = filenames.toArray(new String[filenames.size()]);
} catch (DropboxUnlinkedException e) {
// The AuthSession wasn't properly authenticated or user unlinked.
} catch (DropboxPartialFileException e) {
// We canceled the operation
mErrorMsg = "Download 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._304_NOT_MODIFIED) {
// won't happen since we don't pass in revision with metadata
} else 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._406_NOT_ACCEPTABLE) {
// too many entries to return
} else if (e.error == DropboxServerException._415_UNSUPPORTED_MEDIA) {
// 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.";
}
return fnames;
}
@Override
protected void onProgressUpdate(Long... progress){
int percent = (int)(100.0*(double)progress[0]/mFileLen + 0.5);
mDialog.setProgress(percent);
}
@Override
protected void onPostExecute(String[] result){
try{
if (result != null){
ArrayAdapter<String> array = new ArrayAdapter<String>(mContext,
android.R.layout.simple_list_item_1, result);
Log.d("dropbox", result[1]);
}
else
showToast("result==null");
}
catch (NullPointerException e){
e.printStackTrace();
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<Button
android:id="@+id/listit"
android:text="List directory content"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<LinearLayout
android:id="@+id/listing"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
>
<ListView
android:id="@+id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
</ListView>
</LinearLayout>
</LinearLayout>