# 圖片存入相簿功能
> RN 提供了 CameraRoll 的功能。
- [Ref](https://www.twblogs.net/a/5c87b8f3bd9eee35cd6a4885)
---
## 照片獲取與保存
將採用 CameraRoll 訪問本地相冊的功能,它包含兩個方法: `CameraRoll.getPhotos(params);` 與 `CameraRoll.saveToCameraRoll(tag, [type]);` 。
### 權限
要保存內容,或取用手機資料,皆需要跟手機請求權限。
- [Ref](https://blog.csdn.net/zeping891103/article/details/88413708)
#### Android
官方提供 PermissionsAndroid 来獲取權限,以獲取 WRITE 權限。
``` js
UNSAFE_componentWillMount() {
this.requestReadPermission();
}
async requestReadPermission() {
try {
const os = Platform.OS; // android or ios
if(os === 'android'){
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE,
{
//第一次请求【拒绝】后提示用户你为什么要这个权限
'title': '我要读写权限',
'message': '没权限我不能工作,同意就好了'
}
);
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
console.log('你已获取了读写权限');
// 继续运行其它代码
} else {
console.log('获取读写权限失败');
}
}else{
console.log('你已获取了读写权限');
// 继续运行其它代码
}
} catch (err) {
console.log(err.toString());
}
}
```
用户首次啟動 app 時將會收到讀寫權限請求的通知。
除此之外,最好還要 android/app/src/main/AndroidManifest.xml配置上
```
// 需要什麼權限就配置什麼權限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
```
#### iOS
使用 RCTCameraRoll Library(也有部分權限只需配置 Info.plist 即可,視官方 RN 支持程度而定)。
1. node_module/react-native/Libraries/CameraRoll
2. 把 RCTCameraRoll.xcodeproj 添加到在 Liberaries 資料夾下
3. Build Phases -> Link Binary With Libraries 裡添加 libRCTCameraRoll.a
4. 在 Info.plist 配置請求照片的描述(Privacy - Photo Library Usage Description)
```
CameraRoll.getPhotos(...) // 获取相册照片或视频
CameraRoll.saveToCameraRoll(...) // 保存照片或视频
```
### Demo
``` js
import React from 'react';
import { View, Text, Button, Image, Platform, CameraRoll, PermissionsAndroid, Alert } from 'react-native';
class CameraRollAPI extends React.Component {
state = {
images: [], // 存放照片數據
cursorEnd: '', // 上一次相冊中獲取照片的結束標記
hasNextPage: true // 是否還有下一張照片
}
UNSAFE_componentWillMount() {
this.requestReadPermission();
}
getPhotos(){
if(this.state.hasNextPage){
let queryNativePictuire = {
first: 1,
assetType: 'Photos' // All全部|Videos錄像|Photos照片(默認)
};
if (this.state.cursorEnd) {
queryNativePictuire.after = this.state.cursorEnd;
}
CameraRoll.getPhotos(queryNativePictuire).then((result) => {
let pageInfo = result.page_info;
this.setState({ images: result.edges, cursorEnd: pageInfo.end_cursor, hasNextPage: pageInfo.has_next_page });
}).catch((error) => {
console.log(error);
});
}else{
Alert.alert('提示','已經沒有下一張照片');
}
}
async requestReadPermission() {
try {
const os = Platform.OS; // android or ios
if(os === 'android'){
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE,
{
//第一次請求【拒絕】後提示用戶你爲什麼要這個權限
'title': '我要讀寫權限',
'message': '沒權限我不能工作,同意就好了'
}
);
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
// 已獲取了讀寫權限
this.getPhotos();
} else {
// 獲取讀寫權限失敗
}
}else{
this.getPhotos();
}
} catch (err) {
console.log(err.toString());
}
}
_getNextPhoto = () => {
this.getPhotos();
}
_saveImg = () => {
const img = 'http://www.helloui.net/assets/watch.jpg'; // 網絡圖片在android中會報錯
var promise = CameraRoll.saveToCameraRoll(img); // 在 Android 上,img是一個本地 URI,例如"file:///sdcard/img.png"。在 iOS, img可以是任意圖片 URI
promise.then(function(result) {
alert('保存成功!地址如下:\n' + result);
}).catch(function(error) {
alert('保存失敗!\n' + error);
});
}
_renderImg = () => {
const side = 200 ;
if(this.state.images.length > 0){
const image = this.state.images[0].node.image;
return(
<View>
<Image
source={{ uri: image.uri }}
style={{width:side, height:side}}
/>
</View>
);
}else{
return null;
}
}
render(){
return(
<View>
<Text>照片:</Text>
{this._renderImg()}
<Button
title='更換一張照片'
onPress={this._getNextPhoto}
/>
<Button
title='保存一張網絡圖片'
onPress={this._saveImg}
/>
</View>
);
}
}
export default CameraRollAPI;
```