我通過Xamarin在Android上使用MvvmCross,並且遇到問題。我創建了一個名爲IFileExplorerService的核心服務接口。如何在Xamarin C#上等待OnActivityResult Android
這個接口的目標是打開一個打開的文件對話框,並選擇一個文件,無論設備是什麼(Windows或Android)。
在Android上,我管理easly,通過僅使用OnActivityResult和Intents,通過視圖來完成此操作。
但我只是不能使它從我的視圖工作,因爲接口實現是在設置中註冊的單例,當我從我的viewmodel調用它時,絕對沒有人來處理OnActivityResult。
我試圖讓我的FileExplorer implmentation從Activity或MvxActivity繼承,爲此我的FileExplorer可以重寫OnActivityResult,但是失敗。
我試圖使用StartActivity(typeof(FileExplorer)),但是這顯然會失敗,因爲它不會是在MvvmCross中註冊的單身人員,將會啓動。
有沒有人有任何想法/評論/問題/建議來幫助我呢?
這是到目前爲止我的代碼:
public class FileExplorerService : IFileExplorerServiceMock
{
string _addedFileName;
public static int REQUEST_FILE_CAPTURE = 2;
private bool _hasMediaBeenAdded;
private TaskCompletionSource<String> GetFileTask;
public Activity activity;
public FileExplorerService()
{
GetFileTask = new TaskCompletionSource<string>();
}
private void DispatchSelectFileIntent()
{
Intent Intent = new Intent();
Intent.SetType("*/*");
Intent.SetAction(Intent.ActionGetContent);
activity.StartActivityForResult(Intent.CreateChooser(Intent, "Select File"), REQUEST_FILE_CAPTURE);
}
public void OnActivityResult(int requestCode, [GeneratedEnum] Result resultCode, Intent data)
{
//
if (resultCode == Result.Ok)
{
if (data != null)
{
bool isFileCopied = CopySelectedFileToAddedFilesDirectory(data.Data);
if (isFileCopied)
{
//everything went well
ShowSuccesAlertDialog();
GetFileTask.SetResult(_addedFileName);
}
else
{
ShowFailureAlertDialog();
//oops something crashed
//Log
}
}
}
else
{
_addedFileName = String.Empty;
}
}
private void ShowFailureAlertDialog()
{
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
AlertDialog alertDialog = builder.Create();
alertDialog.SetTitle("Oops... something went wrong");
alertDialog.SetIcon(Android.Resource.Drawable.IcDialogAlert);
alertDialog.SetMessage("Something went rong when adding a media");
alertDialog.SetButton("Ok", (s, ev) =>
{
});
alertDialog.Show();
}
private void ShowSuccesAlertDialog()
{
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
AlertDialog alertDialog = builder.Create();
alertDialog.SetTitle("Media added with succes !");
alertDialog.SetIcon(Android.Resource.Drawable.IcDialogAlert);
alertDialog.SetMessage("Your media has been added with succes");
alertDialog.SetButton("Ok", (s, ev) =>
{
_hasMediaBeenAdded = true;
});
alertDialog.Show();
}
private void DeletePreviousAddedFile()
{
//todo delete file only if selected rex type is the same
if (_hasMediaBeenAdded)
{
MsFile.Delete(_addedFileName);
_addedFileName = string.Empty;
_hasMediaBeenAdded = false;
}
}
private static string GetRealPathFromURI(Context _context, Android.Net.Uri contentUri)
{
string[] projection = new string[] { MediaStore.MediaColumns.Data };
ContentResolver cr = _context.ContentResolver;
Android.Database.ICursor cursor = cr.Query(contentUri, projection, null, null, null);
if (cursor != null && cursor.Count > 0)
{
cursor.MoveToFirst();
int index = cursor.GetColumnIndex(Android.Provider.MediaStore.MediaColumns.Data);
return cursor.GetString(index);
}
return "";
}
private bool CopySelectedFileToAddedFilesDirectory(Android.Net.Uri data)
{
var dir = new Java.IO.File(Android.OS.Environment.ExternalStorageDirectory.AbsolutePath + "/Medias/AddedMedias/Files/");
if (!dir.Exists())
dir.Mkdirs();
string path = Android.OS.Environment.ExternalStorageDirectory.AbsolutePath + "/Medias/AddedMedias/Files/";
JavaFile file = new Java.IO.File(path);
string realPath = GetRealPathFromURI(activity.ApplicationContext, data);
string FileName = realPath.Split('/').Last();
_addedFileName = Path.Combine(dir + "/" + FileName);
if (!string.IsNullOrEmpty(realPath))
{
//todo manage errors
using (FileStream fs = new FileStream(realPath, FileMode.Open))
{
byte[] datas = new byte[fs.Length];
int numberBytesToRead = (int)fs.Length;
int numBytesRead = 0;
while (numberBytesToRead > 0)
{
int n = fs.Read(datas, numBytesRead, numberBytesToRead);
if (n == 0)
{
break;
}
numBytesRead += n;
numberBytesToRead -= n;
}
using (FileStream fs2 = System.IO.File.OpenWrite(Path.Combine(dir + "/" + FileName)))
{
fs2.Write(datas, 0, datas.Length);
}
}
return true;
}
return false;
}
public List<FileType> FileTypes
{
get
{
return new List<FileType>();
}
}
public async Task<string> Show(string fiel)
{
if (activity != null)
{
DeletePreviousAddedFile();
DispatchSelectFileIntent();
return GetFileTask.Task.Result;
}
else
{
return String.Empty;
}
}
而且在我看來:
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.RexView);
_addMediaController = new AddMediaController(this, (RexViewModel)base.ViewModel);
_flyoutMenuAnimator = new FlyoutMenuAnimator(this);
var t= Mvx.Resolve<IFileExplorerServiceMock>() as FileExplorerService;
t.activity = this;
}
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
var t = Mvx.Resolve<IFileExplorerServiceMock>() as FileExplorerService;
t.OnActivityResult(requestCode, resultCode, data);
base.OnActivityResult(requestCode, resultCode, data);
}
隨着只是OnActivityResult這一切工作,我的看法是從來沒有所謂的