2016-10-18 4 views
0

からSystem.Drawing.Bitmap(Xamarin)として、私は、画面全体のスクリーンショットを取る必要がありますバックグラウンドに送信されないようにします。iOSのスクリーンショット<strong>プライベートアプリ</strong>用アプリのバックグラウンド

同様の質問が掲載されていることが原因のiOSのセキュリティサンドボックス

  • How to take screenshots of running iPhone from background app?に非ジェイルブレイクデバイス上不可能であろうと結論づけ

    以下は私のコードの投稿です。さらに時、私はそれにピクセル毎の操作を実行する必要があるので、スクリーンショットをSystem.Drawing.Bitmapする必要があり、その後

    EDIT 1

    :私はprivate System.Drawing.Bitmap ShootScreen()

    using System; 
    using System.Collections.Generic; 
    using System.Drawing; 
    using System.Threading; 
    
    namespace StackOverflowSnippets 
    { 
        public sealed class ScreenshooterThread 
        { 
         private Thread _t = null;     // Thread-Object: Execution-Helper 
         private Boolean _terminate = false;   // Stop current execution? 
         private Int32 _intervalMS = 0;    // Take Screenshots every ? MS 
         private Queue<Bitmap> _q;     // Queue to store the Screenshots 
    
         #region Interface 
         /// <summary> 
         /// Creates a Screenshooter 
         /// </summary> 
         /// <param name="intervalMS">Defines every how many MS a screenshot should be taken</param> 
         public ScreenshooterThread(Int32 intervalMS = 200) 
         { 
          _intervalMS = intervalMS; 
         } 
    
         /// <summary> 
         /// Starts taking Screenshots 
         /// </summary> 
         public void Run() 
         { 
          if(this.IsRunning || this.IsTerminating) 
          { 
           throw new InvalidOperationException("ScreenshooterThread is currently running or terminating"); 
          } 
    
          lock (this) 
          { 
           _terminate = false; 
           _t = new Thread(this.DoWork); 
           _t.Start(); 
          } 
         } 
    
         /// <summary> 
         /// Stops taking Screenshots 
         /// </summary> 
         public void Stop() 
         { 
          if (!this.IsRunning) return; if (this.IsTerminating) return; 
    
          lock(this) 
          { 
           _terminate = true; 
          } 
         } 
    
         /// <summary> 
         /// Determines whether the Thread is currently running 
         /// </summary> 
         public Boolean IsRunning 
         { 
          get 
          { 
           if (_t == null) return false; 
    
           return _t.IsAlive; 
          } 
         } 
         /// <summary> 
         /// Determines whether Thread-Termination has been invoked 
         /// </summary> 
         public Boolean IsTerminating 
         { 
          get 
          { 
           return _terminate; 
          } 
         } 
    
         /// <summary> 
         /// Get a Screenshot from the Queue. Returns null if none available 
         /// </summary> 
         public Bitmap Deqeue() 
         { 
          lock(_q) 
          { 
           if (_q.Count < 1) return null; 
           return _q.Dequeue(); 
          } 
         } 
    
         #endregion 
    
         #region Implementation Details 
         /// <summary> 
         /// Add a Screenshot to the Queue 
         /// </summary> 
         private void Enqueue(Bitmap b) 
         { 
          lock(_q) 
          { 
           _q.Enqueue(b); 
          } 
         } 
    
         /// <summary> 
         /// Task-Implementation while running 
         /// </summary> 
         private void DoWork() 
         { 
          while(!_terminate) 
          { 
           if (_intervalMS > 0) Thread.Sleep(_intervalMS); 
    
           this.Enqueue(this.ShootScreen()); 
          } 
    
          this.CleanUp(); 
         } 
    
         /// <summary> 
         /// Takes a Screenshot of the device even if the app is in the Background 
         /// </summary> 
         private System.Drawing.Bitmap ShootScreen() 
         { 
          // System.Drawing.Bitmap supported by Xamarin 
          // https://developer.xamarin.com/api/type/System.Drawing.Bitmap/ 
    
          // Method in ObjC: https://stackoverflow.com/questions/33369014/how-to-take-screenshot-of-entire-screen-on-a-jailbroken-ios-device 
    
          throw new NotImplementedException(); 
         } 
         /// <summary> 
         /// Preparing for next launch 
         /// </summary> 
         private void CleanUp() 
         { 
          lock(this) 
          { 
           _terminate = false; 
           _t = null; 
          } 
         } 
         #endregion 
        } 
    } 
    

    の実施PSのヘルプを探しています私が見つけた調査http://sharpmobilecode.com/introduction-to-xamarin-what-it-is-what-it-isnt/次の段落

    たとえば、 System.Drawing.Bitmapを使用する既存のC#コードがあるとします。あなたが書いた共通のライブラリです。 デスクトップアプリケーションのリファレンスです。あなたがXamarin.iOSまたはXamarin.Androidアプリでこのメソッドをコンパイルした場合、あなたはコンパイルエラーになるだろう

    using System.Drawing; 
    
    public Bitmap GetBitmapFromCache(string fileName) 
    { 
        return (Bitmap) Image.FromFile(fileName); 
    }  
    

    :可能な方法は、次のようになります。ハァッ? をさらに調査すると、System.Drawing.BitmapSystem.Drawing.Imageが定義されていないことがわかります。何!?!?それは有効なC# 構文です!さらに調査すると、 System.Drawingの中にいくつかのクラスが実際に定義されています(RectangleF、PointFなど)。 ここでは、ビットマップとイメージはどうですか?まあ、これらの クラスがMono Frameworkに実装されていないのは正当な理由があります。 はクロスプラットフォームと互換性がないためです。

    これはどういう意味ですか? MSDNのSystem.Drawing のドキュメントを見てみましょう。 "System.Drawing名前空間 は、GDI +基本グラフィックス機能へのアクセスを提供します。" GDI +とは何ですか? GDI +(Graphics Device Interface)は、Windowsオペレーティングシステム固有の というグラフィックスライブラリ(Win32)です。したがって、 System.Drawingのフードの下。Bitmapは、Windowsデスクトップ/サーバーオペレーティングシステム に関連するWin32実装です。つまり、 System.Drawing.BitmapとSystem.Drawing.Imageはプラットフォームに依存し、 で、Windowsデスクトップ/サーバーアプリケーションでのみ動作します。 は、iOSアプリ、Androidアプリ、またはWindows Phone アプリでこれらのクラスを使用することはできません。では、iOSやAndroidの アプリでこの現在のC#コードをどのように使用できますか?このような若干の変更の場合:

    public byte[] GetBitmapFromCache(string fileName) 
    { 
        return File.ReadAllBytes(fileName); 
    } 
    

    iOSとAndroidのは、しかし、各プラットフォームは、独自の実装に バイトの配列を変換する方法を知っているGDI +ビットマップ (System.Drawing.Bitmap)の概念はありませんビットマップ iOSを使用すると、バイト配列からUIImageを作成でき、 では同じ配列からAndroid.Graphics.Bitmapを作成できます。

  • 答えて

    0

    System.Drawing名前空間は、iOS版のWindows OSに固有のため、単純に利用できないGDI +の基本グラフィックス機能へのアクセスを提供しますので、System.Drawing.Bitmapを作成することはできませんhttp://sharpmobilecode.com/introduction-to-xamarin-what-it-is-what-it-isnt/の下で述べたように。

    1. How to take screenshot of entire screen on a Jailbroken iOS Device?を次のようにUIImageとしてスクリーンショットを作成することが可能であるが、所望のスクリーンショットを返すプライベート関数_UICreateScreenUIImage(void)が存在することを示しました。この機能にアクセスするためには、それが呼び出されると、返されたのIntPtrは、ネイティブUIImageを指すとRuntime.GetNSObject(IntPtr)

      IntPtr ptr = _UICreateScreenUIImage(); 
      UIImage uiimg = Runtime.GetNSObject(ptr) as UIImage; 
      
      によって行われる管理対象オブジェクトの中にラップする必要が

      using System.Runtime.InteropServices; 
      using ObjCRuntime; 
      
      [DLLImport(/*ObjCRuntime.*/Constants.UIKitLibrary)] 
      extern static IntPtr _UICreateScreenUIImage(); 
      
    2. 宣言する必要があります

      uiimg

    添付の写真は上の最小限の例が含まれているスクリーンショットを含ん方法Cにスクリーンショットをreateと.jpeg

    Minimalistic example on how to create and save a screenshot

    とアプリがバックグラウンド

    Picture of what a screenshot looks like

    のときにスクリーンショットがどのように見えるかの例として、それを保存