[Android] [PATCH] Use Uri in VideoPlayer and MediaDatabase

Thomas Guillem thomas at gllm.fr
Fri Jun 5 15:53:19 CEST 2015


---
 .../src/org/videolan/vlc/MediaDatabase.java        |  63 ++++++++-----
 vlc-android/src/org/videolan/vlc/MediaGroup.java   |   2 +-
 vlc-android/src/org/videolan/vlc/MediaLibrary.java |   8 +-
 vlc-android/src/org/videolan/vlc/MediaWrapper.java |  28 ++----
 .../src/org/videolan/vlc/MediaWrapperList.java     |   5 +-
 .../src/org/videolan/vlc/PlaybackService.java      |   8 +-
 .../src/org/videolan/vlc/gui/MainActivity.java     |   6 +-
 .../vlc/gui/browser/BaseBrowserFragment.java       |   8 +-
 .../vlc/gui/browser/FileBrowserFragment.java       |   2 +-
 .../vlc/gui/browser/StorageBrowserAdapter.java     |   3 +-
 .../videolan/vlc/gui/video/MediaInfoFragment.java  |   2 +-
 .../videolan/vlc/gui/video/VideoGridFragment.java  |   2 +-
 .../vlc/gui/video/VideoPlayerActivity.java         | 103 +++++++++------------
 .../src/org/videolan/vlc/util/BitmapUtil.java      |   2 +-
 vlc-android/src/org/videolan/vlc/util/Util.java    |   3 +-
 .../org/videolan/vlc/gui/tv/MainTvActivity.java    |   2 +-
 .../vlc/gui/tv/MediaItemDetailsFragment.java       |   3 +-
 .../vlc/gui/tv/RecommendationsService.java         |   4 +-
 18 files changed, 122 insertions(+), 132 deletions(-)

diff --git a/vlc-android/src/org/videolan/vlc/MediaDatabase.java b/vlc-android/src/org/videolan/vlc/MediaDatabase.java
index 6d3b648..abba0c9 100644
--- a/vlc-android/src/org/videolan/vlc/MediaDatabase.java
+++ b/vlc-android/src/org/videolan/vlc/MediaDatabase.java
@@ -24,12 +24,12 @@ import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Locale;
-import java.util.Set;
 
 import android.content.ContentValues;
 import android.content.Context;
@@ -44,6 +44,8 @@ import android.net.Uri;
 import android.support.annotation.Nullable;
 import android.util.Log;
 
+import org.videolan.libvlc.util.AndroidUtil;
+
 public class MediaDatabase {
     public final static String TAG = "VLC/MediaDatabase";
 
@@ -395,7 +397,7 @@ public class MediaDatabase {
      */
     public void playlistDelete(String name) {
         mDb.delete(PLAYLIST_TABLE_NAME, PLAYLIST_NAME + "=?",
-                new String[] { name });
+                new String[]{name});
         mDb.delete(PLAYLIST_MEDIA_TABLE_NAME, PLAYLIST_MEDIA_PLAYLISTNAME
                 + "=?", new String[] { name });
     }
@@ -539,7 +541,7 @@ public class MediaDatabase {
         values.put(PLAYLIST_MEDIA_PLAYLISTNAME, newPlaylistName);
         mDb.update(PLAYLIST_MEDIA_TABLE_NAME, values,
                 PLAYLIST_MEDIA_PLAYLISTNAME + " =?",
-                new String[] { playlistName });
+                new String[]{playlistName});
 
         return true;
     }
@@ -559,7 +561,7 @@ public class MediaDatabase {
 
         ContentValues values = new ContentValues();
 
-        values.put(MEDIA_LOCATION, media.getLocation());
+        values.put(MEDIA_LOCATION, media.getUri().toString());
         values.put(MEDIA_TIME, media.getTime());
         values.put(MEDIA_LENGTH, media.getLength());
         values.put(MEDIA_TYPE, media.getType());
@@ -586,12 +588,12 @@ public class MediaDatabase {
      * @param location of the item (primary key)
      * @return True if the item exists, false if it does not
      */
-    public synchronized boolean mediaItemExists(String location) {
+    public synchronized boolean mediaItemExists(Uri uri) {
         try {
             Cursor cursor = mDb.query(MEDIA_TABLE_NAME,
                     new String[] { MEDIA_LOCATION },
                     MEDIA_LOCATION + "=?",
-                    new String[] { location },
+                    new String[] { uri.toString() },
                     null, null, null);
             boolean exists = cursor.moveToFirst();
             cursor.close();
@@ -682,8 +684,8 @@ public class MediaDatabase {
             if (cursor.moveToFirst()) {
                 try {
                     do {
-                        String location = cursor.getString(0);
-                        MediaWrapper media = new MediaWrapper(location,
+                        final Uri uri = AndroidUtil.LocationToUri(cursor.getString(0));
+                        MediaWrapper media = new MediaWrapper(uri,
                                 cursor.getLong(1),      // MEDIA_TIME
                                 cursor.getLong(2),      // MEDIA_LENGTH
                                 cursor.getInt(3),       // MEDIA_TYPE
@@ -701,7 +703,7 @@ public class MediaDatabase {
                                 cursor.getInt(14),      // MEDIA_TRACKNUMBER
                                 cursor.getInt(15),     // MEDIA_DISCNUMBER
                                 cursor.getLong(16));     // MEDIA_LAST_MODIFIED
-                        medias.put(media.getLocation(), media);
+                        medias.put(media.getUri().toString(), media);
 
                         count++;
                     } while (cursor.moveToNext());
@@ -750,7 +752,7 @@ public class MediaDatabase {
         return times;
     }
 
-    public synchronized MediaWrapper getMedia(String location) {
+    public synchronized MediaWrapper getMedia(Uri uri) {
 
         Cursor cursor;
         MediaWrapper media = null;
@@ -777,14 +779,14 @@ public class MediaDatabase {
                         MEDIA_LAST_MODIFIED, //15 long
                 },
                 MEDIA_LOCATION + "=?",
-                new String[] { location },
+                new String[] { uri.toString() },
                 null, null, null);
         } catch(IllegalArgumentException e) {
             // java.lang.IllegalArgumentException: the bind value at index 1 is null
             return null;
         }
         if (cursor.moveToFirst()) {
-            media = new MediaWrapper(location,
+            media = new MediaWrapper(uri,
                     cursor.getLong(0),
                     cursor.getLong(1),
                     cursor.getInt(2),
@@ -807,7 +809,7 @@ public class MediaDatabase {
         return media;
     }
 
-    public synchronized Bitmap getPicture(String location) {
+    public synchronized Bitmap getPicture(Uri uri) {
         /* Used for the lazy loading */
         Cursor cursor;
         Bitmap picture = null;
@@ -817,7 +819,7 @@ public class MediaDatabase {
                 MEDIA_TABLE_NAME,
                 new String[] { MEDIA_PICTURE },
                 MEDIA_LOCATION + "=?",
-                new String[] { location },
+                new String[] { uri.toString() },
                 null, null, null);
         if (cursor.moveToFirst()) {
             blob = cursor.getBlob(0);
@@ -835,25 +837,36 @@ public class MediaDatabase {
         return picture;
     }
 
-    public synchronized void removeMedia(String location) {
-        mDb.delete(MEDIA_TABLE_NAME, MEDIA_LOCATION + "=?", new String[] { location });
+    public synchronized void removeMedia(Uri uri) {
+        mDb.delete(MEDIA_TABLE_NAME, MEDIA_LOCATION + "=?", new String[]{uri.toString()});
+    }
+
+    public void removeMedias(Collection<Uri> uris) {
+        mDb.beginTransaction();
+        try {
+            for (Uri uri : uris)
+                removeMedia(uri);
+            mDb.setTransactionSuccessful();
+        } finally {
+            mDb.endTransaction();
+        }
     }
 
-    public void removeMedias(Set<String> locations) {
+    public void removeMediaWrappers(Collection<MediaWrapper> mws) {
         mDb.beginTransaction();
         try {
-            for (String location : locations)
-                mDb.delete(MEDIA_TABLE_NAME, MEDIA_LOCATION + "=?", new String[] { location });
+            for (MediaWrapper mw : mws)
+                removeMedia(mw.getUri());
             mDb.setTransactionSuccessful();
         } finally {
             mDb.endTransaction();
         }
     }
 
-    public synchronized void updateMedia(String location, mediaColumn col,
+    public synchronized void updateMedia(Uri uri, mediaColumn col,
             Object object) {
 
-        if (location == null)
+        if (uri == null)
             return;
 
         ContentValues values = new ContentValues();
@@ -888,7 +901,7 @@ public class MediaDatabase {
             default:
                 return;
         }
-        mDb.update(MEDIA_TABLE_NAME, values, MEDIA_LOCATION + "=?", new String[]{location});
+        mDb.update(MEDIA_TABLE_NAME, values, MEDIA_LOCATION + "=?", new String[]{uri.toString()});
     }
 
     /**
@@ -1061,7 +1074,7 @@ public class MediaDatabase {
                 null, null, null, null, null);
 
         while (cursor.moveToNext()) {
-            mw = new MediaWrapper(Uri.decode(cursor.getString(0)));
+            mw = new MediaWrapper(AndroidUtil.LocationToUri(cursor.getString(0)));
             mw.setTitle(Uri.decode(cursor.getString(1)));
             mw.setType(MediaWrapper.TYPE_DIR);
             favs.add(mw);
@@ -1089,8 +1102,8 @@ public class MediaDatabase {
         Log.d(TAG, "Setting new picture for " + m.getTitle());
         try {
             getInstance().updateMedia(
-                m.getLocation(),
-                mediaColumn.MEDIA_PICTURE,
+                m.getUri(),
+                    mediaColumn.MEDIA_PICTURE,
                 p);
         } catch (SQLiteFullException e) {
             Log.d(TAG, "SQLiteFullException while setting picture");
diff --git a/vlc-android/src/org/videolan/vlc/MediaGroup.java b/vlc-android/src/org/videolan/vlc/MediaGroup.java
index a5c0c4b..c9597c2 100644
--- a/vlc-android/src/org/videolan/vlc/MediaGroup.java
+++ b/vlc-android/src/org/videolan/vlc/MediaGroup.java
@@ -35,7 +35,7 @@ public class MediaGroup extends MediaWrapper {
 
     public MediaGroup(MediaWrapper media)
     {
-        super(media.getLocation(),
+        super(media.getUri(),
                 media.getTime(),
                 media.getLength(),
                 MediaWrapper.TYPE_GROUP,
diff --git a/vlc-android/src/org/videolan/vlc/MediaLibrary.java b/vlc-android/src/org/videolan/vlc/MediaLibrary.java
index afe9ce6..2df4fea 100644
--- a/vlc-android/src/org/videolan/vlc/MediaLibrary.java
+++ b/vlc-android/src/org/videolan/vlc/MediaLibrary.java
@@ -201,7 +201,7 @@ public class MediaLibrary {
                 continue;
             playList = new AudioBrowserListAdapter.ListItem(playlistName, null, null, false);
             for (String track : items){
-                playList.mMediaList.add(new MediaWrapper(track));
+                playList.mMediaList.add(new MediaWrapper(AndroidUtil.LocationToUri(track)));
             }
             playlistItems.add(playList);
         }
@@ -338,14 +338,14 @@ public class MediaLibrary {
                 }
 
                 //Remove ignored files
-                HashSet<String> mediasToRemove = new HashSet<String>();
+                HashSet<Uri> mediasToRemove = new HashSet<Uri>();
                 String path;
                 outloop:
                 for (Map.Entry<String, MediaWrapper> entry : existingMedias.entrySet()){
                     path = entry.getKey();
                     for (String dirPath : dirsToIgnore) {
                         if (path.startsWith(dirPath)) {
-                            mediasToRemove.add(path);
+                            mediasToRemove.add(entry.getValue().getUri());
                             mItemList.remove(existingMedias.get(path));
                             continue outloop;
                         }
@@ -408,7 +408,7 @@ public class MediaLibrary {
                     for (String fileURI : addedLocations) {
                         existingMedias.remove(fileURI);
                     }
-                    mediaDatabase.removeMedias(existingMedias.keySet());
+                    mediaDatabase.removeMediaWrappers(existingMedias.values());
 
                     /*
                      * In case of file matching path of a folder from another removable storage
diff --git a/vlc-android/src/org/videolan/vlc/MediaWrapper.java b/vlc-android/src/org/videolan/vlc/MediaWrapper.java
index 9d89c90..146c7a4 100644
--- a/vlc-android/src/org/videolan/vlc/MediaWrapper.java
+++ b/vlc-android/src/org/videolan/vlc/MediaWrapper.java
@@ -24,6 +24,7 @@ import java.io.File;
 import java.util.Locale;
 
 import org.videolan.libvlc.MediaPlayer;
+import org.videolan.libvlc.util.AndroidUtil;
 import org.videolan.libvlc.util.Extensions;
 import org.videolan.libvlc.Media;
 import org.videolan.libvlc.Media.VideoTrack;
@@ -79,24 +80,15 @@ public class MediaWrapper implements Parcelable {
     private int mFlags = 0;
     private long mLastModified = 0l;
 
-    private static Uri getUri(String mrl) {
-        Uri uri = Uri.parse(mrl);
-        if (uri.getScheme() == null) {
-            Log.w(TAG, "invalid mrl: " + mrl);
-            return Uri.fromFile(new File(mrl));
-        } else
-            return uri;
-    }
-
     /**
      * Create a new MediaWrapper
-     * @param mrl Should not be null.
+     * @param uri Should not be null.
      */
-    public MediaWrapper(String mrl) {
-        if (mrl == null)
-            throw new NullPointerException("mrl was null");
+    public MediaWrapper(Uri uri) {
+        if (uri == null)
+            throw new NullPointerException("uri was null");
 
-        mUri = getUri(mrl);
+        mUri = uri;
         init(null);
     }
 
@@ -180,10 +172,10 @@ public class MediaWrapper implements Parcelable {
         mLastModified = lastModified;
     }
 
-    public MediaWrapper(String location, long time, long length, int type,
+    public MediaWrapper(Uri uri, long time, long length, int type,
                  Bitmap picture, String title, String artist, String genre, String album, String albumArtist,
                  int width, int height, String artworkURL, int audio, int spu, int trackNumber, int discNumber, long lastModified) {
-        mUri = getUri(location);
+        mUri = uri;
         init(time, length, type, picture, title, artist, genre, album, albumArtist,
              width, height, artworkURL, audio, spu, trackNumber, discNumber, lastModified);
     }
@@ -446,7 +438,7 @@ public class MediaWrapper implements Parcelable {
     }
 
     public MediaWrapper(Parcel in) {
-        mUri = getUri(in.readString());
+        mUri = in.readParcelable(Uri.class.getClassLoader());
         init(in.readLong(),
                 in.readLong(),
                 in.readInt(),
@@ -468,7 +460,7 @@ public class MediaWrapper implements Parcelable {
 
     @Override
     public void writeToParcel(Parcel dest, int flags) {
-        dest.writeString(getLocation());
+        dest.writeParcelable(mUri, flags);
         dest.writeLong(getTime());
         dest.writeLong(getLength());
         dest.writeInt(getType());
diff --git a/vlc-android/src/org/videolan/vlc/MediaWrapperList.java b/vlc-android/src/org/videolan/vlc/MediaWrapperList.java
index 73dae5f..064d3fd 100644
--- a/vlc-android/src/org/videolan/vlc/MediaWrapperList.java
+++ b/vlc-android/src/org/videolan/vlc/MediaWrapperList.java
@@ -20,6 +20,7 @@
  *****************************************************************************/
 package org.videolan.vlc;
 
+import android.net.Uri;
 import android.support.annotation.Nullable;
 
 import java.util.ArrayList;
@@ -89,8 +90,8 @@ public class MediaWrapperList {
         return position >= 0 && position < mInternalList.size();
     }
 
-    public void insert(int position, String mrl) {
-        insert(position, new MediaWrapper(mrl));
+    public void insert(int position, Uri uri) {
+        insert(position, new MediaWrapper(uri));
     }
     public void insert(int position, MediaWrapper media) {
         mInternalList.add(position, media);
diff --git a/vlc-android/src/org/videolan/vlc/PlaybackService.java b/vlc-android/src/org/videolan/vlc/PlaybackService.java
index 7da8762..25871d9 100644
--- a/vlc-android/src/org/videolan/vlc/PlaybackService.java
+++ b/vlc-android/src/org/videolan/vlc/PlaybackService.java
@@ -476,10 +476,10 @@ public class PlaybackService extends Service {
                     service.executeUpdate();
                     service.executeUpdateProgress();
 
-                    String location = service.mMediaListPlayer.getMediaList().getMRL(service.mCurrentIndex);
+                    final Uri uri = service.mMediaListPlayer.getMediaList().getMedia(service.mCurrentIndex).getUri();
                     long length = service.MediaPlayer().getLength();
                     MediaDatabase dbManager = MediaDatabase.getInstance();
-                    MediaWrapper m = dbManager.getMedia(location);
+                    MediaWrapper m = dbManager.getMedia(uri);
                     /**
                      * 1) There is a media to update
                      * 2) It has a length of 0
@@ -488,7 +488,7 @@ public class PlaybackService extends Service {
                      * (don't want to replace a 0 with a 0)
                      */
                     if(m != null && m.getLength() == 0 && length > 0) {
-                        dbManager.updateMedia(location,
+                        dbManager.updateMedia(uri,
                                 MediaDatabase.mediaColumn.MEDIA_LENGTH, length);
                     }
 
@@ -1346,7 +1346,7 @@ public class PlaybackService extends Service {
 
             for (int i = 0; i < mediaPathList.size(); i++) {
                 String location = mediaPathList.get(i);
-                MediaWrapper mediaWrapper = db.getMedia(location);
+                MediaWrapper mediaWrapper = db.getMedia(AndroidUtil.LocationToUri(location));
                 if (mediaWrapper == null) {
                     if (!validateLocation(location)) {
                         Log.w(TAG, "Invalid location " + location);
diff --git a/vlc-android/src/org/videolan/vlc/gui/MainActivity.java b/vlc-android/src/org/videolan/vlc/gui/MainActivity.java
index 52422f1..8914c10 100644
--- a/vlc-android/src/org/videolan/vlc/gui/MainActivity.java
+++ b/vlc-android/src/org/videolan/vlc/gui/MainActivity.java
@@ -503,9 +503,9 @@ public class MainActivity extends AudioPlayerContainerActivity implements OnItem
                     Intent i = new Intent(PlaybackService.ACTION_REMOTE_LAST_PLAYLIST);
                     sendBroadcast(i);
                 } else if (current instanceof VideoGridFragment) {
-                    String location = Uri.decode(mSettings.getString(PreferencesActivity.VIDEO_LAST, null));
-                    if (location != null)
-                        VideoPlayerActivity.start(this, location);
+                    final Uri uri = Uri.parse(mSettings.getString(PreferencesActivity.VIDEO_LAST, null));
+                    if (uri != null)
+                        VideoPlayerActivity.start(this, uri);
                 }
                 break;
             case android.R.id.home:
diff --git a/vlc-android/src/org/videolan/vlc/gui/browser/BaseBrowserFragment.java b/vlc-android/src/org/videolan/vlc/gui/browser/BaseBrowserFragment.java
index fb0bd5d..76e98a5 100644
--- a/vlc-android/src/org/videolan/vlc/gui/browser/BaseBrowserFragment.java
+++ b/vlc-android/src/org/videolan/vlc/gui/browser/BaseBrowserFragment.java
@@ -421,14 +421,14 @@ public abstract class BaseBrowserFragment extends MediaBrowserFragment implement
             case  R.id.directory_view_info:
                 Intent i = new Intent(getActivity(), SecondaryActivity.class);
                 i.putExtra("fragment", "mediaInfo");
-                i.putExtra("param", mw.getLocation());
+                i.putExtra("param", mw.getUri().toString());
                 startActivity(i);
                 return true;
             case R.id.directory_view_play_audio:
                 PlaybackServiceController.getInstance().load(mw);
                 return true;
             case  R.id.directory_view_play_video:
-                VideoPlayerActivity.start(getActivity(), mw.getLocation());
+                VideoPlayerActivity.start(getActivity(), mw.getUri());
                 return true;
             case R.id.directory_view_play_folder:
                 ArrayList<MediaWrapper> mediaList = new ArrayList<MediaWrapper>();
@@ -481,7 +481,7 @@ public abstract class BaseBrowserFragment extends MediaBrowserFragment implement
         while (mCurrentParsedPosition <mAdapter.getItemCount()){
             item = mAdapter.getItem(mCurrentParsedPosition);
             if (item instanceof BaseBrowserAdapter.Storage) {
-                mw = new MediaWrapper(((BaseBrowserAdapter.Storage) item).getPath());
+                mw = new MediaWrapper(AndroidUtil.LocationToUri(((BaseBrowserAdapter.Storage) item).getPath()));
                 mw.setType(MediaWrapper.TYPE_DIR);
             } else  if (item instanceof MediaWrapper){
                 mw = (MediaWrapper) item;
@@ -533,7 +533,7 @@ public abstract class BaseBrowserFragment extends MediaBrowserFragment implement
                     if (mw.getType() == MediaWrapper.TYPE_DIR || mw.getType() == MediaWrapper.TYPE_PLAYLIST)
                         break;
                 } else if (mAdapter.getItem(mCurrentParsedPosition) instanceof BaseBrowserAdapter.Storage) {
-                    mw = new MediaWrapper(((BaseBrowserAdapter.Storage) mAdapter.getItem(mCurrentParsedPosition)).getPath());
+                    mw = new MediaWrapper(AndroidUtil.LocationToUri(((BaseBrowserAdapter.Storage) mAdapter.getItem(mCurrentParsedPosition)).getPath()));
                     break;
                 } else
                     mw = null;
diff --git a/vlc-android/src/org/videolan/vlc/gui/browser/FileBrowserFragment.java b/vlc-android/src/org/videolan/vlc/gui/browser/FileBrowserFragment.java
index 29713bb..f646c89 100644
--- a/vlc-android/src/org/videolan/vlc/gui/browser/FileBrowserFragment.java
+++ b/vlc-android/src/org/videolan/vlc/gui/browser/FileBrowserFragment.java
@@ -99,7 +99,7 @@ public class FileBrowserFragment extends BaseBrowserFragment {
                 for (String mediaDirLocation : storages) {
                     if (!(new File(mediaDirLocation).exists()))
                         continue;
-                    directory = new MediaWrapper(mediaDirLocation);
+                    directory = new MediaWrapper(AndroidUtil.PathToUri(mediaDirLocation));
                     directory.setType(MediaWrapper.TYPE_DIR);
                     if (TextUtils.equals(AndroidDevices.EXTERNAL_PUBLIC_DIRECTORY, mediaDirLocation))
                         directory.setTitle(getString(R.string.internal_memory));
diff --git a/vlc-android/src/org/videolan/vlc/gui/browser/StorageBrowserAdapter.java b/vlc-android/src/org/videolan/vlc/gui/browser/StorageBrowserAdapter.java
index de7fdec..3fbc83f 100644
--- a/vlc-android/src/org/videolan/vlc/gui/browser/StorageBrowserAdapter.java
+++ b/vlc-android/src/org/videolan/vlc/gui/browser/StorageBrowserAdapter.java
@@ -31,6 +31,7 @@ import android.view.ViewGroup;
 import android.widget.CheckBox;
 
 import org.videolan.libvlc.Media;
+import org.videolan.libvlc.util.AndroidUtil;
 import org.videolan.vlc.MediaWrapper;
 import org.videolan.vlc.R;
 import org.videolan.vlc.util.Strings;
@@ -69,7 +70,7 @@ public class StorageBrowserAdapter extends BaseBrowserAdapter {
         vh.itemView.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
-                MediaWrapper mw = new MediaWrapper(((Storage) getItem(vh.getAdapterPosition())).getPath());
+                MediaWrapper mw = new MediaWrapper(AndroidUtil.LocationToUri(((Storage) getItem(vh.getAdapterPosition())).getPath()));
                 mw.setType(MediaWrapper.TYPE_DIR);
                 ((StorageBrowserFragment) fragment).browse(mw, holder.getAdapterPosition(), vh.checkBox.isChecked());
             }
diff --git a/vlc-android/src/org/videolan/vlc/gui/video/MediaInfoFragment.java b/vlc-android/src/org/videolan/vlc/gui/video/MediaInfoFragment.java
index fc6074f..4883042 100644
--- a/vlc-android/src/org/videolan/vlc/gui/video/MediaInfoFragment.java
+++ b/vlc-android/src/org/videolan/vlc/gui/video/MediaInfoFragment.java
@@ -107,7 +107,7 @@ public class MediaInfoFragment extends ListFragment {
         mPlayButton.setOnClickListener(new OnClickListener() {
             @Override
             public void onClick(View v) {
-                VideoPlayerActivity.start(getActivity(), mItem.getLocation());
+                VideoPlayerActivity.start(getActivity(), mItem.getUri());
             }
         });
 
diff --git a/vlc-android/src/org/videolan/vlc/gui/video/VideoGridFragment.java b/vlc-android/src/org/videolan/vlc/gui/video/VideoGridFragment.java
index 118950d..319d20d 100644
--- a/vlc-android/src/org/videolan/vlc/gui/video/VideoGridFragment.java
+++ b/vlc-android/src/org/videolan/vlc/gui/video/VideoGridFragment.java
@@ -303,7 +303,7 @@ public class VideoGridFragment extends MediaBrowserFragment implements ISortable
     }
 
     protected void playVideo(MediaWrapper media, boolean fromStart) {
-        VideoPlayerActivity.start(getActivity(), media.getLocation(), fromStart);
+        VideoPlayerActivity.start(getActivity(), media.getUri(), fromStart);
     }
 
     protected void playAudio(MediaWrapper media) {
diff --git a/vlc-android/src/org/videolan/vlc/gui/video/VideoPlayerActivity.java b/vlc-android/src/org/videolan/vlc/gui/video/VideoPlayerActivity.java
index d120e05..75e0a8f 100644
--- a/vlc-android/src/org/videolan/vlc/gui/video/VideoPlayerActivity.java
+++ b/vlc-android/src/org/videolan/vlc/gui/video/VideoPlayerActivity.java
@@ -133,9 +133,7 @@ import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
 import java.io.OutputStream;
 import java.io.StreamCorruptedException;
-import java.io.UnsupportedEncodingException;
 import java.lang.reflect.Method;
-import java.net.URLDecoder;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.Map;
@@ -174,7 +172,7 @@ public class VideoPlayerActivity extends AppCompatActivity implements IVideoPlay
     private SecondaryDisplay mPresentation;
     private int mPresentationDisplayId = -1;
     private MediaWrapperListPlayer mMediaListPlayer;
-    private String mLocation;
+    private Uri mUri;
     private boolean mAskResume = true;
     private GestureDetectorCompat mDetector;
 
@@ -751,7 +749,7 @@ public class VideoPlayerActivity extends AppCompatActivity implements IVideoPlay
         mPlaybackStarted = false;
 
         if(mSwitchingView) {
-            Log.d(TAG, "mLocation = \"" + mLocation + "\"");
+            Log.d(TAG, "mLocation = \"" + mUri + "\"");
             PlaybackServiceController.getInstance().showWithoutParse(savedIndexPosition);
             unbindAudioService();
             return;
@@ -785,9 +783,9 @@ public class VideoPlayerActivity extends AppCompatActivity implements IVideoPlay
         SharedPreferences.Editor editor = mSettings.edit();
         // Save position
         if (time >= 0 && mCanSeek) {
-            if(MediaDatabase.getInstance().mediaItemExists(mLocation)) {
+            if(MediaDatabase.getInstance().mediaItemExists(mUri)) {
                 MediaDatabase.getInstance().updateMedia(
-                        mLocation,
+                        mUri,
                         MediaDatabase.mediaColumn.MEDIA_TIME,
                         time);
             } else {
@@ -812,7 +810,7 @@ public class VideoPlayerActivity extends AppCompatActivity implements IVideoPlay
         }
         editor.putString(PreferencesActivity.VIDEO_SUBTITLE_FILES, subtitleList_serialized);
 
-        editor.putString(PreferencesActivity.VIDEO_LAST, Uri.encode(mLocation));
+        editor.putString(PreferencesActivity.VIDEO_LAST, mUri.toString());
 
         // Save user playback speed and restore normal speed
         editor.putFloat(PreferencesActivity.VIDEO_SPEED, MediaPlayer().getRate());
@@ -844,25 +842,25 @@ public class VideoPlayerActivity extends AppCompatActivity implements IVideoPlay
         mSubtitleSelectedFiles.add(subtitlePath);
     }
 
-    public static void start(Context context, String location) {
-        start(context, location, null, false, -1);
+    public static void start(Context context, Uri uri) {
+        start(context, uri, null, false, -1);
     }
 
-    public static void start(Context context, String location, boolean fromStart) {
-        start(context, location, null, fromStart, -1);
+    public static void start(Context context, Uri uri, boolean fromStart) {
+        start(context, uri, null, fromStart, -1);
     }
 
-    public static void start(Context context, String location, String title) {
-        start(context, location, title, false, -1);
+    public static void start(Context context, Uri uri, String title) {
+        start(context, uri, title, false, -1);
     }
     public static void startOpened(Context context, int openedPosition) {
         start(context, null, null, false, openedPosition);
     }
 
-    private static void start(Context context, String location, String title, boolean fromStart, int openedPosition) {
+    private static void start(Context context, Uri uri, String title, boolean fromStart, int openedPosition) {
         Intent intent = new Intent(context, VideoPlayerActivity.class);
         intent.setAction(PLAY_FROM_VIDEOGRID);
-        intent.putExtra(PLAY_EXTRA_ITEM_LOCATION, location);
+        intent.putExtra(PLAY_EXTRA_ITEM_LOCATION, uri);
         intent.putExtra(PLAY_EXTRA_ITEM_TITLE, title);
         intent.putExtra(PLAY_EXTRA_FROM_START, fromStart);
         intent.putExtra(PLAY_EXTRA_OPENED_POSITION, openedPosition);
@@ -899,8 +897,8 @@ public class VideoPlayerActivity extends AppCompatActivity implements IVideoPlay
 
     private void exit(int resultCode){
         Intent resultIntent = new Intent(ACTION_RESULT);
-        if (mLocation != null) {
-            resultIntent.setData(Uri.parse(mLocation));
+        if (mUri != null) {
+            resultIntent.setData(mUri);
             resultIntent.putExtra(EXTRA_POSITION, MediaPlayer().getTime());
             resultIntent.putExtra(EXTRA_DURATION, MediaPlayer().getLength());
         }
@@ -2181,7 +2179,7 @@ public class VideoPlayerActivity extends AppCompatActivity implements IVideoPlay
                         if (trackID < 0)
                             return false;
                         MediaDatabase.getInstance().updateMedia(
-                                mLocation,
+                                mUri,
                                 MediaDatabase.mediaColumn.MEDIA_AUDIOTRACK,
                                 trackID);
                         MediaPlayer().setAudioTrack(trackID);
@@ -2200,7 +2198,7 @@ public class VideoPlayerActivity extends AppCompatActivity implements IVideoPlay
                             return false;
 
                         MediaDatabase.getInstance().updateMedia(
-                                mLocation,
+                                mUri,
                                 MediaDatabase.mediaColumn.MEDIA_SPUTRACK,
                                 trackID);
                         MediaPlayer().setSpuTrack(trackID);
@@ -2560,7 +2558,7 @@ public class VideoPlayerActivity extends AppCompatActivity implements IVideoPlay
         int time = (int) getTime();
         int length = (int) MediaPlayer().getLength();
         if (length == 0) {
-            MediaWrapper media = MediaDatabase.getInstance().getMedia(mLocation);
+            MediaWrapper media = MediaDatabase.getInstance().getMedia(mUri);
             if (media != null)
                 length = (int) media.getLength();
         }
@@ -2641,7 +2639,7 @@ public class VideoPlayerActivity extends AppCompatActivity implements IVideoPlay
     @TargetApi(12)
     @SuppressWarnings({ "unchecked" })
     private void loadMedia() {
-        mLocation = null;
+        mUri = null;
         String title = getResources().getString(R.string.title);
         boolean fromStart = false;
         int openedPosition = -1;
@@ -2696,7 +2694,7 @@ public class VideoPlayerActivity extends AppCompatActivity implements IVideoPlay
                             while((bytesRead = is.read(buffer)) >= 0) {
                                 os.write(buffer, 0, bytesRead);
                             }
-                            mLocation = AndroidUtil.PathToUri(AndroidDevices.EXTERNAL_PUBLIC_DIRECTORY + "/Download/" + filename).toString();
+                            mUri = AndroidUtil.PathToUri(AndroidDevices.EXTERNAL_PUBLIC_DIRECTORY + "/Download/" + filename);
                         }
                     } catch (Exception e) {
                         Log.e(TAG, "Couldn't download file from mail URI");
@@ -2715,17 +2713,17 @@ public class VideoPlayerActivity extends AppCompatActivity implements IVideoPlay
                         if (cursor != null) {
                             int column_index = cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DATA);
                             if (cursor.moveToFirst())
-                                mLocation = AndroidUtil.PathToUri(cursor.getString(column_index)).toString();
+                                mUri = AndroidUtil.PathToUri(cursor.getString(column_index));
                             cursor.close();
                         }
                         // other content-based URI (probably file pickers)
                         else {
-                            mLocation = data.getPath();
+                            mUri = data;
                         }
                     } catch (Exception e) {
-                        mLocation = data.getPath();
-                        if (!mLocation.startsWith("file://"))
-                            mLocation = "file://"+mLocation;
+                        mUri = data;
+                        if (mUri.getScheme() == null)
+                            mUri = AndroidUtil.PathToUri(mUri.getPath());
                         Log.e(TAG, "Couldn't read the file from media or MMS");
                     }
                 } else {
@@ -2733,10 +2731,10 @@ public class VideoPlayerActivity extends AppCompatActivity implements IVideoPlay
                     try {
                         inputPFD = getContentResolver().openFileDescriptor(data, "r");
                         if (AndroidUtil.isHoneycombMr1OrLater())
-                            mLocation = "fd://"+inputPFD.getFd();
+                            mUri = AndroidUtil.LocationToUri("fd://" + inputPFD.getFd());
                         else {
                             String fdString = inputPFD.getFileDescriptor().toString();
-                            mLocation = "fd://" + fdString.substring(15, fdString.length()-1);
+                            mUri = AndroidUtil.LocationToUri("fd://" + fdString.substring(15, fdString.length() - 1));
                         }
 
                         Cursor returnCursor =
@@ -2758,18 +2756,14 @@ public class VideoPlayerActivity extends AppCompatActivity implements IVideoPlay
             } /* External application */
             else if (intent.getDataString() != null) {
                 // Plain URI
-                mLocation = intent.getDataString();
+                final String location = intent.getDataString();
                 // Remove VLC prefix if needed
-                if (mLocation.startsWith("vlc://")) {
-                    mLocation = mLocation.substring(6);
-                }
-                // Decode URI
-                if (!mLocation.contains("/")){
-                    try {
-                        mLocation = URLDecoder.decode(mLocation,"UTF-8");
-                    } catch (UnsupportedEncodingException e) {
-                        Log.w(TAG, "UnsupportedEncodingException while decoding MRL " + mLocation);
-                    }
+                if (location.startsWith("vlc://")) {
+                    mUri = AndroidUtil.LocationToUri(location.substring(6));
+                } else {
+                    mUri = intent.getData();
+                    if (mUri.getScheme() == null)
+                        mUri = AndroidUtil.PathToUri(mUri.getPath());
                 }
             } else {
                 Log.e(TAG, "Couldn't understand the intent");
@@ -2783,7 +2777,7 @@ public class VideoPlayerActivity extends AppCompatActivity implements IVideoPlay
         } /* ACTION_VIEW */
         /* Started from VideoListActivity */
         else if(TextUtils.equals(action, PLAY_FROM_VIDEOGRID) && extras != null) {
-            mLocation = extras.getString(PLAY_EXTRA_ITEM_LOCATION);
+            mUri = extras.getParcelable(PLAY_EXTRA_ITEM_LOCATION);
             itemTitle = extras.getString(PLAY_EXTRA_ITEM_TITLE);
             fromStart = extras.getBoolean(PLAY_EXTRA_FROM_START);
             if (intent.hasExtra(PLAY_EXTRA_SUBTITLES_LOCATION))
@@ -2800,15 +2794,15 @@ public class VideoPlayerActivity extends AppCompatActivity implements IVideoPlay
                 encounteredError();
                 return;
             }
-            mLocation = openedMedia.getLocation();
+            mUri = openedMedia.getUri();
             itemTitle = openedMedia.getTitle();
             savedIndexPosition = openedPosition;
         } else {
             /* prepare playback */
             PlaybackServiceController.getInstance().stop(); // Stop the previous playback.
-            if (savedIndexPosition == -1 && mLocation != null && mLocation.length() > 0) {
+            if (savedIndexPosition == -1 && mUri != null) {
                 mMediaListPlayer.getMediaList().clear();
-                final Media media = new Media(LibVLC(), Uri.parse(mLocation));
+                final Media media = new Media(LibVLC(), mUri);
                 media.parse(); // FIXME: parse shouldn't be done asynchronously
                 media.release();
                 mMediaListPlayer.getMediaList().add(new MediaWrapper(media));
@@ -2817,9 +2811,9 @@ public class VideoPlayerActivity extends AppCompatActivity implements IVideoPlay
         }
         mCanSeek = false;
 
-        if (mLocation != null && mLocation.length() > 0) {
+        if (mUri != null) {
             // restore last position
-            MediaWrapper media = MediaDatabase.getInstance().getMedia(mLocation);
+            MediaWrapper media = MediaDatabase.getInstance().getMedia(mUri);
             if(media != null) {
                 // in media library
                 if(media.getTime() > 0 && !fromStart && openedPosition == -1) {
@@ -2901,19 +2895,8 @@ public class VideoPlayerActivity extends AppCompatActivity implements IVideoPlay
              }
 
             // Get the title
-            if (itemTitle == null) {
-                try {
-                    title = URLDecoder.decode(mLocation, "UTF-8");
-                } catch (UnsupportedEncodingException e) {
-                } catch (IllegalArgumentException e) {
-                }
-                if (title.startsWith("file:")) {
-                    title = new File(title).getName();
-                    int dotIndex = title.lastIndexOf('.');
-                    if (dotIndex != -1)
-                        title = title.substring(0, dotIndex);
-                }
-            }
+            if (itemTitle == null)
+                title = mUri.getLastPathSegment();
         }
         if (itemTitle != null)
             title = itemTitle;
@@ -3161,7 +3144,7 @@ public class VideoPlayerActivity extends AppCompatActivity implements IVideoPlay
     }
 
     private void updateNavStatus() {
-        mHasMenu = MediaPlayer().getChapterCountForTitle(0) > 1 && MediaPlayer().getTitleCount() > 1 && (mLocation == null || !mLocation.endsWith(".mkv"));
+        mHasMenu = MediaPlayer().getChapterCountForTitle(0) > 1 && MediaPlayer().getTitleCount() > 1 && (mUri == null || !mUri.toString().endsWith(".mkv"));
         mIsNavMenu = mHasMenu && MediaPlayer().getTitle() == 0;
         /***
          * HACK ALERT: assume that any media with >1 titles = DVD with menus
diff --git a/vlc-android/src/org/videolan/vlc/util/BitmapUtil.java b/vlc-android/src/org/videolan/vlc/util/BitmapUtil.java
index ea8ec99..989bddd 100644
--- a/vlc-android/src/org/videolan/vlc/util/BitmapUtil.java
+++ b/vlc-android/src/org/videolan/vlc/util/BitmapUtil.java
@@ -97,7 +97,7 @@ public class BitmapUtil {
                  */
                 picture = readCoverBitmap(media.getArtworkURL());
                 if (picture == null)
-                    picture = MediaDatabase.getInstance().getPicture(media.getLocation());
+                    picture = MediaDatabase.getInstance().getPicture(media.getUri());
                 cache.addBitmapToMemCache(media.getLocation(), picture);
             }
             return picture;
diff --git a/vlc-android/src/org/videolan/vlc/util/Util.java b/vlc-android/src/org/videolan/vlc/util/Util.java
index e32d9f6..5699eb9 100644
--- a/vlc-android/src/org/videolan/vlc/util/Util.java
+++ b/vlc-android/src/org/videolan/vlc/util/Util.java
@@ -210,9 +210,8 @@ public class Util {
     public static void openMedia(Context context, final MediaWrapper media){
         if (media == null)
             return;
-        String mrl = media.getLocation();
         if (media.getType() == MediaWrapper.TYPE_VIDEO)
-            VideoPlayerActivity.start(context, mrl, media.getTitle());
+            VideoPlayerActivity.start(context, media.getUri(), media.getTitle());
         else if (media.getType() == MediaWrapper.TYPE_AUDIO) {
             VLCCallbackTask task = new VLCCallbackTask(context) {
                 @Override
diff --git a/vlc-android/tv/src/org/videolan/vlc/gui/tv/MainTvActivity.java b/vlc-android/tv/src/org/videolan/vlc/gui/tv/MainTvActivity.java
index 1736f92..72fd377 100644
--- a/vlc-android/tv/src/org/videolan/vlc/gui/tv/MainTvActivity.java
+++ b/vlc-android/tv/src/org/videolan/vlc/gui/tv/MainTvActivity.java
@@ -405,7 +405,7 @@ public class MainTvActivity extends Activity implements IVideoBrowser, OnItemVie
                 MediaDatabase mediaDatabase = MediaDatabase.getInstance();
                 if (sThumbnailer != null && videoList != null && !videoList.isEmpty()) {
                     for (MediaWrapper MediaWrapper : videoList){
-                        picture = mediaDatabase.getPicture(MediaWrapper.getLocation());
+                        picture = mediaDatabase.getPicture(MediaWrapper.getUri());
                         if (picture== null)
                             sThumbnailer.addJob(MediaWrapper);
                     }
diff --git a/vlc-android/tv/src/org/videolan/vlc/gui/tv/MediaItemDetailsFragment.java b/vlc-android/tv/src/org/videolan/vlc/gui/tv/MediaItemDetailsFragment.java
index 8567e3c..8efd250 100644
--- a/vlc-android/tv/src/org/videolan/vlc/gui/tv/MediaItemDetailsFragment.java
+++ b/vlc-android/tv/src/org/videolan/vlc/gui/tv/MediaItemDetailsFragment.java
@@ -22,6 +22,7 @@ package org.videolan.vlc.gui.tv;
 
 import java.util.ArrayList;
 
+import org.videolan.libvlc.util.AndroidUtil;
 import org.videolan.vlc.MediaDatabase;
 import org.videolan.vlc.MediaLibrary;
 import org.videolan.vlc.MediaWrapper;
@@ -83,7 +84,7 @@ public class MediaItemDetailsFragment extends DetailsFragment implements Playbac
         mMedia = extras.getParcelable("item");
         boolean hasMedia = extras.containsKey("media");
         ClassPresenterSelector selector = new ClassPresenterSelector();
-        final MediaWrapper media = hasMedia ? (MediaWrapper) extras.getParcelable("media") : new MediaWrapper(mMedia.getLocation());
+        final MediaWrapper media = hasMedia ? (MediaWrapper) extras.getParcelable("media") : new MediaWrapper(AndroidUtil.LocationToUri(mMedia.getLocation()));
         if (!hasMedia){
             media.setTitle(mMedia.getTitle());
         }
diff --git a/vlc-android/tv/src/org/videolan/vlc/gui/tv/RecommendationsService.java b/vlc-android/tv/src/org/videolan/vlc/gui/tv/RecommendationsService.java
index fae3e1e..a80fbfe 100644
--- a/vlc-android/tv/src/org/videolan/vlc/gui/tv/RecommendationsService.java
+++ b/vlc-android/tv/src/org/videolan/vlc/gui/tv/RecommendationsService.java
@@ -108,7 +108,7 @@ public class RecommendationsService extends IntentService {
     private PendingIntent buildPendingIntent(MediaWrapper mediaWrapper, int id) {
         Intent intent = new Intent(mContext, VideoPlayerActivity.class);
         intent.setAction(VideoPlayerActivity.PLAY_FROM_VIDEOGRID);
-        intent.putExtra(VideoPlayerActivity.PLAY_EXTRA_ITEM_LOCATION, mediaWrapper.getLocation());
+        intent.putExtra(VideoPlayerActivity.PLAY_EXTRA_ITEM_LOCATION, mediaWrapper.getUri());
         intent.putExtra(VideoPlayerActivity.PLAY_EXTRA_ITEM_TITLE, mediaWrapper.getTitle());
         intent.putExtra(VideoPlayerActivity.PLAY_EXTRA_FROM_START, false);
 
@@ -144,7 +144,7 @@ public class RecommendationsService extends IntentService {
         for (MediaWrapper mediaWrapper : videoList){
             if (TextUtils.equals(mediaWrapper.getLocation(), last))
                 continue;
-            pic = mMediaDatabase.getPicture(mediaWrapper.getLocation());
+            pic = mMediaDatabase.getPicture(mediaWrapper.getUri());
             if (pic != null && pic.getByteCount() > 4 && mediaWrapper.getTime() == 0) {
                 buildRecommendation(mediaWrapper, ++id, Notification.PRIORITY_DEFAULT);
             }
-- 
2.1.4




More information about the Android mailing list