Unity Andorid IOS截屏保存到手机相册

Andorid IOS 双平台截屏保存到手机相册

因公司需求,需在IOS和Andorid平台下实现截图保存到手机相册,所以在闲暇之余就有了这篇博文。

不管是IOS 还是Andorid 原理都很简单:

1.Unity 提供截图功能
2.IOS和Android负责刷新到相册

其实相交来说IOS比Andorid还要简单,所以我们先介绍难的,要知 难 而上嘛是吧!嘿嘿嘿~

1.Andorid 层代码 :
一个获取动态权限的方法,一个提供刷新的接口。
动态权限一定要有,不然APK在 Andorid10 的手机上会因为没有权限而报错,哪怕你在AndroidManifest 文件中配置了权限,他依然会任性的给你报个错。

首先是动态获取写入权限的接口,在 onCreate 方法中初始化即可
权限:WRITE_EXTERNAL_STORAGE

    @Override
    protected void onCreate(Bundle bundle) {
        super.onCreate(bundle);
        mMainActivity=this;
        InitPermission();
    }
    //初始化用户权限  在游戏一登录的时候进行调用
    public  void InitPermission()
    {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            int checkPermission = checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE);
            if (checkPermission != PackageManager.PERMISSION_GRANTED) {
                requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1); //后面的1为请求码
                Log.e("MainActivity", "未授权,去授权");
                return ;
            } else {
                Log.e("MainActivity", "已授权...");
            }
        }
    }


    //这里是权限获取权限的回调
    @Override
    public void onRequestPermissionsResult(int permsRequestCode, String[] permissions, int[] grantResults){
        switch(permsRequestCode){
            case 1:
                if (grantResults.length>0){  //判断权限
                    boolean albumAccepted = grantResults[0]==PackageManager.PERMISSION_GRANTED;
                    if(!albumAccepted){      //没有权限,继续申请,用户拒绝了页申请
                        String[] perms = {"android.permission.CAMERA"};
                    }else {
                    }
                }
                break;
        }
    }

下面是刷新相册的接口:

   //刷新相册
    public static void RefreshAlbum(String filePath , String str)
    {
        Log.i("RefreshAlbum", "------------filePath" + filePath);//打印保存文件路径日志
        if(str == null)
            str = "已保存到相册";//设置保存成功的提示内容.
        Toast.makeText(mMainActivity, str, Toast.LENGTH_SHORT).show();
        Log.i("Unity", "------------filePath" + filePath);//打印保存文件路径日志
        Intent scanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
        scanIntent.setData(Uri.fromFile(new File(filePath)));
        mMainActivity.sendBroadcast(scanIntent);
    }

下面是AndroidManifest 需要添加的权限:

<activity 
 	<meta-data android:name="unityplayer.SkipPermissionsDialog" android:value="true" />
</activity>


<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

Unity 打包设置开启SD卡写入
在这里插入图片描述

Android 的配置到此结束,可配合文章结尾的截图脚本进行打包测试!

IOS截图保存相册介绍

跟着下面的步骤一步一步来,很简单
在这里插入图片描述
选择头文件Header File,命名为PhotoManager,添加代码如下:

#import <Foundation/Foundation.h>
 
@interface PhotoManager : NSObject
- ( void ) imageSaved: ( UIImage *) image didFinishSavingWithError:( NSError *)error
          contextInfo: ( void *) contextInfo;
@end

再新建文件,选择执行文件Objective-C File,同命名为PhotoManager,添加代码如下:

#import "PhotoManager.h"
@implementation PhotoManager
- ( void ) imageSaved: ( UIImage *) image didFinishSavingWithError:( NSError *)error
          contextInfo: ( void *) contextInfo
{
    NSLog(@"保存结束");
    if (error != nil) {
        NSLog(@"有错误");
    }
}
void _SavePhoto(char *readAddr)
{
    NSString *strReadAddr = [NSString stringWithUTF8String:readAddr];
    UIImage *img = [UIImage imageWithContentsOfFile:strReadAddr];
    NSLog([NSString stringWithFormat:@"w:%f, h:%f", img.size.width, img.size.height]);
    PhotoManager *instance = [PhotoManager alloc];
    UIImageWriteToSavedPhotosAlbum(img, instance,
                                   @selector(imageSaved:didFinishSavingWithError:contextInfo:), nil);
}
@end

然后在Info界面,Custom iOS Target Properties下点击 + 号添加相机权限,如下图所示:

在这里插入图片描述
选择 Privacy-Camera Usage Description(使用相机权限),并在后面添加提示:使用相机(可任意)。
再点击 + 号添加相册权限,选择Privacy-Photo Library Additions Usage Description(相册添加权限),并在后面添加提示:使用相册(可任意)。

IOS到这的配置就算结束了,就这么简单,当然这只是配置在XCode上,如果你打包时担心被覆盖掉,可以把PhotoManager.h 和PhotoManager.m文件移动到Unity项目工程中,并且在代码中添加相机权限,
如下:

在这里插入图片描述
在打包设置代码中添加权限逻辑:

        plist.root.SetString("Privacy-Camera Usage Description", "需要使用相机"); // 使用相机的权限 Privacy-Camera Usage Description
        plist.root.SetString("Privacy-Photo Library Additions Usage Description", "需要使用相机"); // 使用定位的权限 Privacy-Photo Library Additions Usage Description

到此IOS的配置算是彻底结束,

当然要感谢
https://blog.csdn.net/xytmhxy/article/details/81297234?utm_source=copy
这位博主的IOS配置信息。

下面附上Unity中截图脚本及调用Android和IOS保存相册的接口
截图脚本:

	//Unity截图脚本
    public class CameraShoot : MonoBehaviour
    {
		//截图屏幕图片进行保存
        public static string CameraShootAndSave()
        {

            Camera camera = GameObject.Find("SceneUIRoot/UiCamera").GetComponent<Camera>();
            string path = Application.persistentDataPath + "/" + DateTime.Now.ToString("yyyyMMddHHmmssffff") + ".png";
            Fun(camera, path);
            Debug.LogError("截图成功,存放路径:" + Path.GetFullPath(path));
            return Path.GetFullPath(path);
        }
        public static void Fun(Camera m_Camera, string filename)
        {
            RenderTexture rt = new RenderTexture(Screen.width, Screen.height, 16);
            m_Camera.targetTexture = rt;
            m_Camera.Render();

            RenderTexture.active = rt;
            Texture2D t = new Texture2D(Screen.width, Screen.height);
            t.ReadPixels(new Rect(0, 0, t.width, t.height), 0, 0);
            t.Apply();

            System.IO.File.WriteAllBytes(filename, t.EncodeToPNG());

            m_Camera.targetTexture = null;
            m_Camera.Render();
        }
   }

下面是调用刷新相册的脚本,Unity如何调用Android的方法可自行百度
就是把图片的保存路径传给Andorid或IOS进行刷新

 //调用IOS Andorid层 刷新相册方法脚本
  public class CaptureAndSaveScreen : MonoBehaviour
    {
        [DllImport("__Internal")]
        public static extern void _SavePhoto(string readAddr);
		//截图回调
        public static Action<bool> CallBack;
        public static void CaptureFullScrenAndSave()
        {
            //IOS调用
#if UNITY_IOS
                CaptureFullScrenAndSaveIOS();
#elif UNITY_ANDROID || UNITY_EDITOR 
            //Android 调用,这里可以忽略,根据自己的项目调Android的RefreshAlbum储存接口即可
            snapShot.CaptureAndSaveToAlbum(ImageType.JPG);
#endif
        }
        public static void CaptureFullScrenAndSaveIOS()
        {
            string savePath = CameraShoot.CameraShootAndSave();
            _SavePhoto(savePath);
            CallBack?.Invoke(true);
        }
  }

到了这里配置就已经结束了,可以打包测试了,博主已经在使用中了,是没有任何问题的。
安卓和IOS可以独立摘出来一个一个来,Andorid的通了在去搞IOS的,或者相反。

此文章到此结束!

努力积才能,壹叶便成名!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

铸梦xy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值