# Software Studio Bonus Lab
***請謹慎服用,以免遇到靈異事件***
## 解決版本問題
1. 請將 Android Studio 更新到 2024 年的版本,Flutter 更新成 3.22.2。
2. 右鍵點選 ```android``` 資料夾,用 Android Studio 開啟。
3. 左上角選單 -> File -> Project Structure -> Gradle Version 請選 8.8。
4. 左上角選單 -> Tools -> AGP Upgrade Assistant -> 更新到 8.5.0。
5. 打開 ```android/build.gradle```,把 ```allprojects``` 那個 block 換成下面的 code:
```gradle=
allprojects {
ext.kotlin_version = '2.0.0'
repositories {
google()
mavenCentral()
}
}
```
6. 打開 ```android/app/build.gradle```,在 ```android``` 那個 block 貼上下面的 code:
```gradle=
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
kotlinOptions {
jvmTarget = '17'
}
}
```
7. 打開 ```android/settings.gradle```,把 ```plugins``` 那個 block 換成下面的 code:
```gradle=
plugins {
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
id "com.android.application" version '8.4.2' apply false
id "org.jetbrains.kotlin.android" version "2.0.0" apply false
}
```
8. 左上角選單 -> File -> Sync Project with Gradle Files。
## 相機
1. 在 ```AndroidManifest.xml``` 裡的 ```<manifest>``` 貼上以下的 code:
```xml=
<uses-feature
android:name="android.hardware.camera"
android:required="false"/>
<uses-permission
android:name="android.permission.CAMERA" />
```
2. 打開 ```android/app/build.gradle```,貼上下面的 code:
```gradle=
dependencies {
def camerax_version = "1.3.4"
implementation "androidx.camera:camera-core:${camerax_version}"
implementation "androidx.camera:camera-camera2:${camerax_version}"
implementation "androidx.camera:camera-lifecycle:${camerax_version}"
implementation "androidx.camera:camera-view:${camerax_version}"
}
```
3. 在 ```AndroidManifest.xml``` 裡的 ```<application>``` 貼上以下的 code:
```xml=
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
```
4. 打開 ```android/app/src/main/res/xml/file_paths.xml``` (沒有的話請自行建立),貼上以下的 code:
```xml=
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-files-path
name="my_images"
path="Pictures" />
</paths>
```
5. 打開 Chat GPT,問他 ```MainActivity.kt``` 要怎麼寫。注意要有要求相機存取權的步驟,有時候他會忘記提供,請再提醒他一下。```result.success()``` 這個函式參數釋放要回傳給 Flutter 的東西,可以用他來回傳 file path。
6. 以下是調整圖片的函式,請謹慎服用。
```kotlin=
private fun resizeImage(photoPath: String, maxWidth: Int, maxHeight: Int): String {
val options = BitmapFactory.Options()
options.inJustDecodeBounds = true
BitmapFactory.decodeFile(photoPath, options)
// 計算圖像縮放比
val photoW = options.outWidth
val photoH = options.outHeight
val scaleFactor = Math.min(photoW / maxWidth, photoH / maxHeight)
options.inJustDecodeBounds = false
options.inSampleSize = scaleFactor
var resizedBitmap = BitmapFactory.decodeFile(photoPath, options)
// 讀取 EXIF 信息來獲取旋轉角度
val exif = ExifInterface(photoPath)
val orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED)
resizedBitmap = when (orientation) {
ExifInterface.ORIENTATION_ROTATE_90 -> rotateImage(resizedBitmap, 90f)
ExifInterface.ORIENTATION_ROTATE_180 -> rotateImage(resizedBitmap, 180f)
ExifInterface.ORIENTATION_ROTATE_270 -> rotateImage(resizedBitmap, 270f)
else -> resizedBitmap
}
val outputFile = File(photoPath)
FileOutputStream(outputFile).use { out ->
resizedBitmap.compress(Bitmap.CompressFormat.JPEG, 85, out)
}
return outputFile.absolutePath
}
private fun rotateImage(bitmap: Bitmap, degree: Float): Bitmap {
val matrix = Matrix()
matrix.postRotate(degree)
return Bitmap.createBitmap(
bitmap,
0,
0,
bitmap.width,
bitmap.height,
matrix,
true
)
}
```
7. 回傳的路徑通常長這樣 ```file:///storage/...```,但 Flutter 的 File 要得路徑不能包含 ```file://```,所以可以修剪一下路徑的 string。
```keyword: string.replace()```
8. Flutter 端的 code 需要小改,請自行研究。
## 桌面小工具
1. 在 app 資料夾上點選右鍵 -> New -> Widget。
2. 設定好 Widget 的參數,記好 Widget 的 class name。
3. 看一下參考影片並參閱一下 home_widget 的官分文檔,應該不難做出來。
4. 研究一下 view 和 layout.xml 在做什麼,並做出適當的更改。
5. 由於從 Firebase 讀取照片是用 URL 而非 file path,因此需要用到一些函式庫。
打開 ```android/app/build.gradle```,新增以下兩個 dependencies:
```gradle=
implementation 'com.github.bumptech.glide:glide:4.12.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0'
```
更換桌面小工具背景圖片的方法:
***```<>``` 包起來的請自行更換***
```kotlin=
val appWidgetTarget = object : AppWidgetTarget(context.applicationContext, R.id.<your_background_view_id>, views, appWidgetId) {
override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {
super.onResourceReady(resource, transition)
// Update the widget
appWidgetManager.updateAppWidget(appWidgetId, views)
}
}
Glide.with(context.applicationContext)
.asBitmap()
.load(<your_imageUrl>)
.into(appWidgetTarget)
```
## 參考連結
- [Chat GPT](https://chatgpt.com/)
- [Home Widget Tutorial Video](https://youtu.be/e7ee8UIlXFY?si=VxTjsfcKG837yFV4)
- [home_widget | Flutter package - Pub](https://pub.dev/packages/home_widget)