LoginSignup
17
8

More than 5 years have passed since last update.

スクリーンショットをandroid端末に保存する

Last updated at Posted at 2017-06-12

環境

Unity5.6.1f1
Android7.0

概要

Application.CaptureScreenshot()を実行するだけでは保存されません
スクリーンショットをストレージに保存し、メディアフォルダにも保存しています

ストレージ書き込みパーミッションの付与(WRITE_EXTERNAL_STORAGE)

・「BuildSettings」>「switchPlatform」でandroidにスイッチする
・「PlayerSetting」>「OtherSettings」>「WritePermission」を「External(SDcard)」に変更する

プログラム

ファイル保存した後はScanFileを実行する(重要)

ファイルを保存した後はscanFileを実行し、インデックス情報にファイルを登録してあげないとなりません
そうしないとPCと接続した時にファイルが見えず、パニックになります

using System;
using System.Collections;
using System.IO;
using UnityEngine;

public class TestCapture : MonoBehaviour
{
    private string _fileName = "";
    void Start ()
    {
        StartCoroutine( WriteFileProcess() );
    }

    void Update ()
    {
    }

    private IEnumerator WriteFileProcess()
    {
        _fileName = "Screenshot" + DateTime.Now.ToString("yyyyMMddHHmmss") + ".png";
        yield return CaptureScreenshotProcess();
        yield return MediaDirWriteFileProcess();
    }

    private IEnumerator CaptureScreenshotProcess()
    {
        Debug.Log( "CaptureScreenshotProcess" );
        yield return new WaitForEndOfFrame();
        string path = null;
#if UNITY_EDITOR
        path = _fileName;
#elif UNITY_ANDROID
        path = Application.persistentDataPath + "/" + _fileName;
#endif

        Debug.Log( "BeginCaptureScreenshot:" + path );
        Application.CaptureScreenshot( _fileName );
        Debug.Log( "AfterCaptureScreenshot:" + path );

        while ( File.Exists( path ) == false )
        {
            Debug.Log( "NoFile:" + path );
            yield return new WaitForEndOfFrame();
        }

        Debug.Log( "CaptureOK:" + path );
        scanFile( path, null );//"image/png";
    }

    private IEnumerator MediaDirWriteFileProcess()
    {
        Debug.Log( "MediaDirWriteFileProcess" );
        if( Application.platform != RuntimePlatform.Android )
            yield return null;
#if UNITY_ANDROID
        var path = Application.persistentDataPath + "/" + _fileName;
        while ( File.Exists( path ) == false )
        {
            Debug.Log( "NoFile:" + path );
            yield return new WaitForEndOfFrame();
        }
        // 保存パスを取得
        using( AndroidJavaClass jcEnvironment = new AndroidJavaClass("android.os.Environment") )
        using(AndroidJavaObject joPublicDir = jcEnvironment.CallStatic<AndroidJavaObject>("getExternalStoragePublicDirectory", jcEnvironment.GetStatic<string>( "DIRECTORY_PICTURES"/*"DIRECTORY_DCIM"*/ ) ) )
        {
            var outputPath = joPublicDir.Call<string>( "toString" );
            Debug.Log( "MediaDir:" + outputPath );
//              outputPath += "/100ANDRO/" + _fileName;
            outputPath += "/Screenshots/" + _fileName;
            var pngBytes = File.ReadAllBytes( path );
            File.WriteAllBytes( outputPath, pngBytes );
            yield return new WaitForEndOfFrame();
            while ( File.Exists( outputPath ) == false )
            {
                Debug.Log( "NoFile:" + outputPath );
                yield return new WaitForEndOfFrame();
            }
            Debug.Log( "MediaDirWriteFileOK:" + outputPath );
            scanFile( outputPath, null );
        }
#endif
    }

    //インデックス情報にファイル名を登録する
    //これをしないとPC から内部ストレージを参照した時にファイルが見えない
    static void scanFile( string path, string mimeType )
    {
        if( Application.platform != RuntimePlatform.Android )
             return;
#if UNITY_ANDROID
        using( AndroidJavaClass jcUnityPlayer = new AndroidJavaClass( "com.unity3d.player.UnityPlayer" ) )
        using( AndroidJavaObject joActivity = jcUnityPlayer.GetStatic<AndroidJavaObject>( "currentActivity" ) )
        using( AndroidJavaObject joContext = joActivity.Call<AndroidJavaObject>( "getApplicationContext" ) )
        using( AndroidJavaClass jcMediaScannerConnection = new AndroidJavaClass( "android.media.MediaScannerConnection" ) )
        using( AndroidJavaClass jcEnvironment = new AndroidJavaClass( "android.os.Environment" ) )
        using( AndroidJavaObject joExDir = jcEnvironment.CallStatic<AndroidJavaObject>( "getExternalStorageDirectory" ) )
        {
            Debug.Log( "scanFile:" + path );
            var mimeTypes = ( mimeType != null ) ? new string[] { mimeType } : null;
            jcMediaScannerConnection.CallStatic( "scanFile", joContext, new string[] { path }, mimeTypes, null );
        }
        Handheld.StopActivityIndicator();
#endif
    }
}

参考

17
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
8