/*
* Nextcloud Android client application
*
* @author Andy Scherzinger
* Copyright (C) 2016 Andy Scherzinger
* Copyright (C) 2016 Nextcloud
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
* License as published by the Free Software Foundation; either
* version 3 of the License, or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
*
* You should have received a copy of the GNU Affero General Public
* License along with this program. If not, see .
*/
package com.owncloud.android.ui.activity;
import android.accounts.Account;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.annotation.NonNull;
import android.support.design.widget.AppBarLayout;
import android.support.design.widget.BottomNavigationView;
import android.support.design.widget.CollapsingToolbarLayout;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBar;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.owncloud.android.MainApp;
import com.owncloud.android.R;
import com.owncloud.android.authentication.AccountUtils;
import com.owncloud.android.datamodel.ArbitraryDataProvider;
import com.owncloud.android.datamodel.MediaFolder;
import com.owncloud.android.datamodel.MediaFolderType;
import com.owncloud.android.datamodel.MediaProvider;
import com.owncloud.android.datamodel.OCFile;
import com.owncloud.android.datamodel.SyncedFolder;
import com.owncloud.android.datamodel.SyncedFolderDisplayItem;
import com.owncloud.android.datamodel.SyncedFolderProvider;
import com.owncloud.android.files.services.FileUploader;
import com.owncloud.android.ui.adapter.SyncedFolderAdapter;
import com.owncloud.android.ui.decoration.MediaGridItemDecoration;
import com.owncloud.android.ui.dialog.SyncedFolderPreferencesDialogFragment;
import com.owncloud.android.ui.dialog.parcel.SyncedFolderParcelable;
import com.owncloud.android.utils.DisplayUtils;
import com.owncloud.android.utils.FilesSyncHelper;
import com.owncloud.android.utils.PermissionUtil;
import com.owncloud.android.utils.ThemeUtils;
import java.io.File;
import java.io.FileFilter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import static android.support.design.widget.AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS;
import static com.owncloud.android.datamodel.SyncedFolderDisplayItem.UNPERSISTED_ID;
/**
* Activity displaying all auto-synced folders and/or instant upload media folders.
*/
public class SyncedFoldersActivity extends FileActivity implements SyncedFolderAdapter.ClickListener,
SyncedFolderPreferencesDialogFragment.OnSyncedFolderPreferenceListener {
private static final String SYNCED_FOLDER_PREFERENCES_DIALOG_TAG = "SYNCED_FOLDER_PREFERENCES_DIALOG";
public static final String[] PRIORITIZED_FOLDERS = new String[] { "Camera", "Screenshots" };
public static final String EXTRA_SHOW_SIDEBAR = "SHOW_SIDEBAR";
private static final String SCREEN_NAME = "Auto upload";
private static final String TAG = SyncedFoldersActivity.class.getSimpleName();
private RecyclerView mRecyclerView;
private SyncedFolderAdapter mAdapter;
private LinearLayout mProgress;
private TextView mEmpty;
private SyncedFolderProvider mSyncedFolderProvider;
private SyncedFolderPreferencesDialogFragment mSyncedFolderPreferencesDialogFragment;
private boolean showSidebar = true;
private RelativeLayout mCustomFolderRelativeLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getIntent().getExtras() != null) {
showSidebar = getIntent().getExtras().getBoolean(EXTRA_SHOW_SIDEBAR);
}
setContentView(R.layout.synced_folders_layout);
// setup toolbar
setupToolbar();
CollapsingToolbarLayout mCollapsingToolbarLayout = findViewById(R.id.collapsing_toolbar);
mCollapsingToolbarLayout.setTitle(this.getString(R.string.drawer_synced_folders));
mCustomFolderRelativeLayout = findViewById(R.id.custom_folder_toolbar);
SharedPreferences appPrefs =
PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
findViewById(R.id.toolbar).post(() -> {
if (!appPrefs.getBoolean(Preferences.PREFERENCE_EXPERT_MODE, false)) {
findViewById(R.id.app_bar).getLayoutParams().height = findViewById(R.id.toolbar).getHeight();
AppBarLayout.LayoutParams p = (AppBarLayout.LayoutParams) mCollapsingToolbarLayout.getLayoutParams();
p.setScrollFlags(SCROLL_FLAG_ENTER_ALWAYS);
mCollapsingToolbarLayout.setLayoutParams(p);
mCustomFolderRelativeLayout.setVisibility(View.GONE);
} else {
mCustomFolderRelativeLayout.setVisibility(View.VISIBLE);
findViewById(R.id.app_bar).setBackgroundColor(getResources().getColor(R.color.filelist_icon_backgorund));
}
});
// setup drawer
setupDrawer(R.id.nav_synced_folders);
if (!showSidebar) {
setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
mDrawerToggle.setDrawerIndicatorEnabled(false);
}
setupContent();
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
ThemeUtils.setColoredTitle(getSupportActionBar(), getString(R.string.drawer_synced_folders), this);
actionBar.setDisplayHomeAsUpEnabled(true);
}
if (ThemeUtils.themingEnabled(this)) {
setTheme(R.style.FallbackThemingTheme);
}
}
/**
* sets up the UI elements and loads all media/synced folders.
*/
private void setupContent() {
mRecyclerView = findViewById(android.R.id.list);
mProgress = findViewById(android.R.id.progress);
mEmpty = findViewById(android.R.id.empty);
final int gridWidth = getResources().getInteger(R.integer.media_grid_width);
boolean lightVersion = getResources().getBoolean(R.bool.syncedFolder_light);
mAdapter = new SyncedFolderAdapter(this, gridWidth, this, lightVersion);
mSyncedFolderProvider = new SyncedFolderProvider(getContentResolver());
final GridLayoutManager lm = new GridLayoutManager(this, gridWidth);
mAdapter.setLayoutManager(lm);
int spacing = getResources().getDimensionPixelSize(R.dimen.media_grid_spacing);
mRecyclerView.addItemDecoration(new MediaGridItemDecoration(spacing));
mRecyclerView.setLayoutManager(lm);
mRecyclerView.setAdapter(mAdapter);
BottomNavigationView bottomNavigationView = findViewById(R.id.bottom_navigation_view);
if (getResources().getBoolean(R.bool.bottom_toolbar_enabled)) {
bottomNavigationView.setVisibility(View.VISIBLE);
DisplayUtils.setupBottomBar(bottomNavigationView, getResources(), this, -1);
}
load(gridWidth * 2, false);
}
/**
* loads all media/synced folders, adds them to the recycler view adapter and shows the list.
*
* @param perFolderMediaItemLimit the amount of media items to be loaded/shown per media folder
*/
private void load(final int perFolderMediaItemLimit, boolean force) {
if (mAdapter.getItemCount() > 0 && !force) {
return;
}
setListShown(false);
final List mediaFolders = MediaProvider.getImageFolders(getContentResolver(),
perFolderMediaItemLimit, SyncedFoldersActivity.this);
mediaFolders.addAll(MediaProvider.getVideoFolders(getContentResolver(), perFolderMediaItemLimit,
SyncedFoldersActivity.this));
List syncedFolderArrayList = mSyncedFolderProvider.getSyncedFolders();
List currentAccountSyncedFoldersList = new ArrayList<>();
Account currentAccount = AccountUtils.getCurrentOwnCloudAccount(SyncedFoldersActivity.this);
for (SyncedFolder syncedFolder : syncedFolderArrayList) {
if (currentAccount != null && syncedFolder.getAccount().equals(currentAccount.name)) {
currentAccountSyncedFoldersList.add(syncedFolder);
}
}
List syncFolderItems = sortSyncedFolderItems(
mergeFolderData(currentAccountSyncedFoldersList, mediaFolders));
mAdapter.setSyncFolderItems(syncFolderItems);
mAdapter.notifyDataSetChanged();
setListShown(true);
}
/**
* merges two lists of {@link SyncedFolder} and {@link MediaFolder} items into one of SyncedFolderItems.
*
* @param syncedFolders the synced folders
* @param mediaFolders the media folders
* @return the merged list of SyncedFolderItems
*/
@NonNull
private List mergeFolderData(List syncedFolders,
@NonNull List mediaFolders) {
Map syncedFoldersMap = createSyncedFoldersMap(syncedFolders);
List result = new ArrayList<>();
for (MediaFolder mediaFolder : mediaFolders) {
if (syncedFoldersMap.containsKey(mediaFolder.absolutePath+"-"+mediaFolder.type)) {
SyncedFolder syncedFolder = syncedFoldersMap.get(mediaFolder.absolutePath+"-"+mediaFolder.type);
syncedFoldersMap.remove(mediaFolder.absolutePath+"-"+mediaFolder.type);
if (MediaFolderType.CUSTOM == syncedFolder.getType()) {
result.add(createSyncedFolderWithoutMediaFolder(syncedFolder));
} else {
result.add(createSyncedFolder(syncedFolder, mediaFolder));
}
} else {
result.add(createSyncedFolderFromMediaFolder(mediaFolder));
}
}
for (SyncedFolder syncedFolder : syncedFoldersMap.values()) {
result.add(createSyncedFolderWithoutMediaFolder(syncedFolder));
}
return result;
}
/**
* Sorts list of {@link SyncedFolderDisplayItem}s.
*
* @param syncFolderItemList list of items to be sorted
* @return sorted list of items
*/
public static List sortSyncedFolderItems(List
syncFolderItemList) {
Collections.sort(syncFolderItemList, new Comparator() {
public int compare(SyncedFolderDisplayItem f1, SyncedFolderDisplayItem f2) {
if (f1 == null && f2 == null) {
return 0;
} else if (f1 == null) {
return -1;
} else if (f2 == null) {
return 1;
} else if (f1.isEnabled() && f2.isEnabled()) {
return f1.getFolderName().toLowerCase(Locale.getDefault()).compareTo(
f2.getFolderName().toLowerCase(Locale.getDefault()));
} else if (f1.isEnabled()) {
return -1;
} else if (f2.isEnabled()) {
return 1;
} else if (f1.getFolderName() == null && f2.getFolderName() == null) {
return 0;
} else if (f1.getFolderName() == null) {
return -1;
} else if (f2.getFolderName() == null) {
return 1;
}
for (String folder : PRIORITIZED_FOLDERS) {
if (folder.equals(f1.getFolderName()) &&
folder.equals(f2.getFolderName())) {
return 0;
} else if (folder.equals(f1.getFolderName())) {
return -1;
} else if (folder.equals(f2.getFolderName())) {
return 1;
}
}
return f1.getFolderName().toLowerCase(Locale.getDefault()).compareTo(
f2.getFolderName().toLowerCase(Locale.getDefault()));
}
});
return syncFolderItemList;
}
@NonNull
private SyncedFolderDisplayItem createSyncedFolderWithoutMediaFolder(@NonNull SyncedFolder syncedFolder) {
File localFolder = new File(syncedFolder.getLocalPath());
File[] files = getFileList(localFolder);
List filePaths = getDisplayFilePathList(files);
return new SyncedFolderDisplayItem(
syncedFolder.getId(),
syncedFolder.getLocalPath(),
syncedFolder.getRemotePath(),
syncedFolder.getWifiOnly(),
syncedFolder.getChargingOnly(),
syncedFolder.getSubfolderByDate(),
syncedFolder.getAccount(),
syncedFolder.getUploadAction(),
syncedFolder.isEnabled(),
filePaths,
localFolder.getName(),
files.length,
syncedFolder.getType());
}
/**
* creates a SyncedFolderDisplayItem merging a {@link SyncedFolder} and a {@link MediaFolder} object instance.
*
* @param syncedFolder the synced folder object
* @param mediaFolder the media folder object
* @return the created SyncedFolderDisplayItem
*/
@NonNull
private SyncedFolderDisplayItem createSyncedFolder(@NonNull SyncedFolder syncedFolder, @NonNull MediaFolder mediaFolder) {
return new SyncedFolderDisplayItem(
syncedFolder.getId(),
syncedFolder.getLocalPath(),
syncedFolder.getRemotePath(),
syncedFolder.getWifiOnly(),
syncedFolder.getChargingOnly(),
syncedFolder.getSubfolderByDate(),
syncedFolder.getAccount(),
syncedFolder.getUploadAction(),
syncedFolder.isEnabled(),
mediaFolder.filePaths,
mediaFolder.folderName,
mediaFolder.numberOfFiles,
mediaFolder.type);
}
/**
* creates a {@link SyncedFolderDisplayItem} based on a {@link MediaFolder} object instance.
*
* @param mediaFolder the media folder object
* @return the created SyncedFolderDisplayItem
*/
@NonNull
private SyncedFolderDisplayItem createSyncedFolderFromMediaFolder(@NonNull MediaFolder mediaFolder) {
return new SyncedFolderDisplayItem(
UNPERSISTED_ID,
mediaFolder.absolutePath,
getString(R.string.instant_upload_path) + "/" + mediaFolder.folderName,
true,
false,
false,
AccountUtils.getCurrentOwnCloudAccount(this).name,
FileUploader.LOCAL_BEHAVIOUR_FORGET,
false,
mediaFolder.filePaths,
mediaFolder.folderName,
mediaFolder.numberOfFiles,
mediaFolder.type);
}
private File[] getFileList(File localFolder) {
File[] files = localFolder.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
return !pathname.isDirectory();
}
});
if (files != null) {
Arrays.sort(files, new Comparator() {
public int compare(File f1, File f2) {
return Long.valueOf(f1.lastModified()).compareTo(f2.lastModified());
}
});
} else {
files = new File[]{};
}
return files;
}
private List getDisplayFilePathList(File[] files) {
List filePaths = null;
if (files != null && files.length > 0) {
filePaths = new ArrayList<>();
for (int i = 0; i < 7 && i < files.length; i++) {
filePaths.add(files[i].getAbsolutePath());
}
}
return filePaths;
}
/**
* creates a lookup map for a list of given {@link SyncedFolder}s with their local path as the key.
*
* @param syncFolders list of {@link SyncedFolder}s
* @return the lookup map for {@link SyncedFolder}s
*/
@NonNull
private Map createSyncedFoldersMap(List syncFolders) {
Map result = new HashMap<>();
if (syncFolders != null) {
for (SyncedFolder syncFolder : syncFolders) {
result.put(syncFolder.getLocalPath()+"-"+syncFolder.getType(), syncFolder);
}
}
return result;
}
/**
* show/hide recycler view list or the empty message / progress info.
*
* @param shown flag if list should be shown
*/
private void setListShown(boolean shown) {
if (mRecyclerView != null) {
mRecyclerView.setVisibility(shown ? View.VISIBLE : View.GONE);
mProgress.setVisibility(shown ? View.GONE : View.VISIBLE);
mEmpty.setVisibility(shown && mAdapter.getItemCount() == 0 ? View.VISIBLE : View.GONE);
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
boolean result = true;
switch (item.getItemId()) {
case android.R.id.home: {
if (showSidebar) {
if (isDrawerOpen()) {
closeDrawer();
} else {
openDrawer();
}
} else {
Intent settingsIntent = new Intent(getApplicationContext(), Preferences.class);
startActivity(settingsIntent);
}
break;
}
default:
result = super.onOptionsItemSelected(item);
break;
}
return result;
}
@Override
public void restart() {
Intent i = new Intent(this, FileDisplayActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
}
@Override
public void showFiles(boolean onDeviceOnly) {
MainApp.showOnlyFilesOnDevice(onDeviceOnly);
Intent fileDisplayActivity = new Intent(getApplicationContext(), FileDisplayActivity.class);
fileDisplayActivity.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(fileDisplayActivity);
}
@Override
public void onSyncStatusToggleClick(int section, SyncedFolderDisplayItem syncedFolderDisplayItem) {
ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProvider(MainApp.getAppContext().
getContentResolver());
if (syncedFolderDisplayItem.getId() > UNPERSISTED_ID) {
mSyncedFolderProvider.updateSyncedFolderEnabled(syncedFolderDisplayItem.getId(),
syncedFolderDisplayItem.isEnabled());
} else {
long storedId = mSyncedFolderProvider.storeSyncedFolder(syncedFolderDisplayItem);
if (storedId != -1) {
syncedFolderDisplayItem.setId(storedId);
}
}
if (syncedFolderDisplayItem.isEnabled()) {
FilesSyncHelper.insertAllDBEntriesForSyncedFolder(syncedFolderDisplayItem);
} else {
String syncedFolderInitiatedKey = "syncedFolderIntitiated_" + syncedFolderDisplayItem.getId();
arbitraryDataProvider.deleteKeyForAccount("global", syncedFolderInitiatedKey);
}
FilesSyncHelper.scheduleNJobs(false, getApplicationContext());
}
@Override
public void onSyncFolderSettingsClick(int section, SyncedFolderDisplayItem syncedFolderDisplayItem) {
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.addToBackStack(null);
mSyncedFolderPreferencesDialogFragment = SyncedFolderPreferencesDialogFragment.newInstance(
syncedFolderDisplayItem, section);
mSyncedFolderPreferencesDialogFragment.show(ft, SYNCED_FOLDER_PREFERENCES_DIALOG_TAG);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == SyncedFolderPreferencesDialogFragment.REQUEST_CODE__SELECT_REMOTE_FOLDER
&& resultCode == RESULT_OK && mSyncedFolderPreferencesDialogFragment != null) {
OCFile chosenFolder = data.getParcelableExtra(FolderPickerActivity.EXTRA_FOLDER);
mSyncedFolderPreferencesDialogFragment.setRemoteFolderSummary(chosenFolder.getRemotePath());
} if (requestCode == SyncedFolderPreferencesDialogFragment.REQUEST_CODE__SELECT_LOCAL_FOLDER
&& resultCode == RESULT_OK && mSyncedFolderPreferencesDialogFragment != null) {
String localPath = data.getStringExtra(UploadFilesActivity.EXTRA_CHOSEN_FILES);
mSyncedFolderPreferencesDialogFragment.setLocalFolderSummary(localPath);
}
else {
super.onActivityResult(requestCode, resultCode, data);
}
}
@Override
public void onSaveSyncedFolderPreference(SyncedFolderParcelable syncedFolder) {
ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProvider(MainApp.getAppContext().
getContentResolver());
// custom folders newly created aren't in the list already,
// so triggering a refresh
if (MediaFolderType.CUSTOM.equals(syncedFolder.getType()) && syncedFolder.getId() == UNPERSISTED_ID) {
SyncedFolderDisplayItem newCustomFolder = new SyncedFolderDisplayItem(
SyncedFolder.UNPERSISTED_ID, syncedFolder.getLocalPath(), syncedFolder.getRemotePath(),
syncedFolder.getWifiOnly(), syncedFolder.getChargingOnly(), syncedFolder.getSubfolderByDate(),
syncedFolder.getAccount(), syncedFolder.getUploadAction(), syncedFolder.getEnabled(),
new File(syncedFolder.getLocalPath()).getName(), syncedFolder.getType());
long storedId = mSyncedFolderProvider.storeSyncedFolder(newCustomFolder);
if (storedId != -1) {
newCustomFolder.setId(storedId);
if (newCustomFolder.isEnabled()) {
FilesSyncHelper.insertAllDBEntriesForSyncedFolder(newCustomFolder);
} else {
String syncedFolderInitiatedKey = "syncedFolderIntitiated_" + newCustomFolder.getId();
arbitraryDataProvider.deleteKeyForAccount("global", syncedFolderInitiatedKey);
}
FilesSyncHelper.scheduleNJobs(false, getApplicationContext());
}
mAdapter.addSyncFolderItem(newCustomFolder);
} else {
SyncedFolderDisplayItem item = mAdapter.get(syncedFolder.getSection());
item = updateSyncedFolderItem(item, syncedFolder.getLocalPath(), syncedFolder.getRemotePath(), syncedFolder
.getWifiOnly(), syncedFolder.getChargingOnly(), syncedFolder.getSubfolderByDate(), syncedFolder
.getUploadAction(), syncedFolder.getEnabled());
if (syncedFolder.getId() == UNPERSISTED_ID) {
// newly set up folder sync config
long storedId = mSyncedFolderProvider.storeSyncedFolder(item);
if (storedId != -1) {
item.setId(storedId);
if (item.isEnabled()) {
FilesSyncHelper.insertAllDBEntriesForSyncedFolder(item);
} else {
String syncedFolderInitiatedKey = "syncedFolderIntitiated_" + item.getId();
arbitraryDataProvider.deleteKeyForAccount("global", syncedFolderInitiatedKey);
}
FilesSyncHelper.scheduleNJobs(false, getApplicationContext());
}
} else {
// existing synced folder setup to be updated
mSyncedFolderProvider.updateSyncFolder(item);
if (item.isEnabled()) {
FilesSyncHelper.insertAllDBEntriesForSyncedFolder(item);
} else {
String syncedFolderInitiatedKey = "syncedFolderIntitiated_" + item.getId();
arbitraryDataProvider.deleteKeyForAccount("global", syncedFolderInitiatedKey);
}
FilesSyncHelper.scheduleNJobs(false, getApplicationContext());
}
mAdapter.setSyncFolderItem(syncedFolder.getSection(), item);
}
mSyncedFolderPreferencesDialogFragment = null;
}
@Override
public void onCancelSyncedFolderPreference() {
mSyncedFolderPreferencesDialogFragment = null;
}
@Override
public void onDeleteSyncedFolderPreference(SyncedFolderParcelable syncedFolder) {
mSyncedFolderProvider.deleteSyncedFolder(syncedFolder.getId());
mAdapter.removeItem(syncedFolder.getSection());
}
/**
* update given synced folder with the given values.
*
* @param item the synced folder to be updated
* @param localPath the local path
* @param remotePath the remote path
* @param wifiOnly upload on wifi only
* @param chargingOnly upload on charging only
* @param subfolderByDate created sub folders
* @param uploadAction upload action
* @param enabled is sync enabled
* @return the updated item
*/
private SyncedFolderDisplayItem updateSyncedFolderItem(SyncedFolderDisplayItem item,
String localPath,
String remotePath,
Boolean wifiOnly,
Boolean chargingOnly,
Boolean subfolderByDate,
Integer uploadAction,
Boolean enabled) {
item.setLocalPath(localPath);
item.setRemotePath(remotePath);
item.setWifiOnly(wifiOnly);
item.setChargingOnly(chargingOnly);
item.setSubfolderByDate(subfolderByDate);
item.setUploadAction(uploadAction);
item.setEnabled(enabled);
return item;
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[],
@NonNull int[] grantResults) {
switch (requestCode) {
case PermissionUtil.PERMISSIONS_WRITE_EXTERNAL_STORAGE: {
// If request is cancelled, result arrays are empty.
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted
int gridWidth = getResources().getInteger(R.integer.media_grid_width);
load(gridWidth * 2, true);
} else {
// permission denied --> do nothing
return;
}
return;
}
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
public void onAddCustomFolderClick(View view) {
Log.d(TAG, "Show custom folder dialog");
SyncedFolderDisplayItem emptyCustomFolder = new SyncedFolderDisplayItem(
SyncedFolder.UNPERSISTED_ID, null, null, true, false,
false, AccountUtils.getCurrentOwnCloudAccount(this).name,
FileUploader.LOCAL_BEHAVIOUR_FORGET, false, null, MediaFolderType.CUSTOM);
onSyncFolderSettingsClick(0, emptyCustomFolder);
}
}