[Android] [PATCH 01/10] Use MediaBrowser to browse local files
Geoffrey Métais
geoffrey.metais at gmail.com
Mon Apr 20 10:49:47 CEST 2015
Replaces DirectoryViewFragment
---
vlc-android/res/layout/directory_view_item.xml | 2 +
.../src/org/videolan/vlc/gui/BrowserActivity.java | 14 +-
.../src/org/videolan/vlc/gui/BrowserAdapter.java | 165 ---------
.../src/org/videolan/vlc/gui/BrowserFragment.java | 45 ---
.../videolan/vlc/gui/DirectoryViewFragment.java | 7 +-
.../src/org/videolan/vlc/gui/HistoryFragment.java | 2 +-
.../src/org/videolan/vlc/gui/MainActivity.java | 33 +-
.../org/videolan/vlc/gui/MediaBrowserAdapter.java | 165 +++++++++
.../org/videolan/vlc/gui/MediaBrowserFragment.java | 45 +++
.../src/org/videolan/vlc/gui/SidebarAdapter.java | 10 +-
.../vlc/gui/audio/AudioAlbumsSongsFragment.java | 4 +-
.../vlc/gui/audio/AudioBrowserFragment.java | 5 +-
.../vlc/gui/browser/BaseBrowserAdapter.java | 218 ++++++++++++
.../vlc/gui/browser/BaseBrowserFragment.java | 378 +++++++++++++++++++++
.../vlc/gui/browser/FileBrowserFragment.java | 137 ++++++++
.../vlc/gui/browser/NetworkBrowserAdapter.java | 33 ++
.../vlc/gui/browser/NetworkBrowserFragment.java | 173 ++++++++++
.../videolan/vlc/gui/network/NetworkAdapter.java | 200 -----------
.../videolan/vlc/gui/network/NetworkFragment.java | 344 -------------------
.../videolan/vlc/gui/video/VideoGridFragment.java | 6 +-
.../src/org/videolan/vlc/util/AndroidDevices.java | 9 +
vlc-android/src/org/videolan/vlc/util/Util.java | 4 +
.../tv/src/org/videolan/vlc/gui/tv/TvUtil.java | 5 +-
.../vlc/gui/tv/browser/BrowserGridFragment.java | 6 +-
24 files changed, 1204 insertions(+), 806 deletions(-)
delete mode 100644 vlc-android/src/org/videolan/vlc/gui/BrowserAdapter.java
delete mode 100644 vlc-android/src/org/videolan/vlc/gui/BrowserFragment.java
create mode 100644 vlc-android/src/org/videolan/vlc/gui/MediaBrowserAdapter.java
create mode 100644 vlc-android/src/org/videolan/vlc/gui/MediaBrowserFragment.java
create mode 100644 vlc-android/src/org/videolan/vlc/gui/browser/BaseBrowserAdapter.java
create mode 100644 vlc-android/src/org/videolan/vlc/gui/browser/BaseBrowserFragment.java
create mode 100644 vlc-android/src/org/videolan/vlc/gui/browser/FileBrowserFragment.java
create mode 100644 vlc-android/src/org/videolan/vlc/gui/browser/NetworkBrowserAdapter.java
create mode 100644 vlc-android/src/org/videolan/vlc/gui/browser/NetworkBrowserFragment.java
delete mode 100644 vlc-android/src/org/videolan/vlc/gui/network/NetworkAdapter.java
delete mode 100644 vlc-android/src/org/videolan/vlc/gui/network/NetworkFragment.java
diff --git a/vlc-android/res/layout/directory_view_item.xml b/vlc-android/res/layout/directory_view_item.xml
index fa8db6d..3005275 100644
--- a/vlc-android/res/layout/directory_view_item.xml
+++ b/vlc-android/res/layout/directory_view_item.xml
@@ -52,6 +52,8 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
+ android:paddingRight="10dp"
+ android:paddingLeft="10dp"
android:background="@drawable/ic_more"
android:clickable="true" />
diff --git a/vlc-android/src/org/videolan/vlc/gui/BrowserActivity.java b/vlc-android/src/org/videolan/vlc/gui/BrowserActivity.java
index 0cee56a..44fe229 100644
--- a/vlc-android/src/org/videolan/vlc/gui/BrowserActivity.java
+++ b/vlc-android/src/org/videolan/vlc/gui/BrowserActivity.java
@@ -27,7 +27,6 @@ import java.util.Arrays;
import java.util.Locale;
import java.util.Stack;
-import org.videolan.libvlc.LibVLC;
import org.videolan.libvlc.LibVlcUtil;
import org.videolan.vlc.MediaDatabase;
import org.videolan.vlc.MediaLibrary;
@@ -49,7 +48,6 @@ import android.preference.PreferenceManager;
import android.text.InputType;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
-import android.view.ContextThemeWrapper;
import android.view.KeyEvent;
import android.view.MenuItem;
import android.view.View;
@@ -66,7 +64,7 @@ public class BrowserActivity extends ListActivity {
* TODO:
*/
- private BrowserAdapter mAdapter;
+ private MediaBrowserAdapter mAdapter;
private File mCurrentDir;
private final Stack<ScrollState> mScrollStates = new Stack<ScrollState>();
private String mRoots[];
@@ -86,7 +84,7 @@ public class BrowserActivity extends ListActivity {
applyTheme();
super.onCreate(savedInstanceState);
setContentView(R.layout.browser);
- mAdapter = new BrowserAdapter(this);
+ mAdapter = new MediaBrowserAdapter(this);
setListAdapter(mAdapter);
IntentFilter filter = new IntentFilter();
@@ -131,7 +129,7 @@ public class BrowserActivity extends ListActivity {
int position = ((AdapterContextMenuInfo)menuInfo).position;
final File item = mAdapter.getItem(position);
if (mCurrentDir != null
- || item.getPath().equals(BrowserAdapter.ADD_ITEM_PATH)
+ || item.getPath().equals(MediaBrowserAdapter.ADD_ITEM_PATH)
|| AndroidDevices.getStorageDirectories().contains(
item.getPath())) {
return;
@@ -158,7 +156,7 @@ public class BrowserActivity extends ListActivity {
if (f.exists())
mAdapter.add(f);
}
- mAdapter.add(new File(BrowserAdapter.ADD_ITEM_PATH));
+ mAdapter.add(new File(MediaBrowserAdapter.ADD_ITEM_PATH));
mAdapter.sort();
// set scroll position to top
@@ -167,7 +165,7 @@ public class BrowserActivity extends ListActivity {
private void openDir(File file) {
if(file == null || !file.exists() || file.getPath() == null
- || file.getPath().equals(BrowserAdapter.ADD_ITEM_PATH))
+ || file.getPath().equals(MediaBrowserAdapter.ADD_ITEM_PATH))
return;
mAdapter.clear();
@@ -190,7 +188,7 @@ public class BrowserActivity extends ListActivity {
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
File file = mAdapter.getItem(position);
- if(file.getPath().equals(BrowserAdapter.ADD_ITEM_PATH)) {
+ if(file.getPath().equals(MediaBrowserAdapter.ADD_ITEM_PATH)) {
AlertDialog.Builder b = new AlertDialog.Builder(this);
final EditText input = new EditText(this);
if (!LibVlcUtil.isHoneycombOrLater()) {
diff --git a/vlc-android/src/org/videolan/vlc/gui/BrowserAdapter.java b/vlc-android/src/org/videolan/vlc/gui/BrowserAdapter.java
deleted file mode 100644
index c78781e..0000000
--- a/vlc-android/src/org/videolan/vlc/gui/BrowserAdapter.java
+++ /dev/null
@@ -1,165 +0,0 @@
-/*****************************************************************************
- * BrowserAdapter.java
- *****************************************************************************
- * Copyright © 2011-2012 VLC authors and VideoLAN
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- *****************************************************************************/
-
-package org.videolan.vlc.gui;
-
-import java.io.File;
-import java.util.Comparator;
-import java.util.List;
-
-import org.videolan.vlc.MediaDatabase;
-import org.videolan.vlc.R;
-import org.videolan.vlc.VLCApplication;
-
-import android.content.Context;
-import android.os.Build;
-import android.os.Environment;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ArrayAdapter;
-import android.widget.CheckBox;
-import android.widget.CompoundButton;
-import android.widget.CompoundButton.OnCheckedChangeListener;
-import android.widget.TextView;
-
-public class BrowserAdapter extends ArrayAdapter<File>
- implements Comparator<File> {
- public final static String TAG = "VLC/BrowserAdapter";
-
- public final static String ADD_ITEM_PATH = "/add/a/path";
-
- public BrowserAdapter(Context context) {
- super(context, 0);
- }
-
- @Override
- public synchronized void add(File object) {
- super.add(object);
- }
-
- /**
- * Display the view of a file browser item.
- */
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
-
- ViewHolder holder;
- View view = convertView;
- if (view == null) {
- LayoutInflater inflater = (LayoutInflater) this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- view = inflater.inflate(R.layout.browser_item, parent, false);
- holder = new ViewHolder();
- holder.layout = view.findViewById(R.id.layout_item);
- holder.check = (CheckBox) view.findViewById(R.id.browser_item_selected);
- holder.text = (TextView) view.findViewById(R.id.browser_item_dir);
- view.setTag(holder);
- } else
- holder = (ViewHolder) view.getTag();
-
- final File item = getItem(position);
- final MediaDatabase dbManager = MediaDatabase.getInstance();
-
- if(item != null) {
- if(item.getPath().equals(ADD_ITEM_PATH)) {
- holder.text.setText(R.string.add_custom_path);
- holder.check.setVisibility(View.GONE);
- } else if(item.getName() != null) {
- holder.text.setText(getVisibleName(item));
- holder.check.setVisibility(View.VISIBLE);
- holder.check.setOnCheckedChangeListener(null);
- holder.check.setTag(item);
- holder.check.setEnabled(true);
- holder.check.setChecked(false);
-
- List<File> dirs = dbManager.getMediaDirs();
- for (File dir : dirs) {
- if (dir.getPath().equals(item.getPath())) {
- holder.check.setEnabled(true);
- holder.check.setChecked(true);
- break;
- } else if (dir.getPath().startsWith(item.getPath()+"/")) {
- Log.i(TAG, dir.getPath() + " startWith " + item.getPath());
- holder.check.setEnabled(false);
- holder.check.setChecked(true);
- break;
- }
- }
-
- holder.check.setOnCheckedChangeListener(onCheckedChangeListener);
- }
- }
-
- return view;
- }
-
- private final OnCheckedChangeListener onCheckedChangeListener = new OnCheckedChangeListener() {
- @Override
- public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
- final MediaDatabase dbManager = MediaDatabase.getInstance();
- File item = (File) buttonView.getTag();
- if (item == null)
- return;
-
- if (buttonView.isEnabled() && isChecked) {
- dbManager.addDir(item.getPath());
- File tmpFile = item.getParentFile();
- while (tmpFile != null && !tmpFile.getPath().equals("/")) {
- dbManager.removeDir(tmpFile.getPath());
- tmpFile = tmpFile.getParentFile();
- }
- } else {
- dbManager.removeDir(item.getPath());
- }
- }
- };
-
- public void sort() {
- super.sort(this);
- }
-
- @Override
- public int compare(File file1, File file2) {
- // float the add item to the bottom
- if(file1.getPath().equals(ADD_ITEM_PATH))
- return 1;
- else if(file2.getPath().equals(ADD_ITEM_PATH))
- return -1;
-
- return String.CASE_INSENSITIVE_ORDER.compare(file1.getName(), file2.getName());
- }
-
- private String getVisibleName(File file) {
- if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
- // Show "sdcard" for the user's folder when running in multi-user
- if (file.getAbsolutePath().equals(Environment.getExternalStorageDirectory().getPath())) {
- return VLCApplication.getAppContext().getString(R.string.internal_memory);
- }
- }
- return file.getName();
- }
-
- static class ViewHolder {
- View layout;
- CheckBox check;
- TextView text;
- }
-}
diff --git a/vlc-android/src/org/videolan/vlc/gui/BrowserFragment.java b/vlc-android/src/org/videolan/vlc/gui/BrowserFragment.java
deleted file mode 100644
index 1d61d93..0000000
--- a/vlc-android/src/org/videolan/vlc/gui/BrowserFragment.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * *************************************************************************
- * BrowserFragment.java
- * **************************************************************************
- * Copyright © 2015 VLC authors and VideoLAN
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- * ***************************************************************************
- */
-
-package org.videolan.vlc.gui;
-
-import android.support.v4.app.Fragment;
-import android.support.v7.app.ActionBarActivity;
-
-import org.videolan.vlc.widget.SwipeRefreshLayout;
-
-public abstract class BrowserFragment extends Fragment {
-
- protected SwipeRefreshLayout mSwipeRefreshLayout;
- protected volatile boolean mReadyToDisplay = true;
-
- protected void setReadyToDisplay(boolean ready){}
- protected void display(){}
-
- protected abstract String getTitle();
- public abstract void clear();
- public void onStart(){
- super.onStart();
- ((ActionBarActivity) getActivity()).getSupportActionBar().setTitle(getTitle());
- getActivity().supportInvalidateOptionsMenu();
- }
-}
diff --git a/vlc-android/src/org/videolan/vlc/gui/DirectoryViewFragment.java b/vlc-android/src/org/videolan/vlc/gui/DirectoryViewFragment.java
index 5ec2332..56b583c 100644
--- a/vlc-android/src/org/videolan/vlc/gui/DirectoryViewFragment.java
+++ b/vlc-android/src/org/videolan/vlc/gui/DirectoryViewFragment.java
@@ -60,10 +60,9 @@ import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.AdapterView.AdapterContextMenuInfo;
-import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.ListView;
-public class DirectoryViewFragment extends BrowserFragment implements IRefreshable, SwipeRefreshLayout.OnRefreshListener, AdapterView.OnItemClickListener {
+public class DirectoryViewFragment extends MediaBrowserFragment implements IRefreshable, SwipeRefreshLayout.OnRefreshListener, AdapterView.OnItemClickListener {
public final static String TAG = "VLC/DirectoryViewFragment";
private DirectoryAdapter mDirectoryAdapter;
@@ -209,12 +208,12 @@ public class DirectoryViewFragment extends BrowserFragment implements IRefreshab
Fragment fragment = fm.findFragmentByTag(SidebarAdapter.SidebarEntry.ID_AUDIO);
if (fragment != null) {
ft.remove(fragment);
- ((BrowserFragment)fragment).clear();
+ ((MediaBrowserFragment)fragment).clear();
}
fragment = fm.findFragmentByTag(SidebarAdapter.SidebarEntry.ID_VIDEO);
if (fragment != null) {
ft.remove(fragment);
- ((BrowserFragment)fragment).clear();
+ ((MediaBrowserFragment)fragment).clear();
}
if (!ft.isEmpty())
ft.commit();
diff --git a/vlc-android/src/org/videolan/vlc/gui/HistoryFragment.java b/vlc-android/src/org/videolan/vlc/gui/HistoryFragment.java
index 0305473..c23a467 100644
--- a/vlc-android/src/org/videolan/vlc/gui/HistoryFragment.java
+++ b/vlc-android/src/org/videolan/vlc/gui/HistoryFragment.java
@@ -41,7 +41,7 @@ import android.widget.AdapterView;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.ListView;
-public class HistoryFragment extends BrowserFragment implements IRefreshable, SwipeRefreshLayout.OnRefreshListener, AdapterView.OnItemClickListener {
+public class HistoryFragment extends MediaBrowserFragment implements IRefreshable, SwipeRefreshLayout.OnRefreshListener, AdapterView.OnItemClickListener {
public final static String TAG = "VLC/HistoryFragment";
private HistoryAdapter mHistoryAdapter;
diff --git a/vlc-android/src/org/videolan/vlc/gui/MainActivity.java b/vlc-android/src/org/videolan/vlc/gui/MainActivity.java
index f20af7a..021936f 100644
--- a/vlc-android/src/org/videolan/vlc/gui/MainActivity.java
+++ b/vlc-android/src/org/videolan/vlc/gui/MainActivity.java
@@ -63,19 +63,18 @@ import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
-import org.videolan.libvlc.LibVlcException;
import org.videolan.libvlc.LibVlcUtil;
import org.videolan.vlc.BuildConfig;
import org.videolan.vlc.MediaDatabase;
import org.videolan.vlc.MediaLibrary;
import org.videolan.vlc.R;
-import org.videolan.vlc.VLCApplication;
import org.videolan.vlc.audio.AudioService;
import org.videolan.vlc.audio.AudioServiceController;
import org.videolan.vlc.gui.SidebarAdapter.SidebarEntry;
import org.videolan.vlc.gui.audio.AudioBrowserFragment;
import org.videolan.vlc.gui.audio.AudioPlayer;
-import org.videolan.vlc.gui.network.NetworkFragment;
+import org.videolan.vlc.gui.browser.BaseBrowserFragment;
+import org.videolan.vlc.gui.browser.NetworkBrowserFragment;
import org.videolan.vlc.gui.video.VideoGridFragment;
import org.videolan.vlc.gui.video.VideoListAdapter;
import org.videolan.vlc.gui.video.VideoPlayerActivity;
@@ -198,8 +197,8 @@ public class MainActivity extends ActionBarActivity implements OnItemClickListen
@Override
public void onDrawerClosed(View drawerView) {
super.onDrawerClosed(drawerView);
- if (getSupportFragmentManager().findFragmentById(R.id.fragment_placeholder) instanceof BrowserFragment)
- ((BrowserFragment) getSupportFragmentManager().findFragmentById(R.id.fragment_placeholder)).setReadyToDisplay(true);
+ if (getSupportFragmentManager().findFragmentById(R.id.fragment_placeholder) instanceof MediaBrowserFragment)
+ ((MediaBrowserFragment) getSupportFragmentManager().findFragmentById(R.id.fragment_placeholder)).setReadyToDisplay(true);
}
};
@@ -380,17 +379,11 @@ public class MainActivity extends ActionBarActivity implements OnItemClickListen
if (mCurrentFragment!= null) {
// If it's the directory view, a "backpressed" action shows a parent.
- if (mCurrentFragment.equals(SidebarEntry.ID_DIRECTORIES)) {
- DirectoryViewFragment directoryView = (DirectoryViewFragment) getFragment(mCurrentFragment);
- if (!directoryView.isRootDirectory()) {
- directoryView.showParentDirectory();
- return;
- }
- } else if (mCurrentFragment.equals(SidebarEntry.ID_NETWORK)){
- NetworkFragment networkFragment = (NetworkFragment) getSupportFragmentManager()
+ if (mCurrentFragment.equals(SidebarEntry.ID_NETWORK) || mCurrentFragment.equals(SidebarEntry.ID_DIRECTORIES)){
+ BaseBrowserFragment browserFragment = (BaseBrowserFragment) getSupportFragmentManager()
.findFragmentById(R.id.fragment_placeholder);
- if (networkFragment !=null && !networkFragment.isRootDirectory()) {
- networkFragment.goBack();
+ if (browserFragment !=null && !browserFragment.isRootDirectory()) {
+ browserFragment.goBack();
return;
}
}
@@ -504,11 +497,11 @@ public class MainActivity extends ActionBarActivity implements OnItemClickListen
item.setTitle(R.string.sortby_date);
}
- boolean networkSave = current instanceof NetworkFragment && !((NetworkFragment)current).isRootDirectory();
+ boolean networkSave = current instanceof BaseBrowserFragment && !((BaseBrowserFragment)current).isRootDirectory();
if (networkSave) {
MenuItem item = menu.findItem(R.id.ml_menu_save);
item.setVisible(true);
- String mrl = ((NetworkFragment)current).mMrl;
+ String mrl = ((BaseBrowserFragment)current).mMrl;
item.setIcon(MediaDatabase.getInstance().networkFavExists(mrl) ?
R.drawable.ic_menu_bookmark_w :
R.drawable.ic_menu_bookmark_outline_w);
@@ -591,7 +584,7 @@ public class MainActivity extends ActionBarActivity implements OnItemClickListen
case R.id.ml_menu_save:
if (current == null)
break;
- ((NetworkFragment)current).toggleFavorite();
+ ((NetworkBrowserFragment)current).toggleFavorite();
item.setIcon(R.drawable.ic_menu_bookmark_w);
break;
}
@@ -965,8 +958,8 @@ public class MainActivity extends ActionBarActivity implements OnItemClickListen
/* Switch the fragment */
Fragment fragment = getFragment(entry.id);
- if (fragment instanceof BrowserFragment)
- ((BrowserFragment) fragment).setReadyToDisplay(false);
+ if (fragment instanceof MediaBrowserFragment)
+ ((MediaBrowserFragment)fragment).setReadyToDisplay(false);
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.fragment_placeholder, fragment, entry.id);
ft.addToBackStack(mCurrentFragment);
diff --git a/vlc-android/src/org/videolan/vlc/gui/MediaBrowserAdapter.java b/vlc-android/src/org/videolan/vlc/gui/MediaBrowserAdapter.java
new file mode 100644
index 0000000..551d357
--- /dev/null
+++ b/vlc-android/src/org/videolan/vlc/gui/MediaBrowserAdapter.java
@@ -0,0 +1,165 @@
+/*****************************************************************************
+ * BrowserAdapter.java
+ *****************************************************************************
+ * Copyright © 2011-2012 VLC authors and VideoLAN
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+package org.videolan.vlc.gui;
+
+import java.io.File;
+import java.util.Comparator;
+import java.util.List;
+
+import org.videolan.vlc.MediaDatabase;
+import org.videolan.vlc.R;
+import org.videolan.vlc.VLCApplication;
+
+import android.content.Context;
+import android.os.Build;
+import android.os.Environment;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.CheckBox;
+import android.widget.CompoundButton;
+import android.widget.CompoundButton.OnCheckedChangeListener;
+import android.widget.TextView;
+
+public class MediaBrowserAdapter extends ArrayAdapter<File>
+ implements Comparator<File> {
+ public final static String TAG = "VLC/BrowserAdapter";
+
+ public final static String ADD_ITEM_PATH = "/add/a/path";
+
+ public MediaBrowserAdapter(Context context) {
+ super(context, 0);
+ }
+
+ @Override
+ public synchronized void add(File object) {
+ super.add(object);
+ }
+
+ /**
+ * Display the view of a file browser item.
+ */
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+
+ ViewHolder holder;
+ View view = convertView;
+ if (view == null) {
+ LayoutInflater inflater = (LayoutInflater) this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ view = inflater.inflate(R.layout.browser_item, parent, false);
+ holder = new ViewHolder();
+ holder.layout = view.findViewById(R.id.layout_item);
+ holder.check = (CheckBox) view.findViewById(R.id.browser_item_selected);
+ holder.text = (TextView) view.findViewById(R.id.browser_item_dir);
+ view.setTag(holder);
+ } else
+ holder = (ViewHolder) view.getTag();
+
+ final File item = getItem(position);
+ final MediaDatabase dbManager = MediaDatabase.getInstance();
+
+ if(item != null) {
+ if(item.getPath().equals(ADD_ITEM_PATH)) {
+ holder.text.setText(R.string.add_custom_path);
+ holder.check.setVisibility(View.GONE);
+ } else if(item.getName() != null) {
+ holder.text.setText(getVisibleName(item));
+ holder.check.setVisibility(View.VISIBLE);
+ holder.check.setOnCheckedChangeListener(null);
+ holder.check.setTag(item);
+ holder.check.setEnabled(true);
+ holder.check.setChecked(false);
+
+ List<File> dirs = dbManager.getMediaDirs();
+ for (File dir : dirs) {
+ if (dir.getPath().equals(item.getPath())) {
+ holder.check.setEnabled(true);
+ holder.check.setChecked(true);
+ break;
+ } else if (dir.getPath().startsWith(item.getPath()+"/")) {
+ Log.i(TAG, dir.getPath() + " startWith " + item.getPath());
+ holder.check.setEnabled(false);
+ holder.check.setChecked(true);
+ break;
+ }
+ }
+
+ holder.check.setOnCheckedChangeListener(onCheckedChangeListener);
+ }
+ }
+
+ return view;
+ }
+
+ private final OnCheckedChangeListener onCheckedChangeListener = new OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ final MediaDatabase dbManager = MediaDatabase.getInstance();
+ File item = (File) buttonView.getTag();
+ if (item == null)
+ return;
+
+ if (buttonView.isEnabled() && isChecked) {
+ dbManager.addDir(item.getPath());
+ File tmpFile = item.getParentFile();
+ while (tmpFile != null && !tmpFile.getPath().equals("/")) {
+ dbManager.removeDir(tmpFile.getPath());
+ tmpFile = tmpFile.getParentFile();
+ }
+ } else {
+ dbManager.removeDir(item.getPath());
+ }
+ }
+ };
+
+ public void sort() {
+ super.sort(this);
+ }
+
+ @Override
+ public int compare(File file1, File file2) {
+ // float the add item to the bottom
+ if(file1.getPath().equals(ADD_ITEM_PATH))
+ return 1;
+ else if(file2.getPath().equals(ADD_ITEM_PATH))
+ return -1;
+
+ return String.CASE_INSENSITIVE_ORDER.compare(file1.getName(), file2.getName());
+ }
+
+ private String getVisibleName(File file) {
+ if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
+ // Show "sdcard" for the user's folder when running in multi-user
+ if (file.getAbsolutePath().equals(Environment.getExternalStorageDirectory().getPath())) {
+ return VLCApplication.getAppContext().getString(R.string.internal_memory);
+ }
+ }
+ return file.getName();
+ }
+
+ static class ViewHolder {
+ View layout;
+ CheckBox check;
+ TextView text;
+ }
+}
diff --git a/vlc-android/src/org/videolan/vlc/gui/MediaBrowserFragment.java b/vlc-android/src/org/videolan/vlc/gui/MediaBrowserFragment.java
new file mode 100644
index 0000000..66190ff
--- /dev/null
+++ b/vlc-android/src/org/videolan/vlc/gui/MediaBrowserFragment.java
@@ -0,0 +1,45 @@
+/*
+ * *************************************************************************
+ * BrowserFragment.java
+ * **************************************************************************
+ * Copyright © 2015 VLC authors and VideoLAN
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ * ***************************************************************************
+ */
+
+package org.videolan.vlc.gui;
+
+import android.support.v4.app.Fragment;
+import android.support.v7.app.ActionBarActivity;
+
+import org.videolan.vlc.widget.SwipeRefreshLayout;
+
+public abstract class MediaBrowserFragment extends Fragment {
+
+ protected SwipeRefreshLayout mSwipeRefreshLayout;
+ protected volatile boolean mReadyToDisplay = true;
+
+ protected void setReadyToDisplay(boolean ready){}
+ protected void display(){}
+
+ protected abstract String getTitle();
+ public abstract void clear();
+ public void onStart(){
+ super.onStart();
+ ((ActionBarActivity) getActivity()).getSupportActionBar().setTitle(getTitle());
+ getActivity().supportInvalidateOptionsMenu();
+ }
+}
diff --git a/vlc-android/src/org/videolan/vlc/gui/SidebarAdapter.java b/vlc-android/src/org/videolan/vlc/gui/SidebarAdapter.java
index c9286e0..9b4f2af 100644
--- a/vlc-android/src/org/videolan/vlc/gui/SidebarAdapter.java
+++ b/vlc-android/src/org/videolan/vlc/gui/SidebarAdapter.java
@@ -28,7 +28,9 @@ import org.videolan.vlc.BuildConfig;
import org.videolan.vlc.R;
import org.videolan.vlc.VLCApplication;
import org.videolan.vlc.gui.audio.AudioBrowserFragment;
-import org.videolan.vlc.gui.network.NetworkFragment;
+import org.videolan.vlc.gui.browser.BaseBrowserFragment;
+import org.videolan.vlc.gui.browser.FileBrowserFragment;
+import org.videolan.vlc.gui.browser.NetworkBrowserFragment;
import org.videolan.vlc.gui.video.VideoGridFragment;
import org.videolan.vlc.util.Util;
@@ -47,7 +49,7 @@ import android.widget.TextView;
public class SidebarAdapter extends BaseAdapter {
public final static String TAG = "VLC/SidebarAdapter";
- static class SidebarEntry {
+ public static class SidebarEntry {
public static final int TYPE_FRAGMENT = 0;
public static final int TYPE_ACTION = 1;
public static final int TYPE_SECONDARY_FRAGMENT = 2;
@@ -166,13 +168,13 @@ public class SidebarAdapter extends BaseAdapter {
} else if(id.equals(SidebarEntry.ID_VIDEO)) {
f = new VideoGridFragment();
} else if(id.endsWith(SidebarEntry.ID_DIRECTORIES)) {
- f = new DirectoryViewFragment();
+ f = new FileBrowserFragment();
} else if(id.equals(SidebarEntry.ID_HISTORY)) {
f = new HistoryFragment();
} else if(id.equals(SidebarEntry.ID_MRL)) {
f = new MRLPanelFragment();
} else if(id.equals(SidebarEntry.ID_NETWORK)) {
- f = new NetworkFragment();
+ f = new NetworkBrowserFragment();
}
else {
mCurrentFragmentId = prevFragmentId; // Restore the current fragment id.
diff --git a/vlc-android/src/org/videolan/vlc/gui/audio/AudioAlbumsSongsFragment.java b/vlc-android/src/org/videolan/vlc/gui/audio/AudioAlbumsSongsFragment.java
index b4b3f5e..9149e0e 100644
--- a/vlc-android/src/org/videolan/vlc/gui/audio/AudioAlbumsSongsFragment.java
+++ b/vlc-android/src/org/videolan/vlc/gui/audio/AudioAlbumsSongsFragment.java
@@ -52,7 +52,7 @@ import org.videolan.vlc.MediaLibrary;
import org.videolan.vlc.MediaWrapper;
import org.videolan.vlc.R;
import org.videolan.vlc.audio.AudioServiceController;
-import org.videolan.vlc.gui.BrowserFragment;
+import org.videolan.vlc.gui.MediaBrowserFragment;
import org.videolan.vlc.gui.CommonDialogs;
import org.videolan.vlc.util.AndroidDevices;
import org.videolan.vlc.util.Util;
@@ -64,7 +64,7 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.List;
-public class AudioAlbumsSongsFragment extends BrowserFragment implements SwipeRefreshLayout.OnRefreshListener {
+public class AudioAlbumsSongsFragment extends MediaBrowserFragment implements SwipeRefreshLayout.OnRefreshListener {
public final static String TAG = "VLC/AudioAlbumsSongsFragment";
diff --git a/vlc-android/src/org/videolan/vlc/gui/audio/AudioBrowserFragment.java b/vlc-android/src/org/videolan/vlc/gui/audio/AudioBrowserFragment.java
index 3375a10..bf0389c 100644
--- a/vlc-android/src/org/videolan/vlc/gui/audio/AudioBrowserFragment.java
+++ b/vlc-android/src/org/videolan/vlc/gui/audio/AudioBrowserFragment.java
@@ -52,7 +52,6 @@ import android.widget.TextView;
import com.android.widget.SlidingTabLayout;
-import org.videolan.libvlc.LibVLC;
import org.videolan.libvlc.LibVlcUtil;
import org.videolan.libvlc.Media;
import org.videolan.libvlc.util.MediaBrowser;
@@ -61,7 +60,7 @@ import org.videolan.vlc.MediaLibrary;
import org.videolan.vlc.MediaWrapper;
import org.videolan.vlc.R;
import org.videolan.vlc.audio.AudioServiceController;
-import org.videolan.vlc.gui.BrowserFragment;
+import org.videolan.vlc.gui.MediaBrowserFragment;
import org.videolan.vlc.gui.CommonDialogs;
import org.videolan.vlc.gui.MainActivity;
import org.videolan.vlc.gui.SecondaryActivity;
@@ -82,7 +81,7 @@ import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
-public class AudioBrowserFragment extends BrowserFragment implements SwipeRefreshLayout.OnRefreshListener, SlidingTabLayout.OnTabChangedListener, MediaBrowser.EventListener, IBrowser {
+public class AudioBrowserFragment extends MediaBrowserFragment implements SwipeRefreshLayout.OnRefreshListener, SlidingTabLayout.OnTabChangedListener, MediaBrowser.EventListener, IBrowser {
public final static String TAG = "VLC/AudioBrowserFragment";
private AudioServiceController mAudioController;
diff --git a/vlc-android/src/org/videolan/vlc/gui/browser/BaseBrowserAdapter.java b/vlc-android/src/org/videolan/vlc/gui/browser/BaseBrowserAdapter.java
new file mode 100644
index 0000000..03df2d5
--- /dev/null
+++ b/vlc-android/src/org/videolan/vlc/gui/browser/BaseBrowserAdapter.java
@@ -0,0 +1,218 @@
+/**
+ * **************************************************************************
+ * BaseBrowserAdapter.java
+ * ****************************************************************************
+ * Copyright © 2015 VLC authors and VideoLAN
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ * ***************************************************************************
+ */
+package org.videolan.vlc.gui.browser;
+
+import android.support.v7.widget.RecyclerView;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import org.videolan.libvlc.Media;
+import org.videolan.vlc.MediaWrapper;
+import org.videolan.vlc.R;
+import org.videolan.vlc.gui.audio.MediaComparators;
+import org.videolan.vlc.util.Util;
+
+import java.util.ArrayList;
+import java.util.Collections;
+
+public class BaseBrowserAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
+ private static final String TAG = "VLC/BaseBrowserAdapter";
+
+ private static final int TYPE_MEDIA = 0;
+ private static final int TYPE_SEPARATOR = 1;
+
+ protected int FOLDER_RES_ID = R.drawable.ic_menu_folder;
+
+ ArrayList<Object> mMediaList = new ArrayList<Object>();
+ BaseBrowserFragment fragment;
+
+ public BaseBrowserAdapter(BaseBrowserFragment fragment){
+ this.fragment = fragment;
+ }
+
+ @Override
+ public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ RecyclerView.ViewHolder vh;
+ View v;
+ if (viewType == TYPE_MEDIA) {
+ v = LayoutInflater.from(parent.getContext())
+ .inflate(R.layout.directory_view_item, parent, false);
+ vh = new MediaViewHolder(v);
+ } else {
+ v = LayoutInflater.from(parent.getContext())
+ .inflate(R.layout.browser_item_separator, parent, false);
+ vh = new SeparatorViewHolder(v);
+ }
+ return vh;
+ }
+
+ @Override
+ public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) {
+ if (holder instanceof MediaViewHolder) {
+ final MediaViewHolder vh = (MediaViewHolder) holder;
+ final MediaWrapper media = (MediaWrapper) getItem(position);
+ boolean hasContextMenu = (media.getType() == MediaWrapper.TYPE_AUDIO ||
+ media.getType() == MediaWrapper.TYPE_VIDEO ||
+ (media.getType() == MediaWrapper.TYPE_DIR && Util.canWrite(media.getLocation())));
+ vh.title.setText(media.getTitle());
+ vh.text.setVisibility(View.GONE);
+ vh.icon.setImageResource(getIconResId(media));
+ vh.more.setVisibility(hasContextMenu ? View.VISIBLE : View.GONE);
+ vh.itemView.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ MediaWrapper mw = (MediaWrapper) getItem(holder.getPosition());
+ if (mw.getType() == MediaWrapper.TYPE_DIR)
+ fragment.browse(mw);
+ else
+ Util.openMedia(v.getContext(), mw);
+ }
+ });
+ if (hasContextMenu) {
+ vh.more.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ fragment.onPopupMenu(vh.more, holder.getPosition());
+ }
+ });
+ vh.itemView.setOnLongClickListener(new View.OnLongClickListener() {
+ @Override
+ public boolean onLongClick(View v) {
+ fragment.onPopupMenu(vh.title, holder.getPosition());
+ return true;
+ }
+ });
+ }
+ } else {
+ SeparatorViewHolder vh = (SeparatorViewHolder) holder;
+ vh.title.setText(getItem(position).toString());
+ }
+ }
+
+ @Override
+ public int getItemCount() {
+ return mMediaList.size();
+ }
+
+ public class MediaViewHolder extends RecyclerView.ViewHolder {
+ public TextView title;
+ public TextView text;
+ public ImageView icon;
+ public ImageView more;
+
+ public MediaViewHolder(View v) {
+ super(v);
+ title = (TextView) v.findViewById(R.id.title);
+ text = (TextView) v.findViewById(R.id.text);
+ icon = (ImageView) v.findViewById(R.id.dvi_icon);
+ more = (ImageView) v.findViewById(R.id.item_more);
+ }
+ }
+
+ public static class SeparatorViewHolder extends RecyclerView.ViewHolder {
+ public TextView title;
+
+ public SeparatorViewHolder(View v) {
+ super(v);
+ title = (TextView) v.findViewById(R.id.separator_title);
+ }
+ }
+
+ public void clear(){
+ mMediaList.clear();
+ notifyDataSetChanged();
+ }
+
+ public boolean isEmpty(){
+ return mMediaList.isEmpty();
+ }
+
+ public void addItem(Media media, boolean root, boolean first){
+ MediaWrapper mediaWrapper = new MediaWrapper(media);
+ addItem(mediaWrapper, root, first);
+
+ }
+
+ public void addItem(Object item, boolean root, boolean top){
+ int position = top ? 0 : mMediaList.size();
+ if (item instanceof MediaWrapper && ((MediaWrapper)item).getTitle().startsWith("."))
+ return;
+ else if (item instanceof Media)
+ item = new MediaWrapper((Media) item);
+
+ mMediaList.add(position, item);
+ notifyItemInserted(position);
+ }
+
+ public void removeItem(int position){
+ mMediaList.remove(position);
+ notifyItemRemoved(position);
+ }
+
+ public Object getItem(int position){
+ return mMediaList.get(position);
+ }
+
+ public int getItemViewType(int position){
+ if (getItem(position) instanceof MediaWrapper)
+ return TYPE_MEDIA;
+ else
+ return TYPE_SEPARATOR;
+ }
+
+ public void sortList(){
+ ArrayList<MediaWrapper> files = new ArrayList<MediaWrapper>(), dirs = new ArrayList<MediaWrapper>();
+ for (Object item : mMediaList){
+ if (item instanceof MediaWrapper) {
+ MediaWrapper media = (MediaWrapper) item;
+ if (media.getType() == MediaWrapper.TYPE_DIR)
+ dirs.add(media);
+ else
+ files.add(media);
+ }
+ }
+ Collections.sort(dirs, MediaComparators.byName);
+ Collections.sort(files, MediaComparators.byName);
+ mMediaList.clear();
+ mMediaList.addAll(dirs);
+ mMediaList.addAll(files);
+ notifyDataSetChanged();
+ }
+
+ private int getIconResId(MediaWrapper media) {
+ switch (media.getType()){
+ case MediaWrapper.TYPE_AUDIO:
+ return R.drawable.ic_browser_audio_normal;
+ case MediaWrapper.TYPE_DIR:
+ return FOLDER_RES_ID;
+ case MediaWrapper.TYPE_VIDEO:
+ return R.drawable.ic_browser_video_normal;
+ case MediaWrapper.TYPE_SUBTITLE:
+ return R.drawable.ic_browser_subtitle_normal;
+ default:
+ return R.drawable.ic_browser_unknown_normal;
+ }
+ }
+}
diff --git a/vlc-android/src/org/videolan/vlc/gui/browser/BaseBrowserFragment.java b/vlc-android/src/org/videolan/vlc/gui/browser/BaseBrowserFragment.java
new file mode 100644
index 0000000..9a9840f
--- /dev/null
+++ b/vlc-android/src/org/videolan/vlc/gui/browser/BaseBrowserFragment.java
@@ -0,0 +1,378 @@
+/**
+ * **************************************************************************
+ * BaseBrowserFragment.java
+ * ****************************************************************************
+ * Copyright © 2015 VLC authors and VideoLAN
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ * ***************************************************************************
+ */
+package org.videolan.vlc.gui.browser;
+
+import android.annotation.TargetApi;
+import android.app.AlertDialog;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Message;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentManager;
+import android.support.v4.app.FragmentTransaction;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.PopupMenu;
+import android.support.v7.widget.RecyclerView;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import org.videolan.libvlc.LibVLC;
+import org.videolan.libvlc.LibVlcUtil;
+import org.videolan.libvlc.Media;
+import org.videolan.libvlc.util.MediaBrowser;
+import org.videolan.vlc.MediaLibrary;
+import org.videolan.vlc.MediaWrapper;
+import org.videolan.vlc.R;
+import org.videolan.vlc.audio.AudioServiceController;
+import org.videolan.vlc.gui.CommonDialogs;
+import org.videolan.vlc.gui.DividerItemDecoration;
+import org.videolan.vlc.gui.MainActivity;
+import org.videolan.vlc.gui.MediaBrowserFragment;
+import org.videolan.vlc.gui.SidebarAdapter;
+import org.videolan.vlc.gui.video.VideoPlayerActivity;
+import org.videolan.vlc.interfaces.IRefreshable;
+import org.videolan.vlc.util.Util;
+import org.videolan.vlc.util.VLCInstance;
+import org.videolan.vlc.util.VLCRunnable;
+import org.videolan.vlc.util.WeakHandler;
+import org.videolan.vlc.widget.SwipeRefreshLayout;
+
+import java.io.File;
+import java.io.IOException;
+
+
+public abstract class BaseBrowserFragment extends MediaBrowserFragment implements IRefreshable, MediaBrowser.EventListener, SwipeRefreshLayout.OnRefreshListener {
+ protected static final String TAG = "VLC/BaseBrowserFragment";
+
+ public static String ROOT = "smb";
+ public static final String KEY_MRL = "key_mrl";
+ public static final String KEY_MEDIA = "key_media";
+ public static final String KEY_POSITION = "key_list";
+
+ protected BrowserFragmentHandler mHandler;
+ protected MediaBrowser mMediaBrowser;
+ protected RecyclerView mRecyclerView;
+ protected BaseBrowserAdapter mAdapter;
+ protected LinearLayoutManager mLayoutManager;
+ protected TextView mEmptyView;
+ public String mMrl;
+ protected MediaWrapper mCurrentMedia;
+ protected int mSavedPosition = -1, mFavorites = 0;
+ protected boolean mRoot;
+ protected LibVLC mLibVLC;
+
+ protected abstract Fragment createFragment();
+ protected abstract void browseRoot();
+ protected abstract String getCategoryTitle();
+
+ public BaseBrowserFragment(){
+ mHandler = new BrowserFragmentHandler(this);
+ mAdapter = new BaseBrowserAdapter(this);
+ }
+
+ public void onCreate(Bundle bundle){
+ super.onCreate(bundle);
+ mLibVLC = VLCInstance.get();
+
+ if (bundle == null)
+ bundle = getArguments();
+ if (bundle != null){
+ mCurrentMedia = bundle.getParcelable(KEY_MEDIA);
+ if (mCurrentMedia != null)
+ mMrl = mCurrentMedia.getLocation();
+ else
+ mMrl = bundle.getString(KEY_MRL);
+ mSavedPosition = bundle.getInt(KEY_POSITION);
+ }
+ }
+
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
+ View v = inflater.inflate(R.layout.network_browser, container, false);
+ mRecyclerView = (RecyclerView) v.findViewById(R.id.network_list);
+ mEmptyView = (TextView) v.findViewById(android.R.id.empty);
+ mLayoutManager = new LinearLayoutManager(getActivity());
+ mRecyclerView.addItemDecoration(new DividerItemDecoration(getActivity(), DividerItemDecoration.VERTICAL_LIST));
+ mRecyclerView.setLayoutManager(mLayoutManager);
+ mRecyclerView.setAdapter(mAdapter);
+ mRecyclerView.setOnScrollListener(mScrollListener);
+
+ mSwipeRefreshLayout = (SwipeRefreshLayout) v.findViewById(R.id.swipeLayout);
+ mSwipeRefreshLayout.setColorSchemeResources(R.color.orange700);
+ mSwipeRefreshLayout.setOnRefreshListener(this);
+ return v;
+ }
+
+ public void onStop(){
+ super.onStop();
+ if (mMediaBrowser != null)
+ mMediaBrowser.release();
+ }
+
+ public void onSaveInstanceState(Bundle outState){
+ outState.putString(KEY_MRL, mMrl);
+ if (mRecyclerView != null) {
+ outState.putInt(KEY_POSITION, mLayoutManager.findFirstCompletelyVisibleItemPosition());
+ }
+ super.onSaveInstanceState(outState);
+ }
+
+ public boolean isRootDirectory(){
+ return mRoot;
+ }
+
+ public String getTitle(){
+ if (mRoot)
+ return getCategoryTitle();
+ else
+ return mCurrentMedia != null ? mCurrentMedia.getTitle() : mMrl;
+ }
+
+ public void goBack(){
+ getActivity().getSupportFragmentManager().popBackStack();
+ }
+
+ public void browse (MediaWrapper media){
+ FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
+ Fragment next = createFragment();
+ Bundle args = new Bundle();
+ args.putParcelable(KEY_MEDIA, media);
+ next.setArguments(args);
+ ft.replace(R.id.fragment_placeholder, next, media.getLocation());
+ ft.addToBackStack(mMrl);
+ ft.commit();
+ }
+
+
+ @Override
+ public void onMediaAdded(int index, Media media) {
+ mAdapter.addItem(media, mRoot, true);
+ updateEmptyView();
+ if (mRoot)
+ mHandler.sendEmptyMessage(BrowserFragmentHandler.MSG_HIDE_LOADING);
+ }
+
+ @Override
+ public void onMediaRemoved(int index, Media media) {
+ mAdapter.removeItem(index);
+ }
+
+ @Override
+ public void onBrowseEnd() {
+ mAdapter.sortList();
+ mHandler.sendEmptyMessage(BrowserFragmentHandler.MSG_HIDE_LOADING);
+ if (mSavedPosition > 0) {
+ mLayoutManager.scrollToPositionWithOffset(mSavedPosition, 0);
+ mSavedPosition = 0;
+ }
+ focusHelper(mAdapter.isEmpty());
+ }
+
+ @Override
+ public void onRefresh() {
+ mSavedPosition = mLayoutManager.findFirstCompletelyVisibleItemPosition();
+ refresh();
+ }
+
+ RecyclerView.OnScrollListener mScrollListener = new RecyclerView.OnScrollListener() {
+ @Override
+ public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
+ super.onScrollStateChanged(recyclerView, newState);
+ }
+
+ @Override
+ public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
+ int topRowVerticalPosition =
+ (recyclerView == null || recyclerView.getChildCount() == 0) ? 0 : recyclerView.getChildAt(0).getTop();
+ mSwipeRefreshLayout.setEnabled(topRowVerticalPosition >= 0);
+ }
+ };
+
+ /**
+ * Update views visibility and emptiness info
+ *
+ * @return True if content needs can be refreshed
+ */
+ protected boolean updateEmptyView(){
+ if (mAdapter.isEmpty()){
+ mEmptyView.setText("Directory empty");
+ mEmptyView.setVisibility(View.VISIBLE);
+ mRecyclerView.setVisibility(View.GONE);
+ mSwipeRefreshLayout.setEnabled(false);
+ } else if (mEmptyView.getVisibility() == View.VISIBLE) {
+ mEmptyView.setVisibility(View.GONE);
+ mRecyclerView.setVisibility(View.VISIBLE);
+ mSwipeRefreshLayout.setEnabled(true);
+ }
+ return true;
+ }
+
+ protected void updateDisplay(){
+ if (mMediaBrowser == null)
+ mMediaBrowser = new MediaBrowser(mLibVLC, this);
+ if (mAdapter.isEmpty())
+ refresh();
+ }
+
+ @Override
+ public void refresh() {
+ mAdapter.clear();
+ if (mRoot)
+ browseRoot();
+ else
+ mMediaBrowser.browse(mMrl);
+ mHandler.sendEmptyMessageDelayed(BrowserFragmentHandler.MSG_SHOW_LOADING, 300);
+ }
+
+
+ protected static class BrowserFragmentHandler extends WeakHandler<BaseBrowserFragment> {
+
+ public static final int MSG_SHOW_LOADING = 0;
+ public static final int MSG_HIDE_LOADING = 1;
+
+ public BrowserFragmentHandler(BaseBrowserFragment owner) {
+ super(owner);
+ }
+ @Override
+ public void handleMessage(Message msg) {
+ BaseBrowserFragment fragment = getOwner();
+ switch (msg.what){
+ case MSG_SHOW_LOADING:
+ fragment.mSwipeRefreshLayout.setRefreshing(true);
+ break;
+ case MSG_HIDE_LOADING:
+ removeMessages(MSG_SHOW_LOADING);
+ fragment.mSwipeRefreshLayout.setRefreshing(false);
+ break;
+ }
+ }
+ }
+
+ protected void focusHelper(boolean idIsEmpty) {
+ if (getActivity() == null)
+ return;
+ MainActivity main = (MainActivity)getActivity();
+ View parent = View.inflate(main, R.layout.directory_view, null);
+ main.setMenuFocusDown(idIsEmpty, R.id.network_list);
+ main.setSearchAsFocusDown(idIsEmpty, parent, R.id.network_list);
+ }
+
+ public void clear(){
+ mAdapter.clear();
+ }
+
+
+ @TargetApi(Build.VERSION_CODES.HONEYCOMB)
+ public void onPopupMenu(View anchor, final int position) {
+ MediaWrapper mw = (MediaWrapper) mAdapter.getItem(position);
+ if (!LibVlcUtil.isHoneycombOrLater()) {
+ // Call the "classic" context menu
+ anchor.performLongClick();
+ return;
+ }
+ boolean canWrite = Util.canWrite(mw.getLocation());
+ PopupMenu popupMenu = new PopupMenu(getActivity(), anchor);
+ if (mw.getType() == MediaWrapper.TYPE_AUDIO || mw.getType() == MediaWrapper.TYPE_VIDEO) {
+ popupMenu.getMenuInflater().inflate(R.menu.directory_view_file, popupMenu.getMenu());
+ popupMenu.getMenu().findItem(R.id.directory_view_delete).setVisible(canWrite);
+ } else if (mw.getType() == MediaWrapper.TYPE_DIR) {
+ if (canWrite) {
+ Menu menu = popupMenu.getMenu();
+ popupMenu.getMenuInflater().inflate(R.menu.directory_view_dir, menu);
+ boolean nomedia = new File(mw.getLocation() + "/.nomedia").exists();
+ menu.findItem(R.id.directory_view_hide_media).setVisible(!nomedia);
+ menu.findItem(R.id.directory_view_show_media).setVisible(nomedia);
+ }
+ }
+
+ popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
+ @Override
+ public boolean onMenuItemClick(MenuItem item) {
+ return handleContextItemSelected(item, position);
+ }
+ });
+ popupMenu.show();
+ }
+
+ private boolean handleContextItemSelected(MenuItem item, int position) {
+ int id = item.getItemId();
+ if (! (mAdapter.getItem(position) instanceof MediaWrapper))
+ return super.onContextItemSelected(item);
+ MediaWrapper mw = (MediaWrapper) mAdapter.getItem(position);
+ switch (id){
+ case R.id.directory_view_play:
+ Util.openMedia(getActivity(), (MediaWrapper) mAdapter.getItem(position));
+ return true;
+ case R.id.directory_view_append:
+ AudioServiceController.getInstance().append(mw.getLocation());
+ return true;
+ case R.id.directory_view_delete:
+ AlertDialog alertDialog = CommonDialogs.deleteMedia(getActivity(), mw.getLocation(),
+ new VLCRunnable() {
+ @Override
+ public void run(Object o) {
+ refresh();
+ }
+ });
+ alertDialog.show();
+ return true;
+ case R.id.directory_view_play_audio:
+ AudioServiceController.getInstance().load(mw.getLocation(), true);
+ return true;
+ case R.id.directory_view_play_video:
+ VideoPlayerActivity.start(getActivity(), mw.getLocation());
+ return true;
+ case R.id.directory_view_hide_media:
+ try {
+ new File(mw.getLocation()+"/.nomedia").createNewFile();
+ updateLib();
+ } catch (IOException e) {}
+ return true;
+ case R.id.directory_view_show_media:
+ new File(mw.getLocation()+"/.nomedia").delete();
+ updateLib();
+ return true;
+ }
+ return false;
+ }
+
+ private void updateLib() {
+ FragmentManager fm = getFragmentManager();
+ FragmentTransaction ft = fm.beginTransaction();
+ Fragment fragment = fm.findFragmentByTag(SidebarAdapter.SidebarEntry.ID_AUDIO);
+ if (fragment != null) {
+ ft.remove(fragment);
+ ((MediaBrowserFragment)fragment).clear();
+ }
+ fragment = fm.findFragmentByTag(SidebarAdapter.SidebarEntry.ID_VIDEO);
+ if (fragment != null) {
+ ft.remove(fragment);
+ ((MediaBrowserFragment)fragment).clear();
+ }
+ if (!ft.isEmpty())
+ ft.commit();
+ MediaLibrary.getInstance().loadMediaItems();
+ }
+}
diff --git a/vlc-android/src/org/videolan/vlc/gui/browser/FileBrowserFragment.java b/vlc-android/src/org/videolan/vlc/gui/browser/FileBrowserFragment.java
new file mode 100644
index 0000000..c833922
--- /dev/null
+++ b/vlc-android/src/org/videolan/vlc/gui/browser/FileBrowserFragment.java
@@ -0,0 +1,137 @@
+/*
+ * *************************************************************************
+ * FileBrowserFragment.java
+ * **************************************************************************
+ * Copyright © 2015 VLC authors and VideoLAN
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ * ***************************************************************************
+ */
+
+package org.videolan.vlc.gui.browser;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Bundle;
+import android.os.Environment;
+import android.support.v4.app.Fragment;
+import android.support.v7.internal.widget.AdapterViewCompat;
+import android.util.Log;
+import android.view.ContextMenu;
+import android.view.MenuInflater;
+import android.view.View;
+
+import org.videolan.vlc.MediaWrapper;
+import org.videolan.vlc.R;
+import org.videolan.vlc.util.AndroidDevices;
+import org.videolan.vlc.util.Util;
+
+import java.io.File;
+
+public class FileBrowserFragment extends BaseBrowserFragment {
+
+ public FileBrowserFragment() {
+ super();
+ ROOT = Environment.getExternalStorageDirectory().getPath();
+ }
+
+ @Override
+ public void onCreate(Bundle bundle) {
+ super.onCreate(bundle);
+ mRoot = mMrl == null;
+ Log.d(TAG, "file root ? "+mRoot);
+ }
+
+ @Override
+ public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
+ int position = ((AdapterViewCompat.AdapterContextMenuInfo)menuInfo).position;
+ MenuInflater menuInflater = getActivity().getMenuInflater();
+ if (mAdapter.getItem(position) instanceof MediaWrapper) {
+ MediaWrapper mw = (MediaWrapper) mAdapter.getItem(position);
+ if (mw.getType() == MediaWrapper.TYPE_DIR) {
+ if (Util.canWrite(mw.getLocation())) {
+ menuInflater.inflate(R.menu.directory_view_dir, menu);
+ boolean nomedia = new File(mw.getLocation() + "/.nomedia").exists();
+ menu.findItem(R.id.directory_view_hide_media).setVisible(!nomedia);
+ menu.findItem(R.id.directory_view_show_media).setVisible(nomedia);
+ }
+ } else if (mw.getType() == MediaWrapper.TYPE_AUDIO || mw.getType() == MediaWrapper.TYPE_VIDEO)
+ menuInflater.inflate(R.menu.directory_view_file, menu);
+ }
+ }
+
+ @Override
+ protected Fragment createFragment() {
+ return new FileBrowserFragment();
+ }
+
+ @Override
+ protected String getCategoryTitle() {
+ return getString(R.string.directories);
+ }
+
+ @Override
+ protected void browseRoot() {
+ Log.d(TAG, "file browse root");
+ String storages[] = AndroidDevices.getMediaDirectories();
+ MediaWrapper mw;
+ for (String storage : storages) {
+ mw = new MediaWrapper(storage);
+ mw.setTitle(AndroidDevices.getStorageTitle(storage));
+ mw.setType(MediaWrapper.TYPE_DIR);
+ mAdapter.addItem(mw, false, false);
+ }
+ mHandler.sendEmptyMessage(BrowserFragmentHandler.MSG_HIDE_LOADING);
+ updateEmptyView();
+ mAdapter.notifyDataSetChanged();
+ }
+
+ public void onStart(){
+ super.onStart();
+
+ //Handle network connection state
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(Intent.ACTION_MEDIA_MOUNTED);
+ filter.addAction(Intent.ACTION_MEDIA_UNMOUNTED);
+ filter.addAction(Intent.ACTION_MEDIA_REMOVED);
+ filter.addAction(Intent.ACTION_MEDIA_EJECT);
+ getActivity().registerReceiver(storageReceiver, filter);
+ if (updateEmptyView())
+ updateDisplay();
+ }
+
+ @Override
+ public void onStop() {
+ super.onStop();
+ getActivity().unregisterReceiver(storageReceiver);
+ }
+
+ private final BroadcastReceiver storageReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+
+ if (action.equalsIgnoreCase(Intent.ACTION_MEDIA_MOUNTED) ||
+ action.equalsIgnoreCase(Intent.ACTION_MEDIA_UNMOUNTED) ||
+ action.equalsIgnoreCase(Intent.ACTION_MEDIA_REMOVED) ||
+ action.equalsIgnoreCase(Intent.ACTION_MEDIA_EJECT)) {
+ if (updateEmptyView())
+ updateDisplay();
+ }
+ }
+ };
+}
diff --git a/vlc-android/src/org/videolan/vlc/gui/browser/NetworkBrowserAdapter.java b/vlc-android/src/org/videolan/vlc/gui/browser/NetworkBrowserAdapter.java
new file mode 100644
index 0000000..9af76c8
--- /dev/null
+++ b/vlc-android/src/org/videolan/vlc/gui/browser/NetworkBrowserAdapter.java
@@ -0,0 +1,33 @@
+/*
+ * *************************************************************************
+ * NetworkBrowserAdapter.java
+ * **************************************************************************
+ * Copyright © 2015 VLC authors and VideoLAN
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ * ***************************************************************************
+ */
+
+package org.videolan.vlc.gui.browser;
+
+import org.videolan.vlc.R;
+
+public class NetworkBrowserAdapter extends BaseBrowserAdapter{
+
+ public NetworkBrowserAdapter(BaseBrowserFragment fragment){
+ super(fragment);
+ FOLDER_RES_ID = R.drawable.ic_menu_network;
+ }
+}
diff --git a/vlc-android/src/org/videolan/vlc/gui/browser/NetworkBrowserFragment.java b/vlc-android/src/org/videolan/vlc/gui/browser/NetworkBrowserFragment.java
new file mode 100644
index 0000000..e5e3dea
--- /dev/null
+++ b/vlc-android/src/org/videolan/vlc/gui/browser/NetworkBrowserFragment.java
@@ -0,0 +1,173 @@
+/*
+ * *************************************************************************
+ * NetworkBrowserFragment.java
+ * **************************************************************************
+ * Copyright © 2015 VLC authors and VideoLAN
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ * ***************************************************************************
+ */
+
+package org.videolan.vlc.gui.browser;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.ConnectivityManager;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.view.View;
+
+import org.videolan.libvlc.util.MediaBrowser;
+import org.videolan.vlc.MediaDatabase;
+import org.videolan.vlc.MediaWrapper;
+import org.videolan.vlc.R;
+import org.videolan.vlc.util.AndroidDevices;
+
+import java.util.ArrayList;
+
+public class NetworkBrowserFragment extends BaseBrowserFragment {
+
+ public NetworkBrowserFragment() {
+ ROOT = "smb";
+ mHandler = new BrowserFragmentHandler(this);
+ mAdapter = new NetworkBrowserAdapter(this);
+ }
+
+ @Override
+ public void onCreate(Bundle bundle) {
+ super.onCreate(bundle);
+ if (mMrl == null)
+ mMrl = ROOT;
+ mRoot = ROOT.equals(mMrl);
+ }
+
+ public void onStart(){
+ super.onStart();
+
+ //Handle network connection state
+ IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
+ getActivity().registerReceiver(networkReceiver, filter);
+ }
+
+ @Override
+ protected Fragment createFragment() {
+ return new NetworkBrowserFragment();
+ }
+
+ @Override
+ public void onStop() {
+ super.onStop();
+ getActivity().unregisterReceiver(networkReceiver);
+ }
+
+ protected void updateDisplay(){
+ if (mMediaBrowser == null)
+ mMediaBrowser = new MediaBrowser(mLibVLC, this);
+ if (mAdapter.isEmpty())
+ refresh();
+ else if (mRoot)
+ updateFavorites();
+ }
+
+ @Override
+ protected void browseRoot() {
+ ArrayList<MediaWrapper> favs = MediaDatabase.getInstance().getAllNetworkFav();
+ if (!favs.isEmpty()) {
+ mFavorites = favs.size();
+ for (MediaWrapper fav : favs) {
+ mAdapter.addItem(fav, false, true);
+ }
+ mAdapter.addItem("Network favorites", false, true);
+ }
+ mMediaBrowser.discoverNetworkShares();
+ }
+
+ @Override
+ protected String getCategoryTitle() {
+ return getString(R.string.network_browsing);
+ }
+
+ private void updateFavorites(){
+ ArrayList<MediaWrapper> favs = MediaDatabase.getInstance().getAllNetworkFav();
+ int newSize = favs.size(), totalSize = mAdapter.getItemCount();
+
+ if (newSize == 0 && mFavorites == 0)
+ return;
+ for (int i = 1 ; i <= mFavorites ; ++i){ //remove former favorites
+ mAdapter.removeItem(totalSize-i);
+ }
+ if (newSize == 0)
+ mAdapter.removeItem(totalSize-mFavorites-1); //also remove separator if no more fav
+ else {
+ if (mFavorites == 0)
+ mAdapter.addItem("Network favorites", false, false); //add header if needed
+ for (MediaWrapper fav : favs)
+ mAdapter.addItem(fav, false, false); //add new favorites
+ }
+ mFavorites = newSize; //update count
+ }
+
+ public void toggleFavorite() {
+ MediaDatabase db = MediaDatabase.getInstance();
+ if (db.networkFavExists(mMrl))
+ db.deleteNetworkFav(mMrl);
+ else
+ db.addNetworkFavItem(mMrl, mCurrentMedia.getTitle());
+ getActivity().supportInvalidateOptionsMenu();
+ }
+
+ /**
+ * Update views visibility and emptiness info
+ *
+ * @return True if content needs can be refreshed
+ */
+ protected boolean updateEmptyView() {
+ if (AndroidDevices.hasLANConnection()) {
+ if (mAdapter.isEmpty()) {
+ mEmptyView.setText(mRoot ? R.string.network_shares_discovery : R.string.network_empty);
+ mEmptyView.setVisibility(View.VISIBLE);
+ mRecyclerView.setVisibility(View.GONE);
+ mSwipeRefreshLayout.setEnabled(false);
+ } else {
+ if (mEmptyView.getVisibility() == View.VISIBLE) {
+ mEmptyView.setVisibility(View.GONE);
+ mRecyclerView.setVisibility(View.VISIBLE);
+ mSwipeRefreshLayout.setEnabled(true);
+ }
+ }
+ return true;
+ } else {
+ if (mEmptyView.getVisibility() == View.GONE) {
+ mEmptyView.setText(R.string.network_connection_needed);
+ mEmptyView.setVisibility(View.VISIBLE);
+ mRecyclerView.setVisibility(View.GONE);
+ mSwipeRefreshLayout.setEnabled(false);
+ }
+ return false;
+ }
+ }
+
+ private final BroadcastReceiver networkReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+ if (ConnectivityManager.CONNECTIVITY_ACTION.equals(action))
+ if (updateEmptyView())
+ updateDisplay();
+ }
+ };
+}
diff --git a/vlc-android/src/org/videolan/vlc/gui/network/NetworkAdapter.java b/vlc-android/src/org/videolan/vlc/gui/network/NetworkAdapter.java
deleted file mode 100644
index 32cc811..0000000
--- a/vlc-android/src/org/videolan/vlc/gui/network/NetworkAdapter.java
+++ /dev/null
@@ -1,200 +0,0 @@
-/**
- * **************************************************************************
- * NetworkAdapter.java
- * ****************************************************************************
- * Copyright © 2015 VLC authors and VideoLAN
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- * ***************************************************************************
- */
-package org.videolan.vlc.gui.network;
-
-import android.net.Uri;
-import android.support.v7.widget.RecyclerView;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import org.videolan.libvlc.Media;
-import org.videolan.vlc.MediaWrapper;
-import org.videolan.vlc.R;
-import org.videolan.vlc.gui.audio.MediaComparators;
-import org.videolan.vlc.util.Util;
-
-import java.util.ArrayList;
-import java.util.Collections;
-
-public class NetworkAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
- private static final String TAG = "VLC/NetworkAdapter";
-
- private static final int TYPE_MEDIA = 0;
- private static final int TYPE_SEPARATOR = 1;
-
- ArrayList<Object> mMediaList = new ArrayList<Object>();
- NetworkFragment fragment;
-
- public NetworkAdapter(NetworkFragment fragment){
- this.fragment = fragment;
- }
-
- @Override
- public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
- RecyclerView.ViewHolder vh;
- View v;
- if (viewType == TYPE_MEDIA) {
- v = LayoutInflater.from(parent.getContext())
- .inflate(R.layout.directory_view_item, parent, false);
- vh = new MediaViewHolder(v);
- } else {
- v = LayoutInflater.from(parent.getContext())
- .inflate(R.layout.browser_item_separator, parent, false);
- vh = new SeparatorViewHolder(v);
- }
- return vh;
- }
-
- @Override
- public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) {
- if (holder instanceof MediaViewHolder) {
- MediaViewHolder vh = (MediaViewHolder) holder;
- MediaWrapper media = (MediaWrapper) getItem(position);
- vh.title.setText(media.getTitle());
- vh.text.setVisibility(View.GONE);
- vh.icon.setImageResource(getIconResId(media));
- vh.more.setVisibility(View.GONE);
- vh.itemView.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- MediaWrapper mw = (MediaWrapper) getItem(holder.getPosition());
- if (mw.getType() == MediaWrapper.TYPE_DIR)
- fragment.browse(mw);
- else
- Util.openMedia(v.getContext(), mw);
- }
- });
- } else {
- SeparatorViewHolder vh = (SeparatorViewHolder) holder;
- vh.title.setText(getItem(position).toString());
- }
- }
-
- @Override
- public int getItemCount() {
- return mMediaList.size();
- }
-
- public static class MediaViewHolder extends RecyclerView.ViewHolder {
- public TextView title;
- public TextView text;
- public ImageView icon;
- public ImageView more;
-
- public MediaViewHolder(View v) {
- super(v);
- title = (TextView) v.findViewById(R.id.title);
- text = (TextView) v.findViewById(R.id.text);
- icon = (ImageView) v.findViewById(R.id.dvi_icon);
- more = (ImageView) v.findViewById(R.id.item_more);
- }
- }
-
- public static class SeparatorViewHolder extends RecyclerView.ViewHolder {
- public TextView title;
-
- public SeparatorViewHolder(View v) {
- super(v);
- title = (TextView) v.findViewById(R.id.separator_title);
- }
- }
-
- public void clear(){
- mMediaList.clear();
- notifyDataSetChanged();
- }
-
- public boolean isEmpty(){
- return mMediaList.isEmpty();
- }
-
- public void addItem(Media media, boolean root, boolean first){
- MediaWrapper mediaWrapper = new MediaWrapper(media);
- addItem(mediaWrapper, root, first);
-
- }
-
- public void addItem(Object item, boolean root, boolean first){
- int position = first ? 0 : mMediaList.size();
- if (item instanceof MediaWrapper && ((MediaWrapper)item).getTitle().startsWith("."))
- return;
- else if (item instanceof Media)
- item = new MediaWrapper((Media) item);
-
- mMediaList.add(position, item);
- if (root)
- notifyItemInserted(position);
- }
-
- public void removeItem(int position){
- mMediaList.remove(position);
- notifyItemRemoved(position);
- }
-
- public Object getItem(int position){
- return mMediaList.get(position);
- }
-
- public int getItemViewType(int position){
- if (getItem(position) instanceof MediaWrapper)
- return TYPE_MEDIA;
- else
- return TYPE_SEPARATOR;
- }
-
- public void sortList(){
- ArrayList<MediaWrapper> files = new ArrayList<MediaWrapper>(), dirs = new ArrayList<MediaWrapper>();
- for (Object item : mMediaList){
- if (item instanceof MediaWrapper) {
- MediaWrapper media = (MediaWrapper) item;
- if (media.getType() == MediaWrapper.TYPE_DIR)
- dirs.add(media);
- else
- files.add(media);
- }
- }
- Collections.sort(dirs, MediaComparators.byName);
- Collections.sort(files, MediaComparators.byName);
- mMediaList.clear();
- mMediaList.addAll(dirs);
- mMediaList.addAll(files);
- notifyDataSetChanged();
- }
-
- private int getIconResId(MediaWrapper media) {
- switch (media.getType()){
- case MediaWrapper.TYPE_AUDIO:
- return R.drawable.ic_browser_audio_normal;
- case MediaWrapper.TYPE_DIR:
- return R.drawable.ic_menu_network;
- case MediaWrapper.TYPE_VIDEO:
- return R.drawable.ic_browser_video_normal;
- case MediaWrapper.TYPE_SUBTITLE:
- return R.drawable.ic_browser_subtitle_normal;
- default:
- return R.drawable.ic_browser_unknown_normal;
- }
- }
-}
diff --git a/vlc-android/src/org/videolan/vlc/gui/network/NetworkFragment.java b/vlc-android/src/org/videolan/vlc/gui/network/NetworkFragment.java
deleted file mode 100644
index 9562bd4..0000000
--- a/vlc-android/src/org/videolan/vlc/gui/network/NetworkFragment.java
+++ /dev/null
@@ -1,344 +0,0 @@
-/**
- * **************************************************************************
- * NetworkFragment.java
- * ****************************************************************************
- * Copyright © 2015 VLC authors and VideoLAN
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- * ***************************************************************************
- */
-package org.videolan.vlc.gui.network;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.net.ConnectivityManager;
-import android.os.Bundle;
-import android.os.Message;
-import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentTransaction;
-import android.support.v7.widget.LinearLayoutManager;
-import android.support.v7.widget.RecyclerView;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.TextView;
-
-import org.videolan.libvlc.LibVLC;
-import org.videolan.libvlc.Media;
-import org.videolan.libvlc.util.MediaBrowser;
-import org.videolan.vlc.MediaDatabase;
-import org.videolan.vlc.MediaWrapper;
-import org.videolan.vlc.R;
-import org.videolan.vlc.gui.BrowserFragment;
-import org.videolan.vlc.gui.DividerItemDecoration;
-import org.videolan.vlc.gui.MainActivity;
-import org.videolan.vlc.interfaces.IRefreshable;
-import org.videolan.vlc.util.AndroidDevices;
-import org.videolan.vlc.util.Strings;
-import org.videolan.vlc.util.VLCInstance;
-import org.videolan.vlc.util.WeakHandler;
-import org.videolan.vlc.widget.SwipeRefreshLayout;
-
-import java.util.ArrayList;
-
-
-public class NetworkFragment extends BrowserFragment implements IRefreshable, MediaBrowser.EventListener, SwipeRefreshLayout.OnRefreshListener {
- private static final String TAG = "VLC/NetworkFragment";
-
- public static final String SMB_ROOT = "smb";
- public static final String KEY_MRL = "key_mrl";
- public static final String KEY_MEDIA = "key_media";
- public static final String KEY_POSITION = "key_list";
-
- private NetworkFragmentHandler mHandler;
- private MediaBrowser mMediaBrowser;
- private RecyclerView mRecyclerView;
- private SwipeRefreshLayout mSwipeRefreshLayout;
- private NetworkAdapter mAdapter;
- private LinearLayoutManager mLayoutManager;
- TextView mEmptyView;
- public String mMrl;
- private MediaWrapper mCurrentMedia;
- private int mSavedPosition = -1, mFavorites = 0;
- private boolean mRoot;
- private LibVLC mLibVLC;
-
- public void onCreate(Bundle bundle){
- super.onCreate(bundle);
- mLibVLC = VLCInstance.get();
-
- if (bundle == null)
- bundle = getArguments();
- if (bundle != null){
- mCurrentMedia = bundle.getParcelable(KEY_MEDIA);
- if (mCurrentMedia != null)
- mMrl = mCurrentMedia.getLocation();
- else
- mMrl = bundle.getString(KEY_MRL);
- mSavedPosition = bundle.getInt(KEY_POSITION);
- }
- if (mMrl == null)
- mMrl = SMB_ROOT;
- mRoot = SMB_ROOT.equals(mMrl);
- mHandler = new NetworkFragmentHandler(this);
- mAdapter = new NetworkAdapter(this);
- }
-
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
- View v = inflater.inflate(R.layout.network_browser, container, false);
- mRecyclerView = (RecyclerView) v.findViewById(R.id.network_list);
- mEmptyView = (TextView) v.findViewById(android.R.id.empty);
- mLayoutManager = new LinearLayoutManager(getActivity());
- mRecyclerView.addItemDecoration(new DividerItemDecoration(getActivity(), DividerItemDecoration.VERTICAL_LIST));
- mRecyclerView.setLayoutManager(mLayoutManager);
- mRecyclerView.setAdapter(mAdapter);
- mRecyclerView.setOnScrollListener(mScrollListener);
-
- mSwipeRefreshLayout = (SwipeRefreshLayout) v.findViewById(R.id.swipeLayout);
- mSwipeRefreshLayout.setColorSchemeResources(R.color.orange700);
- mSwipeRefreshLayout.setOnRefreshListener(this);
- return v;
- }
-
- public void onStop(){
- super.onStop();
- if (mMediaBrowser != null)
- mMediaBrowser.release();
- }
-
- public void onStart(){
- super.onStart();
-
- //Handle network connection state
- IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
- getActivity().registerReceiver(networkReceiver, filter);
- }
- public void onSaveInstanceState(Bundle outState){
- outState.putString(KEY_MRL, mMrl);
- if (mRecyclerView != null) {
- outState.putInt(KEY_POSITION, mLayoutManager.findFirstCompletelyVisibleItemPosition());
- }
- super.onSaveInstanceState(outState);
- }
-
- public String getTitle(){
- if (mRoot)
- return getString(R.string.network_browsing);
- else
- return mCurrentMedia != null ? mCurrentMedia.getTitle() : mMrl;
- }
-
- public boolean isRootDirectory(){
- return mRoot;
- }
-
- public void goBack(){
- getActivity().getSupportFragmentManager().popBackStack();
- }
-
- public void browse (MediaWrapper media){
- FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
- Fragment next = new NetworkFragment();
- Bundle args = new Bundle();
- args.putParcelable(KEY_MEDIA, media);
- next.setArguments(args);
- ft.replace(R.id.fragment_placeholder, next, media.getLocation());
- ft.addToBackStack(mMrl);
- ft.commit();
- }
-
- @Override
- public void onMediaAdded(int index, Media media) {
- mAdapter.addItem(media, mRoot, true);
- updateEmptyView();
- if (mRoot)
- mHandler.sendEmptyMessage(NetworkFragmentHandler.MSG_HIDE_LOADING);
- }
-
- @Override
- public void onMediaRemoved(int index, Media media) {
- mAdapter.removeItem(index);
- }
-
- @Override
- public void onBrowseEnd() {
- mAdapter.sortList();
- mHandler.sendEmptyMessage(NetworkFragmentHandler.MSG_HIDE_LOADING);
- if (mSavedPosition > 0) {
- mLayoutManager.scrollToPositionWithOffset(mSavedPosition, 0);
- mSavedPosition = 0;
- }
- focusHelper(mAdapter.isEmpty());
- }
-
- @Override
- public void onRefresh() {
- mSavedPosition = mLayoutManager.findFirstCompletelyVisibleItemPosition();
- refresh();
- }
-
- RecyclerView.OnScrollListener mScrollListener = new RecyclerView.OnScrollListener() {
- @Override
- public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
- super.onScrollStateChanged(recyclerView, newState);
- }
-
- @Override
- public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
- int topRowVerticalPosition =
- (recyclerView == null || recyclerView.getChildCount() == 0) ? 0 : recyclerView.getChildAt(0).getTop();
- mSwipeRefreshLayout.setEnabled(topRowVerticalPosition >= 0);
- }
- };
-
- /**
- * Update views visibility and emptiness info
- *
- * @return True if content needs can be refreshed
- */
- private boolean updateEmptyView(){
- if (AndroidDevices.hasLANConnection()){
- if (mAdapter.isEmpty()){
- mEmptyView.setText(mRoot ? R.string.network_shares_discovery : R.string.network_empty);
- mEmptyView.setVisibility(View.VISIBLE);
- mRecyclerView.setVisibility(View.GONE);
- mSwipeRefreshLayout.setEnabled(false);
- } else {
- if (mEmptyView.getVisibility() == View.VISIBLE) {
- mEmptyView.setVisibility(View.GONE);
- mRecyclerView.setVisibility(View.VISIBLE);
- mSwipeRefreshLayout.setEnabled(true);
- }
- }
- return true;
- } else {
- if (mEmptyView.getVisibility() == View.GONE){
- mEmptyView.setText(R.string.network_connection_needed);
- mEmptyView.setVisibility(View.VISIBLE);
- mRecyclerView.setVisibility(View.GONE);
- mSwipeRefreshLayout.setEnabled(false);
- }
- return false;
- }
-
- }
-
- private void updateDisplay(){
- if (mMediaBrowser == null)
- mMediaBrowser = new MediaBrowser(mLibVLC, this);
- if (mAdapter.isEmpty())
- refresh();
- else if (mRoot)
- updateFavorites();
- }
-
- @Override
- public void refresh() {
- mAdapter.clear();
- if (mRoot){
- ArrayList<MediaWrapper> favs = MediaDatabase.getInstance().getAllNetworkFav();
- if (!favs.isEmpty()) {
- mFavorites = favs.size();
- for (MediaWrapper fav : favs) {
- mAdapter.addItem(fav, false, true);
- mAdapter.notifyDataSetChanged();
- }
- mAdapter.addItem("Network favorites", false, true);
- }
- }
- if (mRoot)
- mMediaBrowser.discoverNetworkShares();
- else
- mMediaBrowser.browse(mMrl);
- mHandler.sendEmptyMessageDelayed(NetworkFragmentHandler.MSG_SHOW_LOADING, 300);
- }
-
- private void updateFavorites(){
- ArrayList<MediaWrapper> favs = MediaDatabase.getInstance().getAllNetworkFav();
- int newSize = favs.size(), totalSize = mAdapter.getItemCount();
-
- if (newSize == 0 && mFavorites == 0)
- return;
- for (int i = 1 ; i <= mFavorites ; ++i){ //remove former favorites
- mAdapter.removeItem(totalSize-i);
- }
- if (newSize == 0)
- mAdapter.removeItem(totalSize-mFavorites-1); //also remove separator if no more fav
- else {
- if (mFavorites == 0)
- mAdapter.addItem("Network favorites", false, false); //add header if needed
- for (MediaWrapper fav : favs)
- mAdapter.addItem(fav, false, false); //add new favorites
- }
- mFavorites = newSize; //update count
- }
-
- public void toggleFavorite() {
- MediaDatabase db = MediaDatabase.getInstance();
- if (db.networkFavExists(mMrl))
- db.deleteNetworkFav(mMrl);
- else
- db.addNetworkFavItem(mMrl, mCurrentMedia.getTitle());
- getActivity().supportInvalidateOptionsMenu();
- }
-
- private static class NetworkFragmentHandler extends WeakHandler<NetworkFragment> {
-
- public static final int MSG_SHOW_LOADING = 0;
- public static final int MSG_HIDE_LOADING = 1;
-
- public NetworkFragmentHandler(NetworkFragment owner) {
- super(owner);
- }
- @Override
- public void handleMessage(Message msg) {
- NetworkFragment fragment = getOwner();
- switch (msg.what){
- case MSG_SHOW_LOADING:
- fragment.mSwipeRefreshLayout.setRefreshing(true);
- break;
- case MSG_HIDE_LOADING:
- removeMessages(MSG_SHOW_LOADING);
- fragment.mSwipeRefreshLayout.setRefreshing(false);
- break;
- }
- }
- }
-
- private final BroadcastReceiver networkReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
- if (ConnectivityManager.CONNECTIVITY_ACTION.equals(action))
- if (updateEmptyView())
- updateDisplay();
- }
- };
-
- private void focusHelper(boolean idIsEmpty) {
- if (getActivity() == null)
- return;
- MainActivity main = (MainActivity)getActivity();
- View parent = View.inflate(main, R.layout.directory_view, null);
- main.setMenuFocusDown(idIsEmpty, R.id.network_list);
- main.setSearchAsFocusDown(idIsEmpty, parent, R.id.network_list);
- }
-
- public void clear(){
- mAdapter.clear();
- }
-}
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 07f7783..0cdc730 100644
--- a/vlc-android/src/org/videolan/vlc/gui/video/VideoGridFragment.java
+++ b/vlc-android/src/org/videolan/vlc/gui/video/VideoGridFragment.java
@@ -54,8 +54,6 @@ import android.widget.PopupMenu;
import android.widget.PopupMenu.OnMenuItemClickListener;
import android.widget.TextView;
-import org.videolan.libvlc.LibVLC;
-import org.videolan.libvlc.LibVlcException;
import org.videolan.libvlc.LibVlcUtil;
import org.videolan.libvlc.Media;
import org.videolan.vlc.MediaDatabase;
@@ -65,7 +63,7 @@ import org.videolan.vlc.MediaWrapper;
import org.videolan.vlc.R;
import org.videolan.vlc.Thumbnailer;
import org.videolan.vlc.audio.AudioServiceController;
-import org.videolan.vlc.gui.BrowserFragment;
+import org.videolan.vlc.gui.MediaBrowserFragment;
import org.videolan.vlc.gui.CommonDialogs;
import org.videolan.vlc.gui.MainActivity;
import org.videolan.vlc.gui.SecondaryActivity;
@@ -81,7 +79,7 @@ import java.util.List;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
-public class VideoGridFragment extends BrowserFragment implements ISortable, IVideoBrowser, SwipeRefreshLayout.OnRefreshListener, AdapterView.OnItemClickListener {
+public class VideoGridFragment extends MediaBrowserFragment implements ISortable, IVideoBrowser, SwipeRefreshLayout.OnRefreshListener, AdapterView.OnItemClickListener {
public final static String TAG = "VLC/VideoListFragment";
diff --git a/vlc-android/src/org/videolan/vlc/util/AndroidDevices.java b/vlc-android/src/org/videolan/vlc/util/AndroidDevices.java
index bcdfa79..f7a25cb 100644
--- a/vlc-android/src/org/videolan/vlc/util/AndroidDevices.java
+++ b/vlc-android/src/org/videolan/vlc/util/AndroidDevices.java
@@ -31,6 +31,7 @@ import java.util.List;
import java.util.StringTokenizer;
import org.videolan.libvlc.LibVlcUtil;
+import org.videolan.vlc.R;
import org.videolan.vlc.VLCApplication;
import android.annotation.TargetApi;
@@ -41,6 +42,7 @@ import android.os.Build.VERSION;
import android.os.Build.VERSION_CODES;
import android.os.Environment;
import android.telephony.TelephonyManager;
+import android.text.TextUtils;
import android.view.InputDevice;
import android.view.MotionEvent;
@@ -184,4 +186,11 @@ public class AndroidDevices {
return networkEnabled;
}
+
+ public static String getStorageTitle(String path){
+ if (TextUtils.equals(Environment.getExternalStorageDirectory().getPath(), path))
+ return VLCApplication.getAppContext().getString(R.string.internal_memory);
+ else
+ return Strings.getName(path);
+ }
}
diff --git a/vlc-android/src/org/videolan/vlc/util/Util.java b/vlc-android/src/org/videolan/vlc/util/Util.java
index c13e653..b9bc06d 100644
--- a/vlc-android/src/org/videolan/vlc/util/Util.java
+++ b/vlc-android/src/org/videolan/vlc/util/Util.java
@@ -326,6 +326,10 @@ public class Util {
public static boolean canWrite(String path){
if (path == null)
return false;
+ if (path.startsWith("file://"))
+ path = path.substring(7);
+ if (!path.startsWith("/"))
+ return false;
if (path.startsWith(Environment.getExternalStorageDirectory().getPath()))
return true;
if (LibVlcUtil.isLolliPopOrLater())
diff --git a/vlc-android/tv/src/org/videolan/vlc/gui/tv/TvUtil.java b/vlc-android/tv/src/org/videolan/vlc/gui/tv/TvUtil.java
index 78732a7..c198d55 100644
--- a/vlc-android/tv/src/org/videolan/vlc/gui/tv/TvUtil.java
+++ b/vlc-android/tv/src/org/videolan/vlc/gui/tv/TvUtil.java
@@ -20,10 +20,9 @@
package org.videolan.vlc.gui.tv;
import org.videolan.vlc.MediaWrapper;
-import org.videolan.vlc.gui.network.NetworkFragment;
+import org.videolan.vlc.gui.browser.BaseBrowserFragment;
import org.videolan.vlc.gui.tv.browser.VerticalGridActivity;
import org.videolan.vlc.gui.video.VideoPlayerActivity;
-import org.videolan.vlc.interfaces.IVideoBrowser;
import org.videolan.vlc.util.Strings;
import android.app.Activity;
@@ -48,7 +47,7 @@ public class TvUtil {
} else if (mediaWrapper.getType() == MediaWrapper.TYPE_DIR){
Intent intent = new Intent(activity, VerticalGridActivity.class);
intent.putExtra(MainTvActivity.BROWSER_TYPE, MainTvActivity.HEADER_NETWORK);
- intent.putExtra(NetworkFragment.KEY_MRL, mediaWrapper.getLocation());
+ intent.putExtra(BaseBrowserFragment.KEY_MRL, mediaWrapper.getLocation());
activity.startActivity(intent);
}
} else if (item instanceof CardPresenter.SimpleCard){
diff --git a/vlc-android/tv/src/org/videolan/vlc/gui/tv/browser/BrowserGridFragment.java b/vlc-android/tv/src/org/videolan/vlc/gui/tv/browser/BrowserGridFragment.java
index 802bb13..b80968d 100644
--- a/vlc-android/tv/src/org/videolan/vlc/gui/tv/browser/BrowserGridFragment.java
+++ b/vlc-android/tv/src/org/videolan/vlc/gui/tv/browser/BrowserGridFragment.java
@@ -34,7 +34,7 @@ import org.videolan.libvlc.Media;
import org.videolan.libvlc.util.MediaBrowser;
import org.videolan.vlc.MediaWrapper;
import org.videolan.vlc.gui.audio.MediaComparators;
-import org.videolan.vlc.gui.network.NetworkFragment;
+import org.videolan.vlc.gui.browser.BaseBrowserFragment;
import org.videolan.vlc.gui.tv.DetailsActivity;
import org.videolan.vlc.gui.tv.MediaItemDetails;
import org.videolan.vlc.util.VLCInstance;
@@ -52,9 +52,9 @@ public class BrowserGridFragment extends GridFragment implements MediaBrowser.Ev
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState != null){
- mMrl = savedInstanceState.getString(NetworkFragment.KEY_MRL);
+ mMrl = savedInstanceState.getString(BaseBrowserFragment.KEY_MRL);
} else {
- mMrl = getActivity().getIntent().getStringExtra(NetworkFragment.KEY_MRL);
+ mMrl = getActivity().getIntent().getStringExtra(BaseBrowserFragment.KEY_MRL);
}
setOnItemViewSelectedListener(this);
}
--
2.1.0
More information about the Android
mailing list