Skip to content

Commit

Permalink
Merge pull request #67 from the-reach-trust/master
Browse files Browse the repository at this point in the history
🚀 Android 15 (API 35) Upgrade & Firebase Storage Refactor
  • Loading branch information
ZanriKritzinger authored Feb 12, 2025
2 parents 4025287 + 17e8339 commit 371bcb8
Show file tree
Hide file tree
Showing 9 changed files with 156 additions and 145 deletions.
56 changes: 14 additions & 42 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'com.github.triplet.play'
apply plugin: 'com.google.firebase.firebase-perf'
apply plugin: 'com.google.gms.google-services'
apply plugin: 'com.google.firebase.crashlytics'
apply plugin: 'kotlin-kapt'

repositories {
Expand All @@ -16,7 +18,7 @@ android {
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.compileSdkVersion
versionCode = rootProject.ext.versionCode
versionName = "$rootProject.ext.versionName"
versionName = rootProject.ext.versionName
testInstrumentationRunner "org.bookdash.android.presentation.CustomTestRunner"
resConfigs "en"
vectorDrawables.useSupportLibrary = true
Expand All @@ -31,21 +33,24 @@ android {
targetCompatibility JavaVersion.VERSION_17
}

kotlinOptions {
jvmTarget = '17'
}

File signFile = rootProject.file('release-keystore.properties')
if (signFile.exists()) {
signingConfigs {
release {
def props = new Properties()

props.load(new FileInputStream(signFile))

storeFile rootProject.file(props.keyStore)
storePassword props.keyStorePassword
keyAlias props.keyAlias
keyPassword props.keyAliasPassword
}
}
buildTypes.release.signingConfig signingConfigs.release
buildTypes.debug.signingConfig signingConfigs.release
}

packagingOptions {
Expand All @@ -63,40 +68,6 @@ android {
}

flavorDimensions.add("env")

// productFlavors {
// mock {
// dimension "env"
// versionNameSuffix ".qa"
// applicationIdSuffix ".qa"
// }
// prod {
// dimension "env"
// }
// }

// productFlavors {
// mock {
// dimension "env"
// applicationIdSuffix = ".qa"
// }
// qa {
// dimension "env"
// applicationIdSuffix = ".qa"
// }
// prod {
// dimension "env"
// }
// }
// Remove mockRelease as it's not needed.
// androidComponents {
// onVariants { variant ->
// // Remove 'mock' flavor variants in 'release' build type
// if (variant.buildType.name == 'release' && variant.productFlavors.any { it.name == 'mock' }) {
// variant.ignore = true
// }
// }
// }
// Always show the result of every unit test, even if it passes.
testOptions.unitTests.all {
testLogging {
Expand Down Expand Up @@ -125,9 +96,13 @@ android {
track = "${track}"
}
namespace 'org.bookdash.android'


}

dependencies {

implementation 'com.google.firebase:firebase-storage-ktx:21.0.1'
testImplementation "junit:junit:$rootProject.ext.junitVersion"
testImplementation "org.mockito:mockito-all:$rootProject.ext.mockitoVersion"
testImplementation "org.hamcrest:hamcrest-all:$rootProject.ext.hamcrestVersion"
Expand Down Expand Up @@ -175,7 +150,6 @@ dependencies {
implementation 'com.google.firebase:firebase-messaging'
implementation 'com.google.firebase:firebase-perf'
implementation 'com.google.firebase:firebase-storage'
implementation 'com.firebaseui:firebase-ui-storage:6.1.0'

implementation 'io.reactivex:rxandroid:1.2.1'
implementation 'io.reactivex:rxjava:1.2.5'
Expand All @@ -188,9 +162,7 @@ dependencies {
implementation "androidx.drawerlayout:drawerlayout:1.2.0"
implementation "com.google.android.material:material:$rootProject.ext.materialVersion"


implementation project(path: ':materialhelptutorial')
implementation project(path: ':fabbutton')
}

apply plugin: 'com.google.gms.google-services'
apply plugin: 'com.google.firebase.crashlytics'
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,13 @@ import com.bumptech.glide.GlideBuilder
import com.bumptech.glide.Registry
import com.bumptech.glide.annotation.GlideModule
import com.bumptech.glide.module.AppGlideModule
import com.firebase.ui.storage.images.FirebaseImageLoader
import com.google.firebase.storage.StorageReference

import java.io.InputStream

@GlideModule
class MyGlideModule : AppGlideModule() {

override fun registerComponents(context: Context, glide: Glide, registry: Registry) {
// Register FirebaseImageLoader to handle StorageReference
registry.append(StorageReference::class.java, InputStream::class.java,
FirebaseImageLoader.Factory())

}

override fun applyOptions(context: Context, builder: GlideBuilder) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package org.bookdash.android.presentation.bookinfo;

import static org.bookdash.android.presentation.utils.StringUtils.convertGsUrlToHttp;

import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.Intent;
Expand Down Expand Up @@ -47,7 +49,6 @@
import com.google.android.material.appbar.AppBarLayout;
import com.google.android.material.appbar.CollapsingToolbarLayout;
import com.google.android.material.snackbar.Snackbar;
import com.google.firebase.storage.StorageReference;

import org.bookdash.android.R;
import org.bookdash.android.config.GlideApp;
Expand Down Expand Up @@ -267,7 +268,7 @@ protected void onNewIntent(Intent intent) {
}
}

private void loadImage(StorageReference url) {
private void loadImage(String url) {
GlideApp.with(this).load(url)
.transition(DrawableTransitionOptions.withCrossFade())
.into(new CustomTarget<Drawable>() {
Expand All @@ -286,6 +287,8 @@ public void onLoadCleared(@Nullable Drawable placeholder) {
}
});
}


public static Bitmap drawableToBitmap (Drawable drawable) {
Bitmap bitmap = null;

Expand Down Expand Up @@ -440,7 +443,8 @@ public void setBookInfoBinding(FireBookDetails bookInfo) {
if (bookInfo.isDownloadedAlready()) {
showDownloadFinished();
}
loadImage(bookInfo.getFirebaseBookCoverUrl());
String firebaseUrl = convertGsUrlToHttp(bookInfo.getBookCoverPageUrl());
loadImage(firebaseUrl);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import org.bookdash.android.R;
import org.bookdash.android.config.GlideApp;
import org.bookdash.android.domain.model.firebase.FireBookDetails;
import org.bookdash.android.presentation.utils.StringUtils;

import java.util.List;

Expand Down Expand Up @@ -39,7 +40,8 @@ public DownloadsViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
public void onBindViewHolder(DownloadsViewHolder holder, int position) {
FireBookDetails book = bookList.get(position);
holder.downloadTitleTextView.setText(book.getBookTitle());
GlideApp.with(context).load(book.getFirebaseBookCoverUrl()).into(holder.downloadImageTextView);
String firebaseBookCoverUrl = StringUtils.convertGsUrlToHttp(book.getBookCoverPageUrl());
GlideApp.with(context).load(firebaseBookCoverUrl).into(holder.downloadImageTextView);
holder.downloadActionButtonView.setOnClickListener(deleteClickListener);
holder.book = book;
holder.downloadActionButtonView.setTag(holder);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package org.bookdash.android.presentation.listbooks;

import static org.bookdash.android.presentation.utils.StringUtils.convertGsUrlToHttp;

import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
Expand All @@ -16,6 +17,8 @@

import java.util.List;

import timber.log.Timber;

/**
* @author Rebecca Franks
* @since 2015/07/16 2:06 PM
Expand All @@ -38,15 +41,33 @@ public BookViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new BookViewHolder(v);
}


@Override
public void onBindViewHolder(BookViewHolder holder, int position) {
FireBookDetails bookDetail = bookDetails.get(position);
holder.bookTitle.setText(bookDetail.getBookTitle());
Log.d("BookAdapter", "Book url:" + bookDetail.getBookCoverPageUrl());
GlideApp.with(context).load(bookDetail.getFirebaseBookCoverUrl())
.transition(DrawableTransitionOptions.withCrossFade())
.placeholder(R.drawable.bookdash_placeholder).error(R.drawable.bookdash_placeholder)
.into(holder.bookCover);

String bookCoverImage = bookDetail.getBookCoverPageUrl();
if (bookCoverImage != null) {
Timber.tag("BookAdapter").d("Book url:%s", bookCoverImage);
String firebaseUrl = convertGsUrlToHttp(bookCoverImage);

if (firebaseUrl != null) {
GlideApp.with(context)
.load(firebaseUrl)
.transition(DrawableTransitionOptions.withCrossFade())
.placeholder(R.drawable.bookdash_placeholder)
.error(R.drawable.bookdash_placeholder)
.into(holder.bookCover);
} else {
// Handle error: possibly use a fallback image if conversion fails
holder.bookCover.setImageResource(R.drawable.bookdash_placeholder);
}
} else {
// Handle case where URL is null
holder.bookCover.setImageResource(R.drawable.bookdash_placeholder);
}

holder.bookDetail = bookDetail;
holder.downloadedIcon.setVisibility(bookDetail.isDownloadedAlready() ? View.VISIBLE : View.INVISIBLE);
holder.cardContainer.setTag(holder);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package org.bookdash.android.presentation.utils;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;

import timber.log.Timber;

public class StringUtils {
public static String convertGsUrlToHttp(String gsUrl) {
if (gsUrl == null || !gsUrl.startsWith("gs://book-dash.appspot.com/")) {
return null;
}

// Extract path from gs:// URL
String path = gsUrl.substring("gs://book-dash.appspot.com/".length());

try {
// URL-encode the path, but leave '/' and ':' as is
String encodedPath = URLEncoder.encode(path, StandardCharsets.UTF_8.toString());

// Construct the Firebase URL
return String.format("https://firebasestorage.googleapis.com/v0/b/book-dash.appspot.com/o/%s?alt=media",
encodedPath);
} catch (UnsupportedEncodingException e) {
Timber.tag("URLConversion").e(e, "Failed to encode URL");
return null;
}
}
}
25 changes: 20 additions & 5 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
ext.kotlin_version = '1.9.20'
ext.kotlin_version = '1.9.21'
repositories {
jcenter()
google()
Expand All @@ -24,14 +24,29 @@ allprojects {
}

ext {
versionCode = 38
versionName = "2.9.3"
versionCode = 39
versionName = "2.9.4"
minSdkVersion = 23
compileSdkVersion = 34
compileSdkVersion = 35
junitVersion = '4.13.2'
mockitoVersion = '1.10.19'
powerMockito = '1.7.4'
hamcrestVersion = '1.3'
glideVersion = '4.11.0'
glideVersion = '4.15.1'
materialVersion = '1.13.0-alpha04'
}

tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).configureEach {
kotlinOptions {
jvmTarget = "17" // or "11", depending on your JDK version
freeCompilerArgs += [
"--add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED",
"--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED",
"--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED",
"--add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED",
"--add-exports=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED",
"--add-exports=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED",
"--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED"
]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ and associated documentation files (the "Software"), to deal in the Software wit


import android.app.ActionBar;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
Expand Down Expand Up @@ -76,23 +77,18 @@ protected void onCreate(Bundle savedInstanceState) {
getActionBar().hide();
}
mRootView = findViewById(R.id.activity_help_root);
mHelpTutorialViewPager = (ViewPager) findViewById(R.id.activity_help_view_pager);
mTextViewSkip = (TextView) findViewById(R.id.activity_help_skip_textview);
mNextButton = (ImageButton) findViewById(R.id.activity_next_button);
mDoneButton = (Button) findViewById(R.id.activity_tutorial_done);
mHelpTutorialViewPager = findViewById(R.id.activity_help_view_pager);
mTextViewSkip = findViewById(R.id.activity_help_skip_textview);
mNextButton = findViewById(R.id.activity_next_button);
mDoneButton = findViewById(R.id.activity_tutorial_done);

mTextViewSkip.setOnClickListener(finishTutorialClickListener);
mDoneButton.setOnClickListener(finishTutorialClickListener);


mNextButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
materialTutorialPresenter.nextClick();
mTextViewSkip.setOnClickListener(finishTutorialClickListener);
mDoneButton.setOnClickListener(finishTutorialClickListener);


}
});
mNextButton.setOnClickListener(v -> materialTutorialPresenter.nextClick());
List<TutorialItem> tutorialItems = getIntent().getParcelableArrayListExtra(MATERIAL_TUTORIAL_ARG_TUTORIAL_ITEMS);
if (tutorialItems == null) {
showEndTutorial();
Expand All @@ -105,11 +101,9 @@ private void setStatusBarColor() {
if (isFinishing()) {
return;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Window window = getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}
Window window = getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}

@Override
Expand Down
Loading

0 comments on commit 371bcb8

Please sign in to comment.