wip
authortobiasKaminsky <tobias@kaminsky.me>
Sun, 25 Oct 2015 07:13:38 +0000 (08:13 +0100)
committertobiasKaminsky <tobias@kaminsky.me>
Sun, 25 Oct 2015 07:13:38 +0000 (08:13 +0100)
res/menu/file_actions_menu.xml
res/values/strings.xml
src/com/owncloud/android/media/MediaService.java
src/com/owncloud/android/ui/fragment/OCFileListFragment.java
src/com/owncloud/android/ui/preview/PreviewMediaFragment.java
src/com/owncloud/android/ui/preview/PreviewVideoActivity.java

index 3e6f4cd..cd91616 100644 (file)
         android:icon="@android:drawable/ic_menu_share"
         android:orderInCategory="1" />
     <item
+        android:id="@+id/action_stream_file"
+        android:title="@string/action_stream_file"
+        android:icon="@android:drawable/ic_menu_view"
+        android:orderInCategory="1" />
+    <item
         android:id="@+id/action_unshare_file"
         android:title="@string/action_unshare_file"
         android:icon="@android:drawable/ic_menu_share"
index 267d713..2c101ae 100644 (file)
     <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="action_stream_file">Stream file with external player</string>
 
 </resources>
index e53c635..db64610 100644 (file)
 package com.owncloud.android.media;
 
 import android.accounts.Account;
+import android.app.Activity;
 import android.app.Notification;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
 import android.app.Service;
 import android.content.Context;
+import android.content.DialogInterface;
 import android.content.Intent;
 import android.media.AudioManager;
 import android.media.MediaPlayer;
 import android.media.MediaPlayer.OnCompletionListener;
 import android.media.MediaPlayer.OnErrorListener;
 import android.media.MediaPlayer.OnPreparedListener;
+import android.net.Uri;
 import android.net.wifi.WifiManager;
 import android.net.wifi.WifiManager.WifiLock;
 import android.os.IBinder;
 import android.os.PowerManager;
+import android.support.v7.app.AlertDialog;
 import android.widget.Toast;
 
 import java.io.IOException;
 
 import com.owncloud.android.R;
 import com.owncloud.android.datamodel.OCFile;
+import com.owncloud.android.lib.common.accounts.AccountUtils;
 import com.owncloud.android.lib.common.utils.Log_OC;
 import com.owncloud.android.ui.activity.FileActivity;
 import com.owncloud.android.ui.activity.FileDisplayActivity;
@@ -210,6 +215,24 @@ public class MediaService extends Service implements OnCompletionListener, OnPre
         return context.getString(messageId);
     }
 
+    public static AlertDialog.Builder streamWithExternalApp(final String uri, final Activity activity){
+        AlertDialog.Builder builder = new AlertDialog.Builder(activity);
+        builder.setMessage("May expose password?")
+                .setPositiveButton("Stream", new DialogInterface.OnClickListener() {
+                    public void onClick(DialogInterface dialog, int id) {
+                        Intent i = new Intent(android.content.Intent.ACTION_VIEW);
+                        i.setData(Uri.parse(uri));
+                        activity.startActivity(i);
+                    }
+                })
+                .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
+                    public void onClick(DialogInterface dialog, int id) {
+                        // User cancelled the dialog
+                    }
+                });
+        return builder;
+    }
+
 
     
     /**
@@ -430,12 +453,12 @@ public class MediaService extends Service implements OnCompletionListener, OnPre
         releaseResources(false); // release everything except MediaPlayer
 
         try {
-            if (mFile == null) { 
-                Toast.makeText(this, R.string.media_err_nothing_to_play, Toast.LENGTH_LONG).show();
-                processStopRequest(true);
-                return;
+//            if (mFile == null) {
+//                Toast.makeText(this, R.string.media_err_nothing_to_play, Toast.LENGTH_LONG).show();
+//                processStopRequest(true);
+//                return;
                 
-            } else if (mAccount == null) {
+            if (mAccount == null) {
                 Toast.makeText(this, R.string.media_err_not_in_owncloud, Toast.LENGTH_LONG).show();
                 processStopRequest(true);
                 return;
@@ -444,12 +467,12 @@ public class MediaService extends Service implements OnCompletionListener, OnPre
             createMediaPlayerIfNeeded();
             mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
             String url = mFile.getStoragePath();
-            /* Streaming is not possible right now
+            // Streaming is not possible right now
             if (url == null || url.length() <= 0) {
                 url = AccountUtils.constructFullURLForAccount(this, mAccount) + mFile.getRemotePath();
             }
             mIsStreaming = url.startsWith("http:") || url.startsWith("https:");
-            */
+
             mIsStreaming = false;
             
             mPlayer.setDataSource(url);
@@ -486,6 +509,8 @@ public class MediaService extends Service implements OnCompletionListener, OnPre
             Log_OC.e(TAG, "IllegalArgumentException " + mAccount.name + mFile.getRemotePath(), e);
             Toast.makeText(this, String.format(getString(R.string.media_err_unexpected), mFile.getFileName()), Toast.LENGTH_LONG).show();
             processStopRequest(true);
+        } catch (AccountUtils.AccountNotFoundException e) {
+            e.printStackTrace();
         }
     }
 
index 02bd845..549b763 100644 (file)
  */
 package com.owncloud.android.ui.fragment;
 
+import android.accounts.Account;
+import android.accounts.AccountManager;
+import android.accounts.AuthenticatorException;
+import android.accounts.OperationCanceledException;
 import android.app.Activity;
+import android.content.ActivityNotFoundException;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.DialogInterface;
 import android.content.Intent;
+import android.net.Uri;
 import android.os.Bundle;
 import android.support.v4.widget.SwipeRefreshLayout;
+import android.support.v7.app.AlertDialog;
 import android.view.ContextMenu;
 import android.view.Menu;
 import android.view.MenuInflater;
@@ -35,8 +45,11 @@ import android.widget.AdapterView;
 import android.widget.AdapterView.AdapterContextMenuInfo;
 import android.widget.PopupMenu;
 
+import com.owncloud.android.MainApp;
 import com.owncloud.android.R;
-import com.owncloud.android.authentication.AccountUtils;
+import com.owncloud.android.lib.common.OwnCloudBasicCredentials;
+import com.owncloud.android.lib.common.OwnCloudCredentials;
+import com.owncloud.android.lib.common.accounts.AccountUtils;
 import com.owncloud.android.datamodel.FileDataStorageManager;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.files.FileMenuFilter;
@@ -57,6 +70,7 @@ import com.owncloud.android.utils.FileStorageUtils;
 import com.owncloud.android.ui.preview.PreviewTextFragment;
 
 import java.io.File;
+import java.io.IOException;
 
 /**
  * A Fragment that lists all files and folders in a given path.
@@ -274,15 +288,13 @@ public class OCFileListFragment extends ExtendedListFragment implements FileActi
                     ((FileDisplayActivity)mContainerActivity).startImagePreview(file);
                 } else if (PreviewTextFragment.canBePreviewed(file)){
                     ((FileDisplayActivity)mContainerActivity).startTextPreview(file);
-                } else if (file.isDown()) {
-                    if (PreviewMediaFragment.canBePreviewed(file)) {
+                } else if (PreviewMediaFragment.canBePreviewed(file)) {
                         // media preview
                         ((FileDisplayActivity) mContainerActivity).startMediaPreview(file, 0, true);
-                    } else {
+                    } else if (file.isDown()) {
                         mContainerActivity.getFileOperationsHelper().openFile(file);
                     }
-
-                } else {
+                else {
                     // automatic download, preview on finish
                     ((FileDisplayActivity) mContainerActivity).startDownloadForPreview(file);
                 }
@@ -379,13 +391,98 @@ public class OCFileListFragment extends ExtendedListFragment implements FileActi
             }
             case R.id.action_send_file: {
                 // Obtain the file
-                if (!mTargetFile.isDown()) {  // Download the file
-                    Log_OC.d(TAG, mTargetFile.getRemotePath() + " : File must be downloaded");
-                    ((FileDisplayActivity) mContainerActivity).startDownloadForSending(mTargetFile);
-
-                } else {
-                    mContainerActivity.getFileOperationsHelper().sendDownloadedFile(mTargetFile);
+//                if (!mTargetFile.isDown()) {  // Download the file
+//                    Log_OC.d(TAG, mTargetFile.getRemotePath() + " : File must be downloaded");
+//                    ((FileDisplayActivity) mContainerActivity).startDownloadForSending(mTargetFile);
+//
+//                } else {
+                    // mContainerActivity.getFileOperationsHelper().sendDownloadedFile(mTargetFile);
+
+//                String url = "https://test:teddy03@192.168.0.100/owncloud/remote.php/webdav/2/1.ogg";
+//                String url = "https://test:test@demo.owncloud.org/remote.php/webdav/Demo%20Movie%20OGG%20-%20Big%20Buck%20Bunny%20Trailer.ogg";
+
+
+//                try{
+//                    Intent i = new Intent(Intent.ACTION_VIEW);
+//                    i.setComponent(new ComponentName("org.videolan.vlc.betav7neon", "org.videolan.vlc.betav7neon.gui.video.VideoPlayerActivity"));
+//                    i.setData(Uri.parse(url));
+//                    startActivity(i);
+//                }
+//                catch (ActivityNotFoundException e){
+//                    Uri uri = Uri.parse("http://play.google.com/store/apps/details?id=org.videolan.vlc.betav7neon");
+//                    Intent intent = new Intent (Intent.ACTION_VIEW, uri);
+//                    startActivity(intent);
+//                }
+//
+
+                // TODO TOBI neuer Menüpunkt: Stream
+
+                try {
+                    Context context = MainApp.getAppContext();
+                    Account account = mContainerActivity.getStorageManager().getAccount();
+                    String url = AccountUtils.constructFullURLForAccount(context, account) + mTargetFile.getRemotePath();
+
+                    OwnCloudCredentials credentials = AccountUtils.getCredentialsForAccount(context, account);
+
+                    url = url.replace("//", "//" + credentials.getUsername() + ":" + credentials.getAuthToken() + "@");
+
+                    Log_OC.d(TAG, "Streaming url: " + url);
+                    // VLC
+                    Intent i = new Intent(Intent.ACTION_VIEW);
+                    i.setComponent(new ComponentName("org.videolan.vlc.betav7neon", "org.videolan.vlc.betav7neon.gui.video.VideoPlayerActivity"));
+                    i.setData(Uri.parse(url));
+                    startActivity(i);
+
+                    // MX
+//                    Intent i = new Intent(android.content.Intent.ACTION_VIEW);
+//                    i.setData(Uri.parse(url));
+//                    startActivity(i);
+                } catch (AccountUtils.AccountNotFoundException e) {
+                    e.printStackTrace();
+                }
+                catch (ActivityNotFoundException e) {
+                    // VLC
+                    Uri uri = Uri.parse("http://play.google.com/store/apps/details?id=org.videolan.vlc.betav7neon");
+                    Intent intent = new Intent(Intent.ACTION_VIEW, uri);
+                    startActivity(intent);
+                } catch (AuthenticatorException e) {
+                    e.printStackTrace();
+                } catch (OperationCanceledException e) {
+                    e.printStackTrace();
+                } catch (IOException e) {
+                    e.printStackTrace();
                 }
+
+
+//                }
+                return true;
+            }
+            case R.id.action_stream_file: {
+                AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+                builder.setMessage("May expose password?")
+                        .setPositiveButton("Stream", new DialogInterface.OnClickListener() {
+                            public void onClick(DialogInterface dialog, int id) {
+                                Account account = ((FileActivity)mContainerActivity).getAccount();
+                                Context context = MainApp.getAppContext();
+                                String uri = PreviewMediaFragment.generateUrlWithCredentials(account, context, mTargetFile);
+
+                                Intent i = new Intent(android.content.Intent.ACTION_VIEW);
+                                i.setData(Uri.parse(uri));
+                                startActivity(i);
+
+//                    Intent i = new Intent(Intent.ACTION_VIEW);
+//                    i.setComponent(new ComponentName("org.videolan.vlc", "org.videolan.vlc.gui.video.VideoPlayerActivity"));
+//                    i.setData(Uri.parse(uri));
+//                    startActivity(i);
+                            }
+                        })
+                        .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
+                            public void onClick(DialogInterface dialog, int id) {
+                                // User cancelled the dialog
+                            }
+                        });
+                builder.show();
+
                 return true;
             }
             case R.id.action_move: {
@@ -518,7 +615,7 @@ public class OCFileListFragment extends ExtendedListFragment implements FileActi
             setFooterText(generateFooterText(filesCount, foldersCount));
 
             // decide grid vs list view
-            OwnCloudVersion version = AccountUtils.getServerVersion(
+            OwnCloudVersion version = com.owncloud.android.authentication.AccountUtils.getServerVersion(
                     ((FileActivity)mContainerActivity).getAccount());
             if (version != null && version.supportsRemoteThumbnails() &&
                 imagesCount > 0 && imagesCount == filesCount) {
index 0dbb1a3..21be61d 100644 (file)
 package com.owncloud.android.ui.preview;
 
 import android.accounts.Account;
+import android.accounts.AuthenticatorException;
+import android.accounts.OperationCanceledException;
 import android.app.Activity;
+import android.content.ActivityNotFoundException;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.media.MediaMetadataRetriever;
+import android.os.AsyncTask;
 import android.support.v7.app.AlertDialog;
 import android.content.ComponentName;
 import android.content.Context;
@@ -52,9 +56,16 @@ import android.widget.ImageView;
 import android.widget.Toast;
 import android.widget.VideoView;
 
+import com.owncloud.android.MainApp;
 import com.owncloud.android.R;
 import com.owncloud.android.datamodel.OCFile;
+import com.owncloud.android.datamodel.ThumbnailsCacheManager;
 import com.owncloud.android.files.FileMenuFilter;
+import com.owncloud.android.lib.common.OwnCloudAccount;
+import com.owncloud.android.lib.common.OwnCloudClient;
+import com.owncloud.android.lib.common.OwnCloudClientManagerFactory;
+import com.owncloud.android.lib.common.OwnCloudCredentials;
+import com.owncloud.android.lib.common.accounts.AccountUtils;
 import com.owncloud.android.lib.common.utils.Log_OC;
 import com.owncloud.android.media.MediaControlView;
 import com.owncloud.android.media.MediaService;
@@ -64,6 +75,9 @@ import com.owncloud.android.ui.dialog.ConfirmationDialogFragment;
 import com.owncloud.android.ui.dialog.RemoveFileDialogFragment;
 import com.owncloud.android.ui.fragment.FileFragment;
 
+import java.io.IOException;
+import java.util.concurrent.ExecutionException;
+
 
 /**
  * This fragment shows a preview of a downloaded media file (audio or video).
@@ -87,6 +101,7 @@ public class PreviewMediaFragment extends FileFragment implements
     private ImageView mImagePreview;
     private VideoView mVideoPreview;
     private int mSavedPlaybackPosition;
+    private String mUri;
 
     private MediaServiceBinder mMediaServiceBinder = null;
     private MediaControlView mMediaController = null;
@@ -184,9 +199,9 @@ public class PreviewMediaFragment extends FileFragment implements
             if (mAccount == null) {
                 throw new IllegalStateException("Instanced with a NULL ownCloud Account");
             }
-            if (!file.isDown()) {
-                throw new IllegalStateException("There is no local file to preview");
-            }
+//            if (!file.isDown()) {
+//                throw new IllegalStateException("There is no local file to preview");
+//            }
 
         }
         else {
@@ -198,7 +213,7 @@ public class PreviewMediaFragment extends FileFragment implements
             mAutoplay = savedInstanceState.getBoolean(PreviewMediaFragment.EXTRA_PLAYING);
 
         }
-        if (file != null && file.isDown()) {
+        if (file != null) {
             if (file.isVideo()) {
                 mVideoPreview.setVisibility(View.VISIBLE);
                 mImagePreview.setVisibility(View.GONE);
@@ -271,7 +286,7 @@ public class PreviewMediaFragment extends FileFragment implements
         Log_OC.e(TAG, "onStart");
 
         OCFile file = getFile();
-        if (file != null && file.isDown()) {
+        if (file != null) {
             if (file.isAudio()) {
                 bindMediaService();
 
@@ -431,8 +446,65 @@ public class PreviewMediaFragment extends FileFragment implements
 
         // load the video file in the video player ; 
         // when done, VideoHelper#onPrepared() will be called
-        Uri uri = Uri.parse(getFile().getStoragePath());
-        mVideoPreview.setVideoPath(uri.encode(getFile().getStoragePath()));
+        if (getFile().isDown()) {
+            mUri = getFile().getStoragePath();
+        } else {
+            Context context = MainApp.getAppContext();
+            Account account = mContainerActivity.getStorageManager().getAccount();
+
+            mUri = generateUrlWithCredentials(account, context, getFile());
+        }
+
+        mVideoPreview.setVideoPath(mUri);
+    }
+
+    public static String generateUrlWithCredentials(Account account, Context context, OCFile file){
+        OwnCloudAccount ocAccount = null;
+        try {
+            ocAccount = new OwnCloudAccount(account, context);
+
+            final ClientGenerationTask task = new ClientGenerationTask();
+            task.execute(ocAccount);
+
+            OwnCloudClient mClient = task.get();
+            String url = AccountUtils.constructFullURLForAccount(context, account) + Uri.encode(file.getRemotePath(), "/");
+            OwnCloudCredentials credentials = mClient.getCredentials();
+
+            return url.replace("//", "//" + credentials.getUsername() + ":" + credentials.getAuthToken() + "@");
+
+        } catch (AccountUtils.AccountNotFoundException e) {
+            e.printStackTrace();
+
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        } catch (ExecutionException e) {
+            e.printStackTrace();
+        }
+        return "";
+    }
+
+    public static class ClientGenerationTask extends AsyncTask<Object, Void, OwnCloudClient> {
+        @Override
+        protected OwnCloudClient doInBackground(Object... params) {
+            Object account = params[0];
+            if (account instanceof OwnCloudAccount){
+                try {
+                    OwnCloudAccount ocAccount = (OwnCloudAccount) account;
+                    return OwnCloudClientManagerFactory.getDefaultSingleton().
+                            getClientFor(ocAccount, MainApp.getAppContext());
+                } catch (AccountUtils.AccountNotFoundException e) {
+                    e.printStackTrace();
+                } catch (OperationCanceledException e) {
+                    e.printStackTrace();
+                } catch (AuthenticatorException e) {
+                    e.printStackTrace();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+
+            return null;
+        }
     }
 
 
@@ -443,7 +515,7 @@ public class PreviewMediaFragment extends FileFragment implements
          * <p/>
          * Just starts the playback.
          *
-         * @param   vp    {@link MediaPlayer} instance performing the playback.
+         * @param vp {@link MediaPlayer} instance performing the playback.
          */
         @Override
         public void onPrepared(MediaPlayer vp) {
@@ -474,8 +546,7 @@ public class PreviewMediaFragment extends FileFragment implements
                 if (Build.VERSION.SDK_INT == Build.VERSION_CODES.GINGERBREAD) {
                     mVideoPreview.pause();
 
-                }
-                else {
+                } else {
                     if (Build.VERSION.SDK_INT == Build.VERSION_CODES.GINGERBREAD_MR1) {
                         // mVideePreview.pause() is not enough
 
@@ -500,27 +571,40 @@ public class PreviewMediaFragment extends FileFragment implements
          */
         @Override
         public boolean onError(MediaPlayer mp, int what, int extra) {
-            if (mVideoPreview.getWindowToken() != null) {
-                String message = MediaService.getMessageForMediaError(
-                        getActivity(), what, extra);
-                new AlertDialog.Builder(getActivity())
-                        .setMessage(message)
-                        .setPositiveButton(android.R.string.VideoView_error_button,
-                                new DialogInterface.OnClickListener() {
-                                    public void onClick(DialogInterface dialog, int whichButton) {
-                                        dialog.dismiss();
-                                        VideoHelper.this.onCompletion(null);
-                                    }
-                                })
-                        .setCancelable(false)
-                        .show();
-            }
+//            if (mVideoPreview.getWindowToken() != null) {
+                // try to open with another app
+//                try{
+//                    AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+//                    builder.setMessage("May expose password?")
+//                            .setPositiveButton("Stream", new DialogInterface.OnClickListener() {
+//                                public void onClick(DialogInterface dialog, int id) {
+//                                    Intent i = new Intent(android.content.Intent.ACTION_VIEW);
+//                                    i.setData(Uri.parse(mUri));
+//                                    startActivity(i);
+//                                }
+//                            })
+//                            .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
+//                                public void onClick(DialogInterface dialog, int id) {
+//                                    // User cancelled the dialog
+//                                }
+//                            });
+//                    builder.show();
+
+                MediaService.streamWithExternalApp(mUri, getActivity()).show();
+
+//                }
+//                catch (ActivityNotFoundException e){
+//                    Intent i = new Intent(android.content.Intent.ACTION_VIEW);
+//                    i.setData(Uri.parse(mUri));
+//                    startActivity(i);
+//                }
+//            }
+//            }
             return true;
-        }
 
+        }
     }
 
-
     @Override
     public void onPause() {
         Log_OC.e(TAG, "onPause");
index 42b7fb2..4ba5326 100644 (file)
@@ -209,12 +209,13 @@ public class PreviewVideoActivity extends FileActivity implements OnCompletionLi
                 } else {
                     // not working yet
                     String url;
-                    try {
-                        url = AccountUtils.constructFullURLForAccount(this, getAccount()) + file.getRemotePath();
+//                    try {
+//                        url = AccountUtils.constructFullURLForAccount(this, getAccount()) + file.getRemotePath();
+                        url = PreviewMediaFragment.generateUrlWithCredentials(getAccount(), getApplicationContext(), getFile());
                         mVideoPlayer.setVideoURI(Uri.parse(url));
-                    } catch (AccountNotFoundException e) {
-                        onError(null, MediaService.OC_MEDIA_ERROR, R.string.media_err_no_account);
-                    }
+//                    } catch (AccountNotFoundException e) {
+//                        onError(null, MediaService.OC_MEDIA_ERROR, R.string.media_err_no_account);
+//                    }
                 }
                 
                 // create and prepare control panel for the user