2016-06-30 23 views
0

私はXamarin経由でAndroidでMvvmCrossを使用していますが、問題があります。 IFileExplorerServiceというコアサービスインターフェイスを作成しました。AndroidでXamarin C#でOnActivityResultを待つ方法

このインタフェースの目標は、開いているファイルダイアログを開いて、デバイスが何であれ(WindowsまたはAndroid)ファイルを選択することです。

私はonActivityResultとIntentsを使用するだけで、私のインターフェースなしでこれを行うことができます。

しかし、インターフェイスの実装がセットアップで登録されているため、私のビューからは機能しません。私はViewModelから呼び出すと、OnActivityResultを処理することは絶対にありません。

FileExplorerの実装で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; 
      } 

}

そして、私の見解では:そのOnActivityResult除いて、このすべての作業を

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

私の見解で呼び出されることはありません

答えて

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*/ 
     } 
ここ

は、それを必要とする人のための私のコードです

関連する問題