2
0

Androidでminioにデータを送るのは簡単なんだ.でも依存関係で地獄を見た.

Last updated at Posted at 2023-11-24

はじめに

始めまして.
この度はAdvent Calendar「Qiita学生iOS&Androidエンジニアのカレンダー」に誘われたので初めてQiitaに記事を書こうと思います.

minioとは

オンプレミスなAWS S3です.
minioの公式サイト

画像とか動画とかAPIで通信するには適さないなぁ〜
でもAWS契約するのもなぁ〜
自宅にサーバあるのになぁ〜
って人におすすめです.

今回は何を?

minioのサーバがあるとして,Androidでminioにデータ(CSVファイル)を送信してみようと思います

minioのJavaクイックスタートドキュメント

はじめよう

まずはGradleにminioの依存関係を書きましょう.
implementation 'io.minio:minio:8.5.1'
バージョンはその都度変えてください.

では,依存関係を書いたGradleです.

plugins {
    id 'com.android.application'
    id 'org.jetbrains.kotlin.android'
}

android {
    namespace 'com.example.minio_client'
    compileSdk 33

    defaultConfig {
        applicationId "com.example.minio_client"
        minSdk 31
        targetSdk 33
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    kotlinOptions {
        jvmTarget = '1.8'
    }
    packagingOptions {
        exclude 'javax/servlet/jsp/resources/jspxml.xsd'
        exclude 'javax/servlet/jsp/resources/web-jsptaglibrary_2_0.xsd'
        exclude 'javax/servlet/jsp/resources/web-jsptaglibrary_2_1.xsd'
        exclude 'javax/servlet/http/LocalStrings_ja.properties'
        exclude 'META-INF/mimetypes.default'
        exclude 'javax/servlet/resources/web-app_2_4.xsd'
        exclude 'javax/servlet/jsp/resources/web-jsptaglibrary_1_2.dtd'
        exclude 'javax/servlet/resources/j2ee_web_services_client_1_1.xsd'
        exclude 'javax/servlet/http/LocalStrings_fr.properties'
        exclude 'javax/servlet/LocalStrings_ja.properties'
        exclude 'javax/servlet/jsp/resources/web-jsptaglibrary_1_1.dtd'
        exclude 'javax/servlet/http/LocalStrings_es.properties'
        exclude 'javax/servlet/resources/xml.xsd'
        exclude 'javax/servlet/http/LocalStrings.properties'
        exclude 'javax/servlet/resources/XMLSchema.dtd'
        exclude 'javax/servlet/resources/j2ee_web_services_1_1.xsd'
        exclude 'javax/servlet/resources/web-app_2_2.dtd'
        exclude 'javax/servlet/resources/j2ee_1_4.xsd'
        exclude 'META-INF/DEPENDENCIES'
        exclude 'javax/servlet/resources/web-app_2_5.xsd'
        exclude 'javax/el/LocalStrings.properties'
        exclude 'javax/servlet/jsp/resources/jspxml.dtd'
        exclude 'javax/servlet/resources/datatypes.dtd'
        exclude 'javax/servlet/jsp/resources/jsp_2_0.xsd'
        exclude 'javax/servlet/LocalStrings_fr.properties'
        exclude 'javax/servlet/LocalStrings.properties'
        exclude 'javax/servlet/jsp/resources/jsp_2_1.xsd'
        exclude 'javax/servlet/resources/web-app_2_3.dtd'

    }
}

dependencies {

    implementation 'androidx.core:core-ktx:1.9.0'
    implementation 'androidx.appcompat:appcompat:1.6.0'
    implementation 'com.google.android.material:material:1.8.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.5'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
    implementation 'io.minio:minio:8.5.1'
    implementation group: 'org.apache.openejb', name: 'javaee-api', version: '6.0-1'
    implementation 'com.fasterxml.woodstox:woodstox-core:6.5.0'

}

あれ???すごく長くなっちゃった.
と,いうのも
僕が実装してみた時にライブラリ不足や競合が多く発生してしまい,それを解消したのがこちらです.

なぜこうなったのかを知りたい方はその時の苦悩がここにあるので見てください.

また,すでにある程度大きいプログラムで依存関係も複雑になってる場合これを実装すると競合が起こると思います.
僕はその時これで解消しました.

ではクライアントクラスを作ろう

package com.example.minio_client

import io.minio.MinioClient
import io.minio.UploadObjectArgs

class MinioClient {

    val accessKey = "アクセスキー"
    val secretKey = "シークレットキー"
    val bucketName = "バケットの名前"
    val endpoint = "https://~~~~"

    fun postFile(pass: String): String {
        val minioClient = MinioClient.builder()
            .endpoint(endpoint)
            .credentials(accessKey, secretKey)
            .build()

        // パスの後ろのファイル名をもらっておく
        val fileName = pass.substringAfterLast("/")

        try {
            minioClient.uploadObject(
                UploadObjectArgs.builder()
                    .bucket(bucketName)
                    // ファイルの名前."/"で区切ると階層を分けられる
                    .`object`("$fileName.csv")
                    // ファイルの場所
                    .filename(pass)
                    .build()
            )
            // 送信成功したらデータの場所を返してくれる
            return "$endpoint/$bucketName/$fileName"
        } catch (e: Exception) {
            return "File upload failed: ${e.message}"
        }
    }
}

クラスを作ったのでActivityで読んであげましょう.

package com.example.minio_client

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log


class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val externalStorage = ExternalStorage(this)
        val minioClient = MinioClient()

        try {
            val url = minioClient.postFile("CSVファイルの場所")
            // あの関数はファイルの場所を返してくれる
            Log.d("minio", "url = $url")
        } catch (e: Exception) {
            Log.d("minio", "error = ${e.message}")
        }

    }
}

おわりに

おそらくもっといいやり方があります.
当時は締め切りに追われて頭を焦がしながらこれを作りました.
もっといいやり方を知っている方や依存関係の問題を詳しく知っている人がいればコメントお願いします.

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0