I want to upload a video to BunnyCDN using Retrofit in Android Kotlin, but getting crashes and error is not specified properly in Android Studio. Where I have made the mistake
Here is the documentation
[https://docs.bunny.net/reference/put_-storagezonename-path-filename][1]
Here is my all code.
In Main Activity
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private val REQUEST_CODE: Int = 0
private lateinit var uploadViewModel : VideoUploadViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
uploadViewModel = ViewModelProvider(this).get(VideoUploadViewModel::class.java)
val contact = registerForActivityResult(ActivityResultContracts.GetContent()){
binding.videoUri.text = it.toString()
uploadVideoToBunnyCDN(it!!)
}
binding.selectVideoBtn.setOnClickListener{
contact.launch("video/*")
}
uploadViewModel.videoUploadLiveData.observe(this) {
Log.i("message", it.message.toString())
}
}
private fun uploadVideoToBunnyCDN(it: Uri) {
val file = File(it.path) // Get the file from the Uri
val mediaType = "application/octet-stream".toMediaTypeOrNull()
val requestBody = RequestBody.create(mediaType, file)
Log.i("VIDEO_DATA_", requestBody.contentType().toString())
uploadViewModel.uploadVideo("assam-storage-zone","myFolder","videNew", requestBody)
}
}
ViewModel Class
@HiltViewModel
class VideoUploadViewModel @Inject constructor(private val repository: Repository) : ViewModel(){
val videoUploadLiveData get() = repository.statusLiveData
fun uploadVideo(storageZoneName: String,
folderName: String,
fileName: String,
file: RequestBody) {
viewModelScope.launch {
repository.uploadVideo(storageZoneName, folderName, fileName, file)
}
}
}
Repository class
class Repository @Inject constructor(private val uploadApi: UploadApi) {
private val _statusLiveData = MutableLiveData<NetworkResult<Pair<Boolean, String>>>()
val statusLiveData get() = _statusLiveData
suspend fun uploadVideo(storageZoneName: String,
folderName: String,
fileName: String,
file: RequestBody
) {
_statusLiveData.postValue(NetworkResult.Loading())
val response = uploadApi.uploadVideo(storageZoneName, folderName, fileName, file)
handleResponse(response, "Video Uploaded")
}
private fun handleResponse(response: Response<VideoUploadResponse>, message: String) {
if (response.isSuccessful && response.body() != null) {
_statusLiveData.postValue(NetworkResult.Success(Pair(true, message)))
} else {
_statusLiveData.postValue(NetworkResult.Success(Pair(false, "Something went wrong")))
}
}
}
Interface
interface UploadApi {
@Multipart
@PUT("/{storageZoneName}/{path}/{fileName}")
fun uploadVideo(
@Path("storageZoneName") storageZoneName: String,
@Path("path") folderName: String,
@Path("fileName") fileName: String,
@Body videoData: RequestBody
)
: Response<VideoUploadResponse>
}
AuthInterceptor class
class AuthInterceptor @Inject constructor(): Interceptor {
/*This will observe the request and add modification before sending the request*/
override fun intercept(chain: Interceptor.Chain): Response {
/*This will give us a new request object that we will be modified*/
val request = chain.request().newBuilder()
request.addHeader("AccessKey", "my access key")
request.addHeader("content-type", "application/octet-stream")
//return the modified request
return chain.proceed(request.build())
}
}
NetworkModule class
@InstallIn(SingletonComponent::class)
@Module
class NetworkModule {
/*This function will be used by hilt to create Retrofit object. Called by hilt*/
@Singleton
@Provides
fun providesRetrofitBuilder(): Retrofit.Builder{
return Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl("https://storage.bunnycdn.com/")
}
@Singleton
@Provides
fun providesOkhttpClient(authInterceptor: AuthInterceptor) : OkHttpClient {
return OkHttpClient.Builder().addInterceptor(authInterceptor).build()
}
@Singleton
@Provides
fun providesNoteAPI(retrofitBuilder: Retrofit.Builder, okHttpClient: OkHttpClient) : UploadApi{
return retrofitBuilder
.client(okHttpClient)
.build()
.create(UploadApi::class.java)
}
}
VideoUploadResponse class
data class VideoUploadResponse(
val message: String,
val HttpCode: Boolean
)
NetworkResult class
sealed class NetworkResult<T>(val data: T?= null, val message: String?= null){
class Success<T>(data: T): NetworkResult<T>(data)
class Error<T>(message: String?, data: T?= null): NetworkResult<T>(data, message)
class Loading<T> : NetworkResult<T>()
}