Unity3D截屏录屏后存储IOS安卓系统相册

此方法采用U3D和ios和安卓交互方法完成 具体内容是U3D写出调用IOS和安卓方法 传递录像和照片的沙盒路径 存储由安卓和ios来完成 好了我们先上U3D代码

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;

public class SelectPlatform : MonoBehaviour {

	#if UNITY_ANDROID
	/// 
	/// Android平台接口
	/// 
	public static AndroidInterface android=new AndroidInterface();

	#elif UNITY_IPHONE

	/// 
	/// IOS平台接口
	/// 
	public static IOSInterface ios=new IOSInterface();

	#endif

	/// 
	/// 对Android或IOS接口进行调用
	/// 
	public static void SendMessage(string funName,string data)
	{
		#if UNITY_ANDROID
		Type type = typeof(AndroidInterface);
		type.GetMethod(funName).Invoke(android,new object[]{data});
		#elif UNITY_IPHONE
		Type type = typeof(IOSInterface);
		type.GetMethod(funName).Invoke(ios,new object[]{data});
		#endif
	}
}
#if UNITY_ANDROID
using UnityEngine;
using System.Collections;
/// 
/// 安卓方法列表
/// 
public class AndroidInterface : AbstractClass {
    /// 
    /// 关闭U3D
    /// 
    /// 
    public override void CloseUnity(string data)
    {
        Debug.Log("CloseUnity");
        MyAndroidPlayer.SendMessage("CloseUnity", data);
    }
    /// 
    /// 保存照片
    /// 
    /// 
    public override void PreservationSPhoto(string data)
    {
        Debug.Log("PreservationSPhoto");
        MyAndroidPlayer.SendMessage("PreservationSPhoto", data);
    }
    /// 
    /// 保存录像
    /// 
    /// 
    public override void PreservationSvideotape(string data)
    {
        Debug.Log("PreservationSvideotape");
        MyAndroidPlayer.SendMessage("PreservationSvideotape", data);
    }
}
#endif
using UnityEngine;
using System.Collections;
/// 
/// 方法列表
/// 
public  abstract class AbstractClass  {
    /// 
    /// 关闭U3D
    /// 
    /// 
    public abstract void CloseUnity(string data);
    /// 
    /// 保存照片
    /// 
    /// 
    public abstract void PreservationSPhoto(string data);
    /// 
    /// 保存录像
    /// 
    /// 
    public abstract void PreservationSvideotape(string data);
}
using UnityEngine;
using System.Collections;
#if UNITY_ANDROID
public class MyAndroidPlayer : MonoBehaviour {
	public delegate void ObtainMessageDelegate(string messageType, string message);
	public static ObtainMessageDelegate ObtainMessage;

	private static AndroidJavaClass androidJavaClass;

	private static AndroidJavaObject androidJavaObject;

	private char SEPARATOR = '~';

	void Awake()
	{
		
		if (Application.platform != RuntimePlatform.Android) return;
		androidJavaClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
		androidJavaObject = androidJavaClass.GetStatic<AndroidJavaObject>("currentActivity");
	//	androidJavaObject = androidJavaObject.Get("functionUnity");

	}

	public static void SendMessage(string method, string msgArgs)
	{
		Debug.Log(method);
		androidJavaObject.Call(method, new string[] { msgArgs });
	}
}

#endif
using UnityEngine;
using System.Collections;
using System.Runtime.InteropServices;
using System;

public class IOSInterface : AbstractClass {
    [DllImport("__Internal")]
    private static extern void _CloseUnity(string wenwen);
    public override void CloseUnity(string wenwen)
    {
        _CloseUnity(wenwen);
    }
    [DllImport("__Internal")]
    private static extern void _PreservationSPhoto(string wenwen);
    public override void PreservationSPhoto(string wenwen)
    {
        _PreservationSPhoto(wenwen);
    }
    [DllImport("__Internal")]
    private static extern void _PreservationSvideotape(string wenwen);
    public override void PreservationSvideotape(string wenwen)
    {
        _PreservationSvideotape(wenwen);
    }
}

以上是我对调用ios 安卓方法做的一个小模块处理 然后我们在以后的项目里就很好的调用了 例如

 public void  CloseUnity()
    {
        SelectPlatform.SendMessage("CloseUnity", "退出U3D");
    }
    public void PreservationSPhoto(string data)
    {
        SelectPlatform.SendMessage("PreservationSPhoto",data);
    }
    public void PreservationSvideotape(string data)
    {
        SelectPlatform.SendMessage("PreservationSvideotape",data);
    }

然后方法的参数 就是我们做完截屏和录屏的路径 截屏代码我就不提供了 百度一堆 录屏各种插件或者自己写 最后传递参数 例如 Debug.Log(“录像存储地址” + Application.persistentDataPath + “/” + filePath);
注意路径 Application.persistentDataPath

写好方法后 我们先来安卓 导出AS项目 这里说明一些 如果公司有安卓 ios程序最好 和他们沟通好接口
如果没有 就需要自己来写了 下面贴代码 找到 java里 UnityPlayerActivity

package com.itemjia.app.bandian;

import com.unity3d.player.*;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.PixelFormat;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;

public class UnityPlayerActivity extends Activity
{
    private Context mContext;
    protected UnityPlayer mUnityPlayer; // don't change the name of this variable; referenced from native code
    public  void CloseUnity(String data){
        finish();
    }
    public  void PreservationSvideotape(String  msg){
        File file1=new File(msg);
//获取ContentResolve对象,来操作插入视频
        ContentResolver localContentResolver = this.getContentResolver();
//ContentValues:用于储存一些基本类型的键值对
        ContentValues localContentValues = getVideoContentValues(this, file1, System.currentTimeMillis());
//insert语句负责插入一条新的纪录,如果插入成功则会返回这条记录的id,如果插入失败会返回-1。
        Uri localUri = localContentResolver.insert(MediaStore.Video.Media.EXTERNAL_CONTENT_URI,localContentValues);
        //  Log.d(msg, "PreservationSPhoto: .");
    }
    public  ContentValues getVideoContentValues(Context paramContext, File paramFile, long paramLong) {
        ContentValues localContentValues = new ContentValues();
        localContentValues.put("title", paramFile.getName());
        localContentValues.put("_display_name", paramFile.getName());
        localContentValues.put("mime_type", "video/3gp");
        localContentValues.put("datetaken", Long.valueOf(paramLong));
        localContentValues.put("date_modified", Long.valueOf(paramLong));
        localContentValues.put("date_added", Long.valueOf(paramLong));
        localContentValues.put("_data", paramFile.getAbsolutePath());
        localContentValues.put("_size", Long.valueOf(paramFile.length()));
        return localContentValues;
    }
    public   void PreservationSPhoto(String  msg){
        saveImage(msg);
        DeleteImage(msg);
    }
    //保存图片到相册
    private void saveImage(String path) {
        FileInputStream input = null;
        try {
            input = new FileInputStream(new File(path));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

        Bitmap bitmap = BitmapFactory.decodeStream(input);
        String fileName = System.currentTimeMillis() + ".png";
        ImgUtils.saveBitmap(bitmap, fileName, mContext);

    }
    private void DeleteImage(String imgPath) {
        ContentResolver resolver = getContentResolver();
        Cursor cursor = MediaStore.Images.Media.query(resolver, MediaStore.Images.Media.EXTERNAL_CONTENT_URI, new String[]{MediaStore.Images.Media._ID}, MediaStore.Images.Media.DATA + "=?",
                new String[]{imgPath}, null);
        boolean result = false;
        if (cursor.moveToFirst()) {
            long id = cursor.getLong(0);
            Uri contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
            Uri uri = ContentUris.withAppendedId(contentUri, id);
            int count = getContentResolver().delete(uri, null, null);
            result = count == 1;
        } else {
            File file = new File(imgPath);
            result = file.delete();
        }

    }
    // Setup activity layout
    @Override protected void onCreate(Bundle savedInstanceState)
    {
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        super.onCreate(savedInstanceState);
        mContext = this;
        mUnityPlayer = new UnityPlayer(this);
        setContentView(mUnityPlayer);
        mUnityPlayer.requestFocus();
    }

    @Override protected void onNewIntent(Intent intent)
    {
        // To support deep linking, we need to make sure that the client can get access to
        // the last sent intent. The clients access this through a JNI api that allows them
        // to get the intent set on launch. To update that after launch we have to manually
        // replace the intent with the one caught here.
        setIntent(intent);
    }

    // Quit Unity
    @Override protected void onDestroy ()
    {
        mUnityPlayer.destroy();
        super.onDestroy();
    }

    // Pause Unity
    @Override protected void onPause()
    {
        super.onPause();
        mUnityPlayer.pause();
    }

    // Resume Unity
    @Override protected void onResume()
    {
        super.onResume();
        mUnityPlayer.resume();
    }

    @Override protected void onStart()
    {
        super.onStart();
        mUnityPlayer.start();
    }

    @Override protected void onStop()
    {
        super.onStop();
        mUnityPlayer.stop();
    }

    // Low Memory Unity
    @Override public void onLowMemory()
    {
        super.onLowMemory();
        mUnityPlayer.lowMemory();
    }

    // Trim Memory Unity
    @Override public void onTrimMemory(int level)
    {
        super.onTrimMemory(level);
        if (level == TRIM_MEMORY_RUNNING_CRITICAL)
        {
            mUnityPlayer.lowMemory();
        }
    }

    // This ensures the layout will be correct.
    @Override public void onConfigurationChanged(Configuration newConfig)
    {
        super.onConfigurationChanged(newConfig);
        mUnityPlayer.configurationChanged(newConfig);
    }

    // Notify Unity of the focus change.
    @Override public void onWindowFocusChanged(boolean hasFocus)
    {
        super.onWindowFocusChanged(hasFocus);
        mUnityPlayer.windowFocusChanged(hasFocus);
    }

    // For some reason the multiple keyevent type is not supported by the ndk.
    // Force event injection by overriding dispatchKeyEvent().
    @Override public boolean dispatchKeyEvent(KeyEvent event)
    {
        if (event.getAction() == KeyEvent.ACTION_MULTIPLE)
            return mUnityPlayer.injectEvent(event);
        return super.dispatchKeyEvent(event);
    }

    // Pass any events not handled by (unfocused) views straight to UnityPlayer
    @Override public boolean onKeyUp(int keyCode, KeyEvent event)     { return mUnityPlayer.injectEvent(event); }
    @Override public boolean onKeyDown(int keyCode, KeyEvent event)   { return mUnityPlayer.injectEvent(event); }
    @Override public boolean onTouchEvent(MotionEvent event)          { return mUnityPlayer.injectEvent(event); }
    /*API12*/ public boolean onGenericMotionEvent(MotionEvent event)  { return mUnityPlayer.injectEvent(event); }
}

新建一个 .java代码 ImgUtils

package com.itemjia.app.bandian;

import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.media.MediaScannerConnection;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.MediaStore;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class ImgUtils {
    /*
     * 保存文件,文件名为当前日期
     */
    public static void saveBitmap(Bitmap bitmap, String bitName,Context context) {
        String fileName;
        File file;
        if (Build.BRAND.equals("xiaomi")) { // 小米手机
            fileName = Environment.getExternalStorageDirectory().getPath() + "/DCIM/Camera/" + bitName;
        }else if (Build.BRAND.equals("Huawei")){
            fileName = Environment.getExternalStorageDirectory().getPath() + "/DCIM/Camera/" + bitName;
        } else {  // Meizu 、Oppo
            fileName = Environment.getExternalStorageDirectory().getPath() + "/DCIM/" + bitName;
        }
        file = new File(fileName);

        if (file.exists()) {
            file.delete();
        }
        FileOutputStream out;
        try {
            out = new FileOutputStream(file);
            // 格式为 JPEG,照相机拍出的图片为JPEG格式的,PNG格式的不能显示在相册中
            if (bitmap.compress(Bitmap.CompressFormat.JPEG, 90, out)) {
                out.flush();
                out.close();
// 插入图库
                MediaStore.Images.Media.insertImage(context.getContentResolver(), file.getAbsolutePath(), bitName, null);

            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();

        }
        // 发送广播,通知刷新图库的显示
        context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://" + fileName)));
    }

}

安卓代码完成 下面来做IOS 如果你写了接口 就必须实现 不然会报错 新创建一个.h文件 就叫 u3dmanage.h吧

//
//  u3dmanage.h
//  Unity-iPhone
//
//  Created by Gy on 2020/4/26.
//
@interface u3dmanage : NSObject
void _CloseUnity(char*msg);
void _PreservationSPhoto(char*msg);
void _PreservationSvideotape(char*msg);
@end
#ifndef u3dmanage_h
#define u3dmanage_h

#endif /* u3dmanage_h */

这个是接口 在写实现代码
创建一个 .m文件 u3dmanage.m

//
//  u3dmanage.m
//  Unity-iPhone
//
//  Created by Gy on 2020/4/27.
//

#import "u3dmanage.h"
@interface u3dmanage ();
@end
@implementation u3dmanage

void _CloseUnity(char* msg){
    
   NSString *string1 = [[NSString alloc] initWithUTF8String:msg];
    NSString *string2 = [[NSString alloc] initWithUTF8String:msg];
    
    NSLog(@"###%@", [NSString stringWithFormat:@"%@ %@", string1, string2]);
    
}
void _PreservationSPhoto(char* msg){
    
    NSString *string1 = [[NSString alloc] initWithUTF8String:msg];
      NSString *string2 = [[NSString alloc] initWithUTF8String:msg];
    
    NSString *strReadAddr = [NSString stringWithUTF8String:msg];
      UIImage *img = [UIImage imageWithContentsOfFile:strReadAddr];
      NSLog([NSString stringWithFormat:@"w:%f, h:%f", img.size.width,img.size.height]);
      u3dmanage *instance = [u3dmanage alloc];
      UIImageWriteToSavedPhotosAlbum(img, instance,
          @selector(imageSaved:didFinishSavingWithError:contextInfo:), nil);
      NSLog(@"###%@", [NSString stringWithFormat:@"%@ %@", string1, string2]);
    
}
void _PreservationSvideotape(char* msg){
NSString *strReadAddr = [NSString stringWithUTF8String:msg];
      u3dmanage *instance = [u3dmanage alloc];
      UISaveVideoAtPathToSavedPhotosAlbum(strReadAddr, instance, nil, nil);

}
+ (void) savedVedioImage:(UIImage*)image didFinishSavingWithError: (NSError *)error contextInfo: (void *)contextInfo {
    NSString* result;
    if (error) {
        result =@"视频保存失败";
    }
    else {
        result =@"保存视频成功";
    }
  //  UnitySendMessage( "MainScriptHolder", "SaveVedioToPhotosAlbumCallBack", result.UTF8String);
}
- ( void ) imageSaved: ( UIImage *) image didFinishSavingWithError:( NSError *)error
    contextInfo: ( void *) contextInfo
{
    NSLog(@"保存结束");
    if (error != nil) {
        NSLog(@"有错误");
    }
}

@end

最后测试 录像和截屏完美存储系统相册

你可能感兴趣的:(Unity3D截屏录屏后存储IOS安卓系统相册)