Hai, setelah kemarin kita belajar penggunaan API untuk login, kali ini kita akan mencoba upload image Flutter dengan API, untuk tahap-tahapnya adalah seperti berikut
1. Konfigurasi Server
kita menggunakan file bernama upload.php :
<?php
header('Content-Type: application/json; charset=utf-8');
header('Access-Control-Allow-Origin: *');
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['image'])) {
$targetDirectory = "uploads/";
$targetFile = $targetDirectory . basename($_FILES['image']['name']);
$uploadOk = 1;
$imageFileType = strtolower(pathinfo($targetFile, PATHINFO_EXTENSION));
// Check if image file is a actual image or fake image
$check = getimagesize($_FILES['image']['tmp_name']);
if ($check !== false) {
// File is an image
$uploadOk = 1;
} else {
// File is not an image
$response = array('success' => false, 'message' => 'File is not an image.');
echo json_encode($response);
$uploadOk = 0;
}
// Check if file already exists
if (file_exists($targetFile)) {
// File already exists
$response = array('success' => false, 'message' => 'File already exists.');
echo json_encode($response);
$uploadOk = 0;
}
// Check file size
if ($_FILES['image']['size'] > 500000) {
// File is too large
$response = array('success' => false, 'message' => 'File is too large.');
echo json_encode($response);
$uploadOk = 0;
}
// Allow certain file formats
if ($imageFileType != "jpg" && $imageFileType != "png" && $imageFileType != "jpeg"
&& $imageFileType != "gif") {
// Invalid file format
$response = array('success' => false, 'message' => 'Invalid file format.');
echo json_encode($response);
$uploadOk = 0;
}
// Check if $uploadOk is set to 0 by an error
if ($uploadOk == 0) {
// File upload failed
$response = array('success' => false, 'message' => 'File upload failed.');
echo json_encode($response);
} else {
// Upload file
if (move_uploaded_file($_FILES['image']['tmp_name'], $targetFile)) {
// File uploaded successfully
$response = array('success' => true, 'message' => 'File uploaded successfully.', 'file_path' => $targetFile);
echo json_encode($response);
} else {
// File upload failed
$response = array('success' => false, 'message' => 'File upload failed.');
echo json_encode($response);
}
}
} else {
// Invalid request method or no file uploaded
$response = array('success' => false, 'message' => 'Invalid request method or no file uploaded.');
echo json_encode($response);
}
?>
setelah itu buat folder bernama "uploads" sejajar dengan file upload.php,
pada sebagian kasus di ubuntu, jangan lupa jadikan chmod 777, dan chown www-data.
setelah itu kita coba menggunakan di postman seperti berikut :
jika file tersebut berhasil terupload seharusnya muncul di folder uploads :
Yey, sudah berhasil.
2. Konfigurasi di flutter
2.A, Pertama kita lakukan konfigurasi pada file pubspec.yaml, library yang kita tambahkan adalah seperti berikut :
dependencies:
flutter:
sdk: flutter
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.6
http: ^1.2.1
path_provider: ^2.1.2
lalu pada class upload.dart :
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:path_provider/path_provider.dart';
class Upload extends StatefulWidget {
@override
_Upload createState() => _Upload();
}
class _Upload extends State<Upload> {
File? _image;
// Method untuk memilih gambar dari galeri
Future<void> _chooseImage() async {
// kode untuk memilih gambar dari galeri
print("_chooseImage");
}
// Method untuk mengupload gambar
Future<void> _uploadImage() async {
print("_uploadImage");
String imagePath = '/storage/0000-0000/20220501/DCIM/Camera/20220531_104558.png';
_image = File(imagePath);
if (_image == null) {
// Tampilkan pesan jika gambar belum dipilih )
print("Image masih koosong");
return;
}
// URL endpoint untuk upload gambar
var url = Uri.parse('http://192.168.43.227/contohAPI/upload.php');
// Membuat request
var request = http.MultipartRequest('POST', url);
// Menambahkan gambar ke body form-data
request.files.add(await http.MultipartFile.fromPath('image', _image!.path));
// Mengirim request
var response = await request.send();
// Mengecek status response
if (response.statusCode == 200) {
// Upload berhasil
print('Upload berhasil');
} else {
// Upload gagal
print('Upload gagal');
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Upload File'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
_image == null ? Text('Pilih gambar') : Image.file(_image!),
SizedBox(height: 20),
ElevatedButton(
onPressed: _chooseImage,
child: Text('Pilih Gambar'),
),
ElevatedButton(
onPressed: _uploadImage,
child: Text('Upload Gambar'),
),
],
),
),
);
}
}
pasti bingung dari mana saya mendapatkan /storage/0000-0000/20220501/DCIM/Camera/20220531_104558.png
saya mendapatkan dari bantuan Android Studio , Device manager (lalukan copy path)
Jangan lupa Permision di AndroidManifest.xml file ini terletak di
android/app/src/main/AndroidManifest.xml
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Untuk code lengkapnya seperti berikut :
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:label="login"
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher">
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues
to determine the Window background behind the Flutter UI. -->
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme"
/>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data
android:name="flutterEmbedding"
android:value="2" />
</application>
<!-- Required to query activities that can process text, see:
https://developer.android.com/training/package-visibility?hl=en and
https://developer.android.com/reference/android/content/Intent#ACTION_PROCESS_TEXT.
In particular, this is used by the Flutter engine in io.flutter.plugin.text.ProcessTextPlugin. -->
<queries>
<intent>
<action android:name="android.intent.action.PROCESS_TEXT"/>
<data android:mimeType="text/plain"/>
</intent>
</queries>
</manifest>
Jangan lupa izinkan applikasi di andoridnya,
Sekarang kita jalankan aplikasinya dan tekan "upload gambar"
Tunggu beberapa saat, seharusnya di terminal muncul indikator, atau cek di folder uploads tadi
Sudah berhasil.
Part 3. Menggunakan Image Picker
jika pada part 2 kita mengupload file langsung dari lokasi file
//String imagePath = '/storage/0000-0000/20220501/DCIM/Camera/20220531_104558.png';
Kali ini kita akan menggunakan File manager agar user bisa memilih secara manual, user juga bisa memilih menggunakan camera secara langsung
1. Berikan izin pada AndroidManifest.xml
<uses-permission android:name="android.permission.CAMERA" />
2. Pada file pubscpec.yaml tambahkan library image_picker
Untuk file upload.dart kita melakukan sedikit perubahan, seperti berikut :
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:path_provider/path_provider.dart';
import 'package:image_picker/image_picker.dart';
class Upload extends StatefulWidget {
@override
_Upload createState() => _Upload();
}
class _Upload extends State<Upload> {
File? _image;
// Method untuk memilih gambar dari galeri
Future<void> _chooseImage() async {
// kode untuk memilih gambar dari galeri
print("_chooseImage");
final picker = ImagePicker();
// final pickedImage = await picker.getImage(source: ImageSource.gallery); // Untuk membuka galeri
// final pickedImage = await picker.getImage(source: ImageSource.camera); // Untuk mengambil gambar menggunakan kamera
//
//final pickedImage = await picker.pickImage(source: ImageSource.gallery);
final pickedImage = await picker.pickImage(source: ImageSource.camera);
if (pickedImage != null) {
// Lakukan sesuatu dengan gambar yang dipilih
setState(() {
// Misalnya, menampilkan gambar yang dipilih di UI
_image = File(pickedImage.path);
});
} else {
// Pengguna membatalkan pemilihan gambar
}
}
// Method untuk mengupload gambar
Future<void> _uploadImage() async {
print("_uploadImage");
//String imagePath = '/storage/0000-0000/20220501/DCIM/Camera/20220531_104558.png';
//_image = File(imagePath);
if (_image == null) {
// Tampilkan pesan jika gambar belum dipilih )
print("Image masih koosong");
return;
}
// URL endpoint untuk upload gambar
var url = Uri.parse('http://192.168.43.227/contohAPI/upload.php');
// Membuat request
var request = http.MultipartRequest('POST', url);
// Menambahkan gambar ke body form-data
request.files.add(await http.MultipartFile.fromPath('image', _image!.path));
// Mengirim request
var response = await request.send();
// Mengecek status response
if (response.statusCode == 200) {
// Upload berhasil
print('Upload berhasil');
} else {
// Upload gagal
print('Upload gagal');
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Upload File'),
),
body: Center(
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
_image == null ? Text('Pilih gambar') : Image.file(_image!),
SizedBox(height: 5),
ElevatedButton(
onPressed: _chooseImage,
child: Text('Pilih Gambar'),
),
ElevatedButton(
onPressed: _uploadImage,
child: Text('Upload Gambar'),
),
],
),
),
),
);
}
}
Setelah itu coba jalankan, bila gagal error coba cek upload.php dan gantilah ukuran maksimal gambar
// if ($_FILES['image']['size'] > 500000) {
if ($_FILES['image']['size'] > 9900000) {
setelah itu coba lagi, maka seharusnya sudah berhasil