Browse Source

Use MediaBrowser to browse local files

1.4.x
Geoffrey Métais 11 years ago
parent
commit
90abd11ad7
  1. 2
      vlc-android/res/layout/directory_view_item.xml
  2. 14
      vlc-android/src/org/videolan/vlc/gui/BrowserActivity.java
  3. 7
      vlc-android/src/org/videolan/vlc/gui/DirectoryViewFragment.java
  4. 2
      vlc-android/src/org/videolan/vlc/gui/HistoryFragment.java
  5. 33
      vlc-android/src/org/videolan/vlc/gui/MainActivity.java
  6. 4
      vlc-android/src/org/videolan/vlc/gui/MediaBrowserAdapter.java
  7. 2
      vlc-android/src/org/videolan/vlc/gui/MediaBrowserFragment.java
  8. 10
      vlc-android/src/org/videolan/vlc/gui/SidebarAdapter.java
  9. 4
      vlc-android/src/org/videolan/vlc/gui/audio/AudioAlbumsSongsFragment.java
  10. 5
      vlc-android/src/org/videolan/vlc/gui/audio/AudioBrowserFragment.java
  11. 50
      vlc-android/src/org/videolan/vlc/gui/browser/BaseBrowserAdapter.java
  12. 290
      vlc-android/src/org/videolan/vlc/gui/browser/BaseBrowserFragment.java
  13. 137
      vlc-android/src/org/videolan/vlc/gui/browser/FileBrowserFragment.java
  14. 33
      vlc-android/src/org/videolan/vlc/gui/browser/NetworkBrowserAdapter.java
  15. 173
      vlc-android/src/org/videolan/vlc/gui/browser/NetworkBrowserFragment.java
  16. 6
      vlc-android/src/org/videolan/vlc/gui/video/VideoGridFragment.java
  17. 9
      vlc-android/src/org/videolan/vlc/util/AndroidDevices.java
  18. 4
      vlc-android/src/org/videolan/vlc/util/Util.java
  19. 5
      vlc-android/tv/src/org/videolan/vlc/gui/tv/TvUtil.java
  20. 6
      vlc-android/tv/src/org/videolan/vlc/gui/tv/browser/BrowserGridFragment.java

2
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" />

14
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()) {

7
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();

2
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;

33
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);

4
vlc-android/src/org/videolan/vlc/gui/BrowserAdapter.java → vlc-android/src/org/videolan/vlc/gui/MediaBrowserAdapter.java

@ -41,13 +41,13 @@ import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.TextView;
public class BrowserAdapter extends ArrayAdapter<File>
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 BrowserAdapter(Context context) {
public MediaBrowserAdapter(Context context) {
super(context, 0);
}

2
vlc-android/src/org/videolan/vlc/gui/BrowserFragment.java → vlc-android/src/org/videolan/vlc/gui/MediaBrowserFragment.java

@ -27,7 +27,7 @@ import android.support.v7.app.ActionBarActivity;
import org.videolan.vlc.widget.SwipeRefreshLayout;
public abstract class BrowserFragment extends Fragment {
public abstract class MediaBrowserFragment extends Fragment {
protected SwipeRefreshLayout mSwipeRefreshLayout;
protected volatile boolean mReadyToDisplay = true;

10
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.

4
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";

5
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;

50
vlc-android/src/org/videolan/vlc/gui/network/NetworkAdapter.java → vlc-android/src/org/videolan/vlc/gui/browser/BaseBrowserAdapter.java

@ -1,6 +1,6 @@
/**
* **************************************************************************
* NetworkAdapter.java
* BaseBrowserAdapter.java
* ****************************************************************************
* Copyright © 2015 VLC authors and VideoLAN
*
@ -19,9 +19,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
* ***************************************************************************
*/
package org.videolan.vlc.gui.network;
package org.videolan.vlc.gui.browser;
import android.net.Uri;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
@ -38,16 +37,18 @@ 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";
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>();
NetworkFragment fragment;
BaseBrowserFragment fragment;
public NetworkAdapter(NetworkFragment fragment){
public BaseBrowserAdapter(BaseBrowserFragment fragment){
this.fragment = fragment;
}
@ -70,12 +71,15 @@ public class NetworkAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
@Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) {
if (holder instanceof MediaViewHolder) {
MediaViewHolder vh = (MediaViewHolder) holder;
MediaWrapper media = (MediaWrapper) getItem(position);
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(View.GONE);
vh.more.setVisibility(hasContextMenu ? View.VISIBLE : View.GONE);
vh.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
@ -86,6 +90,21 @@ public class NetworkAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
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());
@ -97,7 +116,7 @@ public class NetworkAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
return mMediaList.size();
}
public static class MediaViewHolder extends RecyclerView.ViewHolder {
public class MediaViewHolder extends RecyclerView.ViewHolder {
public TextView title;
public TextView text;
public ImageView icon;
@ -136,16 +155,15 @@ public class NetworkAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
}
public void addItem(Object item, boolean root, boolean first){
int position = first ? 0 : mMediaList.size();
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);
if (root)
notifyItemInserted(position);
notifyItemInserted(position);
}
public void removeItem(int position){
@ -188,7 +206,7 @@ public class NetworkAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
case MediaWrapper.TYPE_AUDIO:
return R.drawable.ic_browser_audio_normal;
case MediaWrapper.TYPE_DIR:
return R.drawable.ic_menu_network;
return FOLDER_RES_ID;
case MediaWrapper.TYPE_VIDEO:
return R.drawable.ic_browser_video_normal;
case MediaWrapper.TYPE_SUBTITLE:

290
vlc-android/src/org/videolan/vlc/gui/network/NetworkFragment.java → vlc-android/src/org/videolan/vlc/gui/browser/BaseBrowserFragment.java

@ -1,6 +1,6 @@
/**
* **************************************************************************
* NetworkFragment.java
* BaseBrowserFragment.java
* ****************************************************************************
* Copyright © 2015 VLC authors and VideoLAN
*
@ -19,63 +19,79 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
* ***************************************************************************
*/
package org.videolan.vlc.gui.network;
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.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.MediaDatabase;
import org.videolan.vlc.MediaLibrary;
import org.videolan.vlc.MediaWrapper;
import org.videolan.vlc.R;
import org.videolan.vlc.gui.BrowserFragment;
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.AndroidDevices;
import org.videolan.vlc.util.Strings;
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.util.ArrayList;
import java.io.File;
import java.io.IOException;
public class NetworkFragment extends BrowserFragment implements IRefreshable, MediaBrowser.EventListener, SwipeRefreshLayout.OnRefreshListener {
private static final String TAG = "VLC/NetworkFragment";
public abstract class BaseBrowserFragment extends MediaBrowserFragment implements IRefreshable, MediaBrowser.EventListener, SwipeRefreshLayout.OnRefreshListener {
protected static final String TAG = "VLC/BaseBrowserFragment";
public static final String SMB_ROOT = "smb";
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";
private NetworkFragmentHandler mHandler;
private MediaBrowser mMediaBrowser;
private RecyclerView mRecyclerView;
private SwipeRefreshLayout mSwipeRefreshLayout;
private NetworkAdapter mAdapter;
private LinearLayoutManager mLayoutManager;
TextView mEmptyView;
protected BrowserFragmentHandler mHandler;
protected MediaBrowser mMediaBrowser;
protected RecyclerView mRecyclerView;
protected BaseBrowserAdapter mAdapter;
protected LinearLayoutManager mLayoutManager;
protected TextView mEmptyView;
public String mMrl;
private MediaWrapper mCurrentMedia;
private int mSavedPosition = -1, mFavorites = 0;
private boolean mRoot;
private LibVLC mLibVLC;
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);
@ -91,11 +107,6 @@ public class NetworkFragment extends BrowserFragment implements IRefreshable, Me
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){
@ -120,13 +131,6 @@ public class NetworkFragment extends BrowserFragment implements IRefreshable, Me
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) {
@ -135,24 +139,24 @@ public class NetworkFragment extends BrowserFragment implements IRefreshable, Me
super.onSaveInstanceState(outState);
}
public boolean isRootDirectory(){
return mRoot;
}
public String getTitle(){
if (mRoot)
return getString(R.string.network_browsing);
return getCategoryTitle();
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();
Fragment next = createFragment();
Bundle args = new Bundle();
args.putParcelable(KEY_MEDIA, media);
next.setArguments(args);
@ -161,12 +165,13 @@ public class NetworkFragment extends BrowserFragment implements IRefreshable, Me
ft.commit();
}
@Override
public void onMediaAdded(int index, Media media) {
mAdapter.addItem(media, mRoot, true);
updateEmptyView();
if (mRoot)
mHandler.sendEmptyMessage(NetworkFragmentHandler.MSG_HIDE_LOADING);
mHandler.sendEmptyMessage(BrowserFragmentHandler.MSG_HIDE_LOADING);
}
@Override
@ -177,7 +182,7 @@ public class NetworkFragment extends BrowserFragment implements IRefreshable, Me
@Override
public void onBrowseEnd() {
mAdapter.sortList();
mHandler.sendEmptyMessage(NetworkFragmentHandler.MSG_HIDE_LOADING);
mHandler.sendEmptyMessage(BrowserFragmentHandler.MSG_HIDE_LOADING);
if (mSavedPosition > 0) {
mLayoutManager.scrollToPositionWithOffset(mSavedPosition, 0);
mSavedPosition = 0;
@ -210,103 +215,49 @@ public class NetworkFragment extends BrowserFragment implements IRefreshable, Me
*
* @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;
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;
}
private void updateDisplay(){
protected 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();
browseRoot();
else
mMediaBrowser.browse(mMrl);
mHandler.sendEmptyMessageDelayed(NetworkFragmentHandler.MSG_SHOW_LOADING, 300);
mHandler.sendEmptyMessageDelayed(BrowserFragmentHandler.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> {
protected static class BrowserFragmentHandler extends WeakHandler<BaseBrowserFragment> {
public static final int MSG_SHOW_LOADING = 0;
public static final int MSG_HIDE_LOADING = 1;
public NetworkFragmentHandler(NetworkFragment owner) {
public BrowserFragmentHandler(BaseBrowserFragment owner) {
super(owner);
}
@Override
public void handleMessage(Message msg) {
NetworkFragment fragment = getOwner();
BaseBrowserFragment fragment = getOwner();
switch (msg.what){
case MSG_SHOW_LOADING:
fragment.mSwipeRefreshLayout.setRefreshing(true);
@ -319,17 +270,7 @@ public class NetworkFragment extends BrowserFragment implements IRefreshable, Me
}
}
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) {
protected void focusHelper(boolean idIsEmpty) {
if (getActivity() == null)
return;
MainActivity main = (MainActivity)getActivity();
@ -341,4 +282,97 @@ public class NetworkFragment extends BrowserFragment implements IRefreshable, Me
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();
}
}

137
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();
}
}
};
}

33
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;
}
}

173
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();
}
};
}

6
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";

9
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);
}
}

4
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())

5
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){

6
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);
}

Loading…
Cancel
Save