瀏覽代碼

Merge pull request #194 from nextcloud/setAsWallpaper

Set as wallpaper/contact-photo/etc.
Mario Đanić 8 年之前
父節點
當前提交
01e7112a9a

+ 1 - 1
src/main/java/com/owncloud/android/authentication/AccountUtils.java

@@ -156,7 +156,7 @@ public class AccountUtils {
                             .getDefaultSharedPreferences(context).edit();
                     appPrefs.putString("select_oc_account", accountName);
     
-                    appPrefs.commit();
+                    appPrefs.apply();
                     result = true;
                     break;
                 }

+ 1 - 1
src/main/java/com/owncloud/android/authentication/AuthenticatorActivity.java

@@ -1791,7 +1791,7 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
                 SharedPreferences.Editor editor = PreferenceManager
                         .getDefaultSharedPreferences(this).edit();
                 editor.putString("select_oc_account", accountName);
-                editor.commit();
+                editor.apply();
             }
 
             /// prepare result to return to the Authenticator

+ 1 - 1
src/main/java/com/owncloud/android/db/PreferenceManager.java

@@ -274,7 +274,7 @@ public abstract class PreferenceManager {
     private static void saveStringPreferenceNow(Context context, String key, String value) {
         SharedPreferences.Editor appPreferences = getDefaultSharedPreferences(context.getApplicationContext()).edit();
         appPreferences.putString(key, value);
-        appPreferences.commit();
+        appPreferences.apply();
     }
 
     private static void saveIntPreference(Context context, String key, int value) {

+ 18 - 10
src/main/java/com/owncloud/android/files/FileMenuFilter.java

@@ -1,4 +1,4 @@
-/**
+/*
  * ownCloud Android client application
  *
  * @author David A. Velasco
@@ -31,10 +31,11 @@ import com.owncloud.android.files.services.FileUploader.FileUploaderBinder;
 import com.owncloud.android.lib.resources.status.OCCapability;
 import com.owncloud.android.services.OperationsService.OperationsServiceBinder;
 import com.owncloud.android.ui.activity.ComponentsGetter;
+import com.owncloud.android.utils.MimeTypeUtil;
 
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
 
@@ -59,8 +60,7 @@ public class FileMenuFilter {
      * @param cg                Accessor to app components, needed to access synchronization services
      * @param context           Android {@link Context}, needed to access build setup resources.
      */
-    public FileMenuFilter(Collection<OCFile> targetFiles, Account account, ComponentsGetter cg,
-                          Context context) {
+    public FileMenuFilter(Collection<OCFile> targetFiles, Account account, ComponentsGetter cg, Context context) {
         mFiles = targetFiles;
         mAccount = account;
         mComponentsGetter = cg;
@@ -75,9 +75,8 @@ public class FileMenuFilter {
      * @param cg                Accessor to app components, needed to access synchronization services
      * @param context           Android {@link Context}, needed to access build setup resources.
      */
-    public FileMenuFilter(OCFile targetFile, Account account, ComponentsGetter cg,
-                          Context context) {
-        this(Arrays.asList(new OCFile[]{targetFile}), account, cg, context);
+    public FileMenuFilter(OCFile targetFile, Account account, ComponentsGetter cg, Context context) {
+        this(Collections.singletonList(targetFile), account, cg, context);
     }
 
     /**
@@ -91,8 +90,8 @@ public class FileMenuFilter {
             hideAll(menu);
 
         } else {
-            List<Integer> toShow = new ArrayList<Integer>();
-            List<Integer> toHide = new ArrayList<Integer>();
+            List<Integer> toShow = new ArrayList<>();
+            List<Integer> toHide = new ArrayList<>();
 
             filter(toShow, toHide);
 
@@ -124,7 +123,6 @@ public class FileMenuFilter {
         }
     }
 
-
     /**
      * Performs the real filtering, to be applied in the {@link Menu} by the caller methods.
      *
@@ -257,6 +255,12 @@ public class FileMenuFilter {
         }
 
 
+        // SET PICTURE AS
+        if (isSingleImage() && !MimeTypeUtil.isSVG(mFiles.iterator().next())) {
+            toShow.add(R.id.action_set_as_wallpaper);
+        } else {
+            toHide.add(R.id.action_set_as_wallpaper);
+        }
     }
 
     private boolean anyFileSynchronizing() {
@@ -312,6 +316,10 @@ public class FileMenuFilter {
         return isSingleSelection() && !mFiles.iterator().next().isFolder();
     }
 
+    private boolean isSingleImage() {
+        return isSingleSelection() && MimeTypeUtil.isImage(mFiles.iterator().next());
+    }
+
     private boolean allFiles() {
         return mFiles != null && !containsFolder();
     }

+ 5 - 2
src/main/java/com/owncloud/android/files/services/FileDownloader.java

@@ -54,6 +54,7 @@ import com.owncloud.android.lib.resources.files.FileUtils;
 import com.owncloud.android.operations.DownloadFileOperation;
 import com.owncloud.android.ui.activity.FileActivity;
 import com.owncloud.android.ui.activity.FileDisplayActivity;
+import com.owncloud.android.ui.fragment.OCFileListFragment;
 import com.owncloud.android.ui.notifications.NotificationUtils;
 import com.owncloud.android.ui.preview.PreviewImageActivity;
 import com.owncloud.android.ui.preview.PreviewImageFragment;
@@ -174,9 +175,10 @@ public class FileDownloader extends Service
         } else {
             final Account account = intent.getParcelableExtra(EXTRA_ACCOUNT);
             final OCFile file = intent.getParcelableExtra(EXTRA_FILE);
+            final String behaviour = intent.getStringExtra(OCFileListFragment.DOWNLOAD_BEHAVIOUR);
             AbstractList<String> requestedDownloads = new Vector<String>();
             try {
-                DownloadFileOperation newDownload = new DownloadFileOperation(account, file);
+                DownloadFileOperation newDownload = new DownloadFileOperation(account, file, behaviour);
                 newDownload.addDatatransferProgressListener(this);
                 newDownload.addDatatransferProgressListener((FileDownloaderBinder) mBinder);
                 Pair<String, String> putResult = mPendingDownloads.putIfAbsent(
@@ -490,7 +492,7 @@ public class FileDownloader extends Service
         file.setFileLength((new File(mCurrentDownload.getSavePath()).length()));
         file.setRemoteId(mCurrentDownload.getFile().getRemoteId());
         mStorageManager.saveFile(file);
-        mStorageManager.triggerMediaScan(file.getStoragePath());
+        FileDataStorageManager.triggerMediaScan(file.getStoragePath());
         mStorageManager.saveConflict(file, null);
     }
 
@@ -639,6 +641,7 @@ public class FileDownloader extends Service
         end.putExtra(ACCOUNT_NAME, download.getAccount().name);
         end.putExtra(EXTRA_REMOTE_PATH, download.getRemotePath());
         end.putExtra(EXTRA_FILE_PATH, download.getSavePath());
+        end.putExtra(OCFileListFragment.DOWNLOAD_BEHAVIOUR, download.getBehaviour());
         if (unlinkedFromRemotePath != null) {
             end.putExtra(EXTRA_LINKED_TO_PATH, unlinkedFromRemotePath);
         }

+ 8 - 2
src/main/java/com/owncloud/android/operations/DownloadFileOperation.java

@@ -49,6 +49,7 @@ public class DownloadFileOperation extends RemoteOperation {
 
     private Account mAccount;
     private OCFile mFile;
+    private String mBehaviour;
     private Set<OnDatatransferProgressListener> mDataTransferListeners = new HashSet<OnDatatransferProgressListener>();
     private long mModificationTimestamp = 0;
     private String mEtag = "";
@@ -56,8 +57,8 @@ public class DownloadFileOperation extends RemoteOperation {
     
     private DownloadRemoteFileOperation mDownloadOperation;
 
-    
-    public DownloadFileOperation(Account account, OCFile file) {
+
+    public DownloadFileOperation(Account account, OCFile file, String behaviour) {
         if (account == null) {
             throw new IllegalArgumentException("Illegal null account in DownloadFileOperation " +
                     "creation");
@@ -69,6 +70,7 @@ public class DownloadFileOperation extends RemoteOperation {
         
         mAccount = account;
         mFile = file;
+        mBehaviour = behaviour;
     }
 
 
@@ -80,6 +82,10 @@ public class DownloadFileOperation extends RemoteOperation {
         return mFile;
     }
 
+    public String getBehaviour() {
+        return mBehaviour;
+    }
+
     public String getSavePath() {
         if (mFile.getStoragePath() != null) {
             File path = new File(mFile.getStoragePath());  // re-downloads should be done over the original file

+ 27 - 14
src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.java

@@ -83,12 +83,12 @@ import com.owncloud.android.services.observer.FileObserverService;
 import com.owncloud.android.syncadapter.FileSyncAdapter;
 import com.owncloud.android.ui.dialog.SortingOrderDialogFragment;
 import com.owncloud.android.ui.events.TokenPushEvent;
-import com.owncloud.android.ui.fragment.contactsbackup.ContactListFragment;
 import com.owncloud.android.ui.fragment.ExtendedListFragment;
 import com.owncloud.android.ui.fragment.FileDetailFragment;
 import com.owncloud.android.ui.fragment.FileFragment;
 import com.owncloud.android.ui.fragment.OCFileListFragment;
 import com.owncloud.android.ui.fragment.TaskRetainerFragment;
+import com.owncloud.android.ui.fragment.contactsbackup.ContactListFragment;
 import com.owncloud.android.ui.helpers.UriUploader;
 import com.owncloud.android.ui.preview.PreviewImageActivity;
 import com.owncloud.android.ui.preview.PreviewImageFragment;
@@ -1373,28 +1373,35 @@ public class FileDisplayActivity extends HookActivity
         public void onReceive(Context context, Intent intent) {
             try {
                 boolean sameAccount = isSameAccount(intent);
-                String downloadedRemotePath =
-                        intent.getStringExtra(FileDownloader.EXTRA_REMOTE_PATH);
+                String downloadedRemotePath = intent.getStringExtra(FileDownloader.EXTRA_REMOTE_PATH);
+                String downloadBehaviour = intent.getStringExtra(OCFileListFragment.DOWNLOAD_BEHAVIOUR);
                 boolean isDescendant = isDescendant(downloadedRemotePath);
 
                 if (sameAccount && isDescendant) {
-                    String linkedToRemotePath =
-                            intent.getStringExtra(FileDownloader.EXTRA_LINKED_TO_PATH);
+                    String linkedToRemotePath = intent.getStringExtra(FileDownloader.EXTRA_LINKED_TO_PATH);
                     if (linkedToRemotePath == null || isAscendant(linkedToRemotePath)) {
                         refreshListOfFilesFragment(false);
                     }
                     refreshSecondFragment(
                             intent.getAction(),
                             downloadedRemotePath,
-                            intent.getBooleanExtra(FileDownloader.EXTRA_DOWNLOAD_RESULT, false)
-                    );
+                            intent.getBooleanExtra(FileDownloader.EXTRA_DOWNLOAD_RESULT, false));
                 }
 
                 if (mWaitingToSend != null) {
-                    mWaitingToSend =
-                            getStorageManager().getFileByPath(mWaitingToSend.getRemotePath());
-                    if (mWaitingToSend.isDown()) {
-                        sendDownloadedFile();
+                    mWaitingToSend = getStorageManager().getFileByPath(mWaitingToSend.getRemotePath());
+                    if (mWaitingToSend.isDown() && downloadBehaviour != null) {
+                        switch (downloadBehaviour) {
+                            case OCFileListFragment.DOWNLOAD_SEND:
+                                sendDownloadedFile();
+                                break;
+                            case OCFileListFragment.DOWNLOAD_SET_AS:
+                                setPictureAs();
+                                break;
+                            default:
+                                // do nothing
+                                break;
+                        }
                     }
                 }
 
@@ -1872,12 +1879,13 @@ public class FileDisplayActivity extends HookActivity
         }
     }
 
-    private void requestForDownload(OCFile file) {
+    private void requestForDownload(OCFile file, String downloadBehaviour) {
         Account account = getAccount();
         if (!mDownloaderBinder.isDownloading(account, mWaitingToPreview)) {
             Intent i = new Intent(this, FileDownloader.class);
             i.putExtra(FileDownloader.EXTRA_ACCOUNT, account);
             i.putExtra(FileDownloader.EXTRA_FILE, file);
+            i.putExtra(OCFileListFragment.DOWNLOAD_BEHAVIOUR, downloadBehaviour);
             startService(i);
         }
     }
@@ -1887,6 +1895,11 @@ public class FileDisplayActivity extends HookActivity
         mWaitingToSend = null;
     }
 
+    private void setPictureAs() {
+        getFileOperationsHelper().setPictureAs(mWaitingToSend);
+        mWaitingToSend = null;
+    }
+
 
     /**
      * Requests the download of the received {@link OCFile} , updates the UI
@@ -1895,9 +1908,9 @@ public class FileDisplayActivity extends HookActivity
      *
      * @param file {@link OCFile} to download and preview.
      */
-    public void startDownloadForSending(OCFile file) {
+    public void startDownloadForSending(OCFile file, String downloadBehaviour) {
         mWaitingToSend = file;
-        requestForDownload(mWaitingToSend);
+        requestForDownload(mWaitingToSend, downloadBehaviour);
         boolean hasSecondFragment = (getSecondFragment() != null);
         updateFragmentsVisibility(hasSecondFragment);
     }

+ 2 - 1
src/main/java/com/owncloud/android/ui/fragment/FileDetailFragment.java

@@ -307,7 +307,8 @@ public class FileDetailFragment extends FileFragment implements OnClickListener
                 // Obtain the file
                 if (!getFile().isDown()) {  // Download the file                    
                     Log_OC.d(TAG, getFile().getRemotePath() + " : File must be downloaded");
-                    ((FileDisplayActivity) mContainerActivity).startDownloadForSending(getFile());
+                    ((FileDisplayActivity) mContainerActivity).startDownloadForSending(getFile(),
+                            OCFileListFragment.DOWNLOAD_SEND);
                 }
                 else {
                     mContainerActivity.getFileOperationsHelper().sendDownloadedFile(getFile());

+ 14 - 2
src/main/java/com/owncloud/android/ui/fragment/OCFileListFragment.java

@@ -120,6 +120,10 @@ public class OCFileListFragment extends ExtendedListFragment implements OCFileLi
     public final static String ARG_ALLOW_CONTEXTUAL_ACTIONS = MY_PACKAGE + ".ALLOW_CONTEXTUAL";
     public final static String ARG_HIDE_FAB = MY_PACKAGE + ".HIDE_FAB";
 
+    public static final String DOWNLOAD_BEHAVIOUR = "DOWNLOAD_BEHAVIOUR";
+    public static final String DOWNLOAD_SEND = "DOWNLOAD_SEND";
+    public static final String DOWNLOAD_SET_AS = "DOWNLOAD_SET_AS";
+
     public static final String SEARCH_EVENT = "SEARCH_EVENT";
 
     private static final String KEY_FILE = MY_PACKAGE + ".extra.FILE";
@@ -867,13 +871,21 @@ public class OCFileListFragment extends ExtendedListFragment implements OCFileLi
                     // Obtain the file
                     if (!singleFile.isDown()) {  // Download the file
                         Log_OC.d(TAG, singleFile.getRemotePath() + " : File must be downloaded");
-                        ((FileDisplayActivity) mContainerActivity).startDownloadForSending(singleFile);
-
+                        ((FileDisplayActivity) mContainerActivity).startDownloadForSending(singleFile, DOWNLOAD_SEND);
                     } else {
                         mContainerActivity.getFileOperationsHelper().sendDownloadedFile(singleFile);
                     }
                     return true;
                 }
+                case R.id.action_set_as_wallpaper: {
+                    if (singleFile.isDown()) {
+                        mContainerActivity.getFileOperationsHelper().setPictureAs(singleFile);
+                    } else {
+                        Log_OC.d(TAG, singleFile.getRemotePath() + " : File must be downloaded");
+                        ((FileDisplayActivity) mContainerActivity).startDownloadForSending(singleFile, DOWNLOAD_SET_AS);
+                    }
+                    return true;
+                }
             }
         }
 

+ 92 - 57
src/main/java/com/owncloud/android/ui/helpers/FileOperationsHelper.java

@@ -1,23 +1,22 @@
 /**
- *   ownCloud Android client application
- *
- *   @author masensio
- *   @author David A. Velasco
- *   @author Juan Carlos González Cabrero
- *   Copyright (C) 2015 ownCloud Inc.
- *
- *   This program is free software: you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License version 2,
- *   as published by the Free Software Foundation.
- *
- *   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 General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ * ownCloud Android client application
  *
+ * @author masensio
+ * @author David A. Velasco
+ * @author Juan Carlos González Cabrero
+ * Copyright (C) 2015 ownCloud Inc.
+ * <p>
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2,
+ * as published by the Free Software Foundation.
+ * <p>
+ * 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 General Public License for more details.
+ * <p>
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
 package com.owncloud.android.ui.helpers;
@@ -29,11 +28,14 @@ import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.net.Uri;
+import android.os.Build;
 import android.support.annotation.Nullable;
 import android.support.v4.app.DialogFragment;
+import android.support.v4.content.FileProvider;
 import android.webkit.MimeTypeMap;
 import android.widget.Toast;
 
+import com.owncloud.android.MainApp;
 import com.owncloud.android.R;
 import com.owncloud.android.authentication.AccountUtils;
 import com.owncloud.android.datamodel.OCFile;
@@ -53,6 +55,7 @@ import com.owncloud.android.ui.events.FavoriteEvent;
 import org.greenrobot.eventbus.EventBus;
 
 import java.io.BufferedReader;
+import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStreamReader;
@@ -68,7 +71,7 @@ import java.util.regex.Pattern;
 public class FileOperationsHelper {
 
     private static final String TAG = FileOperationsHelper.class.getSimpleName();
-    
+
     private static final String FTAG_CHOOSER_DIALOG = "CHOOSER_DIALOG";
 
     protected FileActivity mFileActivity = null;
@@ -76,21 +79,21 @@ public class FileOperationsHelper {
     /// Identifier of operation in progress which result shouldn't be lost 
     private long mWaitingForOpId = Long.MAX_VALUE;
 
-	private static final Pattern mPatternUrl = Pattern.compile("^URL=(.+)$");
-	private static final Pattern mPatternString = Pattern.compile("<string>(.+)</string>");
+    private static final Pattern mPatternUrl = Pattern.compile("^URL=(.+)$");
+    private static final Pattern mPatternString = Pattern.compile("<string>(.+)</string>");
 
     public FileOperationsHelper(FileActivity fileActivity) {
         mFileActivity = fileActivity;
     }
 
-	@Nullable
+    @Nullable
     private String getUrlFromFile(String storagePath, Pattern pattern) {
         String url = null;
 
         InputStreamReader fr = null;
         BufferedReader br = null;
         try {
-            fr =  new InputStreamReader(new FileInputStream(storagePath), "UTF8");
+            fr = new InputStreamReader(new FileInputStream(storagePath), "UTF8");
             br = new BufferedReader(fr);
 
             String line;
@@ -102,7 +105,7 @@ public class FileOperationsHelper {
                 }
             }
         } catch (IOException e) {
-			Log_OC.d(TAG, e.getMessage());
+            Log_OC.d(TAG, e.getMessage());
         } finally {
             if (br != null) {
                 try {
@@ -121,20 +124,20 @@ public class FileOperationsHelper {
             }
         }
         return url;
-	}
-	
+    }
+
     @Nullable
     private Intent createIntentFromFile(String storagePath) {
         String url = null;
         int lastIndexOfDot = storagePath.lastIndexOf('.');
         if (lastIndexOfDot >= 0) {
             String fileExt = storagePath.substring(lastIndexOfDot + 1);
-            if (fileExt.equalsIgnoreCase("url") ||fileExt.equalsIgnoreCase("desktop")) {
-				// Windows internet shortcut file .url
-				// Ubuntu internet shortcut file .desktop
+            if (fileExt.equalsIgnoreCase("url") || fileExt.equalsIgnoreCase("desktop")) {
+                // Windows internet shortcut file .url
+                // Ubuntu internet shortcut file .desktop
                 url = getUrlFromFile(storagePath, mPatternUrl);
             } else if (fileExt.equalsIgnoreCase("webloc")) {
-				// mac internet shortcut file .webloc
+                // mac internet shortcut file .webloc
                 url = getUrlFromFile(storagePath, mPatternString);
             }
         }
@@ -162,7 +165,7 @@ public class FileOperationsHelper {
                 }
             }
 
-            if(openFileWithIntent == null) {
+            if (openFileWithIntent == null) {
                 openFileWithIntent = createIntentFromFile(storagePath);
             }
 
@@ -179,7 +182,7 @@ public class FileOperationsHelper {
             List<ResolveInfo> launchables = mFileActivity.getPackageManager().
                     queryIntentActivities(openFileWithIntent, PackageManager.GET_INTENT_FILTERS);
 
-            if(launchables != null && launchables.size() > 0) {
+            if (launchables != null && launchables.size() > 0) {
                 try {
                     mFileActivity.startActivity(
                             Intent.createChooser(
@@ -247,7 +250,7 @@ public class FileOperationsHelper {
         }
     }
 
-    public void getFileWithLink(OCFile file){
+    public void getFileWithLink(OCFile file) {
         if (isSharedSupported()) {
             if (file != null) {
                 mFileActivity.showLoadingDialog(mFileActivity.getApplicationContext().
@@ -284,7 +287,7 @@ public class FileOperationsHelper {
         if (file != null) {
             // TODO check capability?
             mFileActivity.showLoadingDialog(mFileActivity.getApplicationContext().
-                getString(R.string.wait_a_moment));
+                    getString(R.string.wait_a_moment));
 
             Intent service = new Intent(mFileActivity, OperationsService.class);
             service.setAction(OperationsService.ACTION_CREATE_SHARE_WITH_SHAREE);
@@ -332,7 +335,7 @@ public class FileOperationsHelper {
         queueShareIntent(unshareService);
     }
 
-    public void unshareFileWithUserOrGroup(OCFile file, ShareType shareType, String userOrGroup){
+    public void unshareFileWithUserOrGroup(OCFile file, ShareType shareType, String userOrGroup) {
 
         // Unshare the file: Create the intent
         Intent unshareService = new Intent(mFileActivity, OperationsService.class);
@@ -346,7 +349,7 @@ public class FileOperationsHelper {
     }
 
 
-    private void queueShareIntent(Intent shareIntent){
+    private void queueShareIntent(Intent shareIntent) {
         if (isSharedSupported()) {
             // Unshare the file
             mWaitingForOpId = mFileActivity.getOperationsServiceBinder().
@@ -370,7 +373,7 @@ public class FileOperationsHelper {
      *
      * @param file  File to share or unshare.
      */
-    public void showShareFile(OCFile file){
+    public void showShareFile(OCFile file) {
         Intent intent = new Intent(mFileActivity, ShareActivity.class);
         intent.putExtra(FileActivity.EXTRA_FILE, file);
         intent.putExtra(FileActivity.EXTRA_ACCOUNT, mFileActivity.getAccount());
@@ -508,8 +511,8 @@ public class FileOperationsHelper {
             // set MimeType
             sendIntent.setType(file.getMimetype());
             sendIntent.putExtra(
-                Intent.EXTRA_STREAM,
-                file.getExposedFileUri(mFileActivity)
+                    Intent.EXTRA_STREAM,
+                    file.getExposedFileUri(mFileActivity)
             );
             sendIntent.putExtra(Intent.ACTION_SEND, true);      // Send Action
 
@@ -524,18 +527,50 @@ public class FileOperationsHelper {
     }
 
     public void syncFiles(Collection<OCFile> files) {
-        for (OCFile file: files) {
+        for (OCFile file : files) {
             syncFile(file);
         }
     }
 
+    public void setPictureAs(OCFile file) {
+        if (file != null) {
+            if (file.isDown()) {
+                Context context = MainApp.getAppContext();
+
+                try {
+                    File externalFile = new File(file.getStoragePath());
+                    Intent intent = new Intent(Intent.ACTION_ATTACH_DATA);
+                    Uri sendUri;
+
+                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+                        intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+                        sendUri = FileProvider.getUriForFile(context,
+                                context.getResources().getString(R.string.file_provider_authority), externalFile);
+                    } else {
+                        sendUri = Uri.fromFile(externalFile);
+                    }
+
+                    intent.setDataAndType(sendUri, file.getMimetype());
+                    intent.putExtra("mimeType", file.getMimetype());
+                    mFileActivity.startActivityForResult(Intent.createChooser(intent,
+                            mFileActivity.getString(R.string.set_as)), 200);
+
+                } catch (ActivityNotFoundException exception) {
+                    Toast.makeText(context, R.string.picture_set_as_no_app, Toast.LENGTH_LONG).show();
+                }
+            }
+        } else {
+            Log_OC.wtf(TAG, "Trying to send a NULL OCFile");
+        }
+    }
+
     /**
      * Request the synchronization of a file or folder with the OC server, including its contents.
      *
      * @param file          The file or folder to synchronize
      */
     public void syncFile(OCFile file) {
-        if (!file.isFolder()){
+        if (!file.isFolder()) {
             Intent intent = new Intent(mFileActivity, OperationsService.class);
             intent.setAction(OperationsService.ACTION_SYNC_FILE);
             intent.putExtra(OperationsService.EXTRA_ACCOUNT, mFileActivity.getAccount());
@@ -543,8 +578,8 @@ public class FileOperationsHelper {
             intent.putExtra(OperationsService.EXTRA_SYNC_FILE_CONTENTS, true);
             mWaitingForOpId = mFileActivity.getOperationsServiceBinder().queueNewOperation(intent);
             mFileActivity.showLoadingDialog(mFileActivity.getApplicationContext().
-                getString(R.string.wait_a_moment));
-            
+                    getString(R.string.wait_a_moment));
+
         } else {
             Intent intent = new Intent(mFileActivity, OperationsService.class);
             intent.setAction(OperationsService.ACTION_SYNC_FOLDER);
@@ -557,37 +592,37 @@ public class FileOperationsHelper {
 
     public void toggleFavoriteFiles(Collection<OCFile> files, boolean shouldBeFavorite) {
         List<OCFile> alreadyRightStateList = new ArrayList<>();
-        for(OCFile file : files) {
-            if(file.getIsFavorite() == shouldBeFavorite) {
+        for (OCFile file : files) {
+            if (file.getIsFavorite() == shouldBeFavorite) {
                 alreadyRightStateList.add(file);
             }
         }
 
         files.removeAll(alreadyRightStateList);
 
-        for (OCFile file: files) {
+        for (OCFile file : files) {
             toggleFavoriteFile(file, shouldBeFavorite);
         }
     }
 
     public void toggleFavoriteFile(OCFile file, boolean shouldBeFavorite) {
-        if(file.getIsFavorite() != shouldBeFavorite) {
+        if (file.getIsFavorite() != shouldBeFavorite) {
             EventBus.getDefault().post(new FavoriteEvent(file.getRemotePath(), shouldBeFavorite, file.getRemoteId()));
         }
     }
 
 
-    public void toogleOfflineFiles(Collection<OCFile> files, boolean isAvailableOffline){
+    public void toogleOfflineFiles(Collection<OCFile> files, boolean isAvailableOffline) {
         List<OCFile> alreadyRightStateList = new ArrayList<>();
-        for(OCFile file : files) {
-            if(file.isAvailableOffline() == isAvailableOffline) {
+        for (OCFile file : files) {
+            if (file.isAvailableOffline() == isAvailableOffline) {
                 alreadyRightStateList.add(file);
             }
         }
 
         files.removeAll(alreadyRightStateList);
 
-        for (OCFile file: files) {
+        for (OCFile file : files) {
             toggleOfflineFile(file, isAvailableOffline);
         }
     }
@@ -612,7 +647,7 @@ public class FileOperationsHelper {
             }
         }
     }
-    
+
     public void renameFile(OCFile file, String newFilename) {
         // RenameFile
         Intent service = new Intent(mFileActivity, OperationsService.class);
@@ -621,7 +656,7 @@ public class FileOperationsHelper {
         service.putExtra(OperationsService.EXTRA_REMOTE_PATH, file.getRemotePath());
         service.putExtra(OperationsService.EXTRA_NEWNAME, newFilename);
         mWaitingForOpId = mFileActivity.getOperationsServiceBinder().queueNewOperation(service);
-        
+
         mFileActivity.showLoadingDialog(mFileActivity.getString(R.string.wait_a_moment));
     }
 
@@ -643,7 +678,7 @@ public class FileOperationsHelper {
             service.putExtra(OperationsService.EXTRA_REMOVE_ONLY_LOCAL, onlyLocalCopy);
             mWaitingForOpId = mFileActivity.getOperationsServiceBinder().queueNewOperation(service);
         }
-        
+
         mFileActivity.showLoadingDialog(mFileActivity.getString(R.string.wait_a_moment));
     }
 
@@ -655,8 +690,8 @@ public class FileOperationsHelper {
         service.putExtra(OperationsService.EXTRA_ACCOUNT, mFileActivity.getAccount());
         service.putExtra(OperationsService.EXTRA_REMOTE_PATH, remotePath);
         service.putExtra(OperationsService.EXTRA_CREATE_FULL_PATH, createFullPath);
-        mWaitingForOpId =  mFileActivity.getOperationsServiceBinder().queueNewOperation(service);
-        
+        mWaitingForOpId = mFileActivity.getOperationsServiceBinder().queueNewOperation(service);
+
         mFileActivity.showLoadingDialog(mFileActivity.getString(R.string.wait_a_moment));
     }
 
@@ -754,7 +789,7 @@ public class FileOperationsHelper {
         mWaitingForOpId = mFileActivity.getOperationsServiceBinder().queueNewOperation(service);
 
         mFileActivity.showLoadingDialog(
-            mFileActivity.getString(R.string.wait_checking_credentials)
+                mFileActivity.getString(R.string.wait_checking_credentials)
         );
     }
 }

+ 4 - 0
src/main/java/com/owncloud/android/ui/preview/PreviewImageFragment.java

@@ -365,6 +365,10 @@ public class PreviewImageFragment extends FileFragment {
                 mContainerActivity.getFileOperationsHelper().syncFile(getFile());
                 return true;
 
+            case R.id.action_set_as_wallpaper:
+                mContainerActivity.getFileOperationsHelper().setPictureAs(getFile());
+                return true;
+
             default:
                 return super.onOptionsItemSelected(item);
         }

+ 4 - 0
src/main/java/com/owncloud/android/utils/MimeTypeUtil.java

@@ -175,6 +175,10 @@ public class MimeTypeUtil {
         return isImage(extractMimeType(file));
     }
 
+    public static boolean isSVG(OCFile file) {
+        return "image/svg+xml".equalsIgnoreCase(file.getMimetype());
+    }
+
     /**
      * @param file the file to be analyzed
      * @return 'True' if the file contains audio

+ 6 - 0
src/main/res/menu/file_actions_menu.xml

@@ -118,6 +118,12 @@
         app:showAsAction="never"
         android:showAsAction="never"
         android:orderInCategory="1" />
+    <item
+        android:id="@+id/action_set_as_wallpaper"
+        android:title="@string/set_picture_as"
+        app:showAsAction="never"
+        android:showAsAction="never"
+        android:orderInCategory="1" />
     <item
         android:id="@+id/action_see_details"
         android:title="@string/actionbar_see_details"

+ 4 - 2
src/main/res/values/strings.xml

@@ -483,6 +483,9 @@
     <string name="file_list__footer__files">%1$d files</string>
     <string name="file_list__footer__files_and_folder">%1$d files, 1 folder</string>
     <string name="file_list__footer__files_and_folders">%1$d files, %2$d folders</string>
+    <string name="set_picture_as">Set picture as</string>
+    <string name="set_as">Set As</string>
+
     <string name="prefs_instant_behaviour_dialogTitle">Original file will be&#8230;</string>
     <string name="prefs_instant_behaviour_title">Original file will be&#8230;</string>
     <string name="upload_copy_files">Copy file</string>
@@ -662,7 +665,6 @@
     <!-- Notifications -->
     <string name="new_notification_received">New notification received</string>
     <string name="drawer_logout">Logout</string>
+    <string name="picture_set_as_no_app">No app found to set a picture with!</string>
     <string name="privacy">Privacy</string>
-
-
 </resources>