160 строки
5.7 KiB
C#
Executable File
160 строки
5.7 KiB
C#
Executable File
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
|
|
using Android;
|
|
using Android.Content.PM;
|
|
using Android.OS;
|
|
using Android.Support.Design.Widget;
|
|
using Android.Support.V4.App;
|
|
using Android.Util;
|
|
using Android.Views;
|
|
using Android.Widget;
|
|
|
|
namespace com.xamarin.recipes.filepicker
|
|
{
|
|
/// <summary>
|
|
/// A ListFragment that will show the files and subdirectories of a given directory.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// <para> This was placed into a ListFragment to make this easier to share this functionality with with tablets. </para>
|
|
/// <para>
|
|
/// Note that this is a incomplete example. It lacks things such as the ability to go back up the directory
|
|
/// tree, or any special handling of a file when it is selected.
|
|
/// </para>
|
|
/// </remarks>
|
|
public class FileListFragment : ListFragment
|
|
{
|
|
public static readonly string DefaultInitialDirectory = "/sdcard";
|
|
FileListAdapter adapter;
|
|
DirectoryInfo directoryInfo;
|
|
Action<View> requestPermissionHandler;
|
|
static string[] REQUIRED_PERMISSIONS = new[] {Manifest.Permission.ReadExternalStorage};
|
|
|
|
public override void OnCreate(Bundle savedInstanceState)
|
|
{
|
|
base.OnCreate(savedInstanceState);
|
|
adapter = new FileListAdapter(Activity, new FileSystemInfo[0]);
|
|
ListAdapter = adapter;
|
|
|
|
}
|
|
|
|
public override void OnListItemClick(ListView l, View v, int position, long id)
|
|
{
|
|
var fileSystemInfo = adapter.GetItem(position);
|
|
|
|
if (fileSystemInfo.IsFile())
|
|
{
|
|
// Do something with the file. In this case we just pop some toast.
|
|
Log.Verbose("FileListFragment", "The file {0} was clicked.", fileSystemInfo.FullName);
|
|
Toast.MakeText(Activity, "You selected file " + fileSystemInfo.FullName, ToastLength.Short).Show();
|
|
}
|
|
else
|
|
{
|
|
// Dig into this directory, and display it's contents
|
|
RefreshFilesList(fileSystemInfo.FullName);
|
|
}
|
|
|
|
base.OnListItemClick(l, v, position, id);
|
|
}
|
|
|
|
public override void OnResume()
|
|
{
|
|
base.OnResume();
|
|
if (Activity.PermissionsHaveBeenGranted())
|
|
{
|
|
RefreshFilesList(DefaultInitialDirectory);
|
|
}
|
|
else
|
|
{
|
|
RequestExternalStoragePermissions();
|
|
}
|
|
}
|
|
|
|
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Permission[] grantResults)
|
|
{
|
|
if (requestCode == Helpers.REQUEST_STORAGE)
|
|
{
|
|
if (grantResults.VerifyPermissions())
|
|
{
|
|
RefreshFilesList(DefaultInitialDirectory);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
|
|
}
|
|
}
|
|
|
|
void RequestExternalStoragePermissions()
|
|
{
|
|
if (ActivityCompat.ShouldShowRequestPermissionRationale(Activity, Manifest.Permission.ReadExternalStorage))
|
|
{
|
|
var rootView = Activity.FindViewById<View>(Android.Resource.Id.Content);
|
|
requestPermissionHandler = delegate
|
|
{
|
|
ActivityCompat.RequestPermissions(Activity, REQUIRED_PERMISSIONS, Helpers.REQUEST_STORAGE);
|
|
};
|
|
Snackbar.Make(rootView, Resource.String.permission_externalstorage_rationale, Snackbar.LengthIndefinite)
|
|
.SetAction(Resource.String.ok, requestPermissionHandler)
|
|
.Show();
|
|
}
|
|
else
|
|
{
|
|
ActivityCompat.RequestPermissions(Activity, REQUIRED_PERMISSIONS, Helpers.REQUEST_STORAGE);
|
|
}
|
|
}
|
|
public void RefreshFilesList(string directory)
|
|
{
|
|
|
|
if (!Activity.PermissionsHaveBeenGranted())
|
|
{
|
|
Activity.ShowSimpleSnackbar("Don't have permissions to read external storage.");
|
|
return;
|
|
}
|
|
|
|
IList<FileSystemInfo> visibleThings = new List<FileSystemInfo>();
|
|
var dir = new DirectoryInfo(directory);
|
|
|
|
try
|
|
{
|
|
foreach (var item in dir.GetFileSystemInfos().Where(item => item.IsVisible()))
|
|
{
|
|
visibleThings.Add(item);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Log.Error("FileListFragment", "Couldn't access the directory " + dir.FullName + "; " + ex);
|
|
Toast.MakeText(Activity, "Problem retrieving contents of " + directory, ToastLength.Long).Show();
|
|
return;
|
|
}
|
|
|
|
directoryInfo = dir;
|
|
adapter.AddDirectoryContents(visibleThings);
|
|
|
|
// If we don't do this, then the ListView will not update itself when then data set
|
|
// in the adapter changes. It will appear to the user that nothing has happened.
|
|
ListView.RefreshDrawableState();
|
|
|
|
Log.Verbose("FileListFragment", "Displaying the contents of directory {0}.", directory);
|
|
}
|
|
|
|
public void NavigateUpOneDirectory()
|
|
{
|
|
var parentDir = directoryInfo.Parent;
|
|
var nextDir = directoryInfo.Parent.FullName;
|
|
|
|
if ("/".Equals(nextDir))
|
|
{
|
|
RefreshFilesList(DefaultInitialDirectory);
|
|
}
|
|
else
|
|
{
|
|
RefreshFilesList(parentDir.FullName);
|
|
}
|
|
}
|
|
}
|
|
}
|