2016-06-30 43 views
0

我通過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這一切工作,我的看法是從來沒有所謂的

回答

2

好吧,我解決了它!由於這個鏈接https://forums.xamarin.com/discussion/45691/pass-data-from-android-project-to-pcl

我不得不重寫開始活動,以回調作爲參數,回調是我的文件資源管理器中的OnActivityResult。

,這裏是我的人的代碼需要它: 在MyView的:

private Action<int, Result, Intent> _resultCallback; 

     public void StartActivity(Intent intent,int resultCode, Action<int, Result, Intent> resultCallback) 
     { 
      _resultCallback = resultCallback; 

      StartActivityForResult(intent, resultCode); 
     } 

     protected override void OnActivityResult(int requestCode, Result resultCode, Intent data) 
     { 
      base.OnActivityResult(requestCode, resultCode, data); 
      if (_resultCallback != null) 
      { 
       _resultCallback(requestCode, resultCode, data); 
       _resultCallback = null; 
      } 
     } 

,在我的文件資源管理器:

string _addedFileName; 
     public static int REQUEST_FILE_CAPTURE = 2; 
     private bool _hasMediaBeenAdded; 
     private TaskCompletionSource<String> GetFileTask; 
     public RexView activity; 
     public FileExplorerService() 
     { 
     } 


     private void DispatchSelectFileIntent() 
     { 
      Intent intent = new Intent(); 
      intent.SetType("*/*"); 
      intent.SetAction(Intent.ActionGetContent); 

      GetFileTask = new TaskCompletionSource<string>(); 
      activity.StartActivity(Intent.CreateChooser(intent, "Select File"), REQUEST_FILE_CAPTURE, OnActivityResult); 
     // 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 await GetFileTask.Task; 
      } 
      else 
      { 
       return String.Empty; 
      } 
     } 
    } 

在我看來模型

private async void BrowseMedias() 
     { 
      var fileExplorerService = Mvx.Resolve<IFileExplorerServiceMock>(); 
      fileExplorerService.FileTypes.Add(FileType.Picture); 
      string fileSavedPath = await fileExplorerService.Show(DatabaseContentPath); 
      /* file managment*/ 
     }