Skip to content
This repository was archived by the owner on Feb 4, 2024. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,12 @@ android {
}

dependencies {
def room_version = "2.3.0"

// Room
implementation "androidx.room:room-runtime:$room_version"
annotationProcessor "androidx.room:room-compiler:$room_version"

implementation 'androidx.appcompat:appcompat:1.3.0-beta01'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'

Expand Down
24 changes: 24 additions & 0 deletions app/src/main/java/com/gsnathan/pdfviewer/AppDatabase.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.gsnathan.pdfviewer;

import android.content.Context;

import androidx.room.Database;
import androidx.room.Room;
import androidx.room.RoomDatabase;

@Database(entities = {SavedLocation.class}, version = 1, exportSchema = false)
public abstract class AppDatabase extends RoomDatabase {
private static AppDatabase INSTANCE = null;
private static String DATABASE_NAME = "app-db.db";

public static AppDatabase getInstance(Context context) {
if (INSTANCE != null) {
return INSTANCE;
}
String location = context.getCacheDir().getAbsolutePath() + "/" + DATABASE_NAME;
INSTANCE = Room.databaseBuilder(context, AppDatabase.class, location).build();
return INSTANCE;
}

public abstract SavedLocationDao savedLocationDao();
}
73 changes: 68 additions & 5 deletions app/src/main/java/com/gsnathan/pdfviewer/MainActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,17 +35,18 @@
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Looper;
import android.os.StrictMode;
import android.preference.PreferenceManager;
import android.print.PrintManager;
import android.provider.OpenableColumns;
import android.util.Log;
import android.view.WindowManager;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Toast;

import androidx.activity.result.ActivityResultLauncher;
Expand Down Expand Up @@ -75,22 +76,36 @@
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

import static android.content.pm.PackageManager.PERMISSION_GRANTED;

public class MainActivity extends CyaneaAppCompatActivity {

private static final String TAG = "MainActivity";

/** For performance reasons, we won't hash the entire PDF but only up to this many bytes. */
private static final int HASH_SIZE = 1024 * 1024;

private final Executor executor = Executors.newSingleThreadExecutor();
private final Handler handler = new Handler(Looper.getMainLooper());

private PrintManager mgr;
private SharedPreferences prefManager;
private AppDatabase appDb;

private Uri uri;
private int pageNumber = 0;
private String pdfPassword;
private String pdfFileName = "";

private byte[] downloadedPdfFileContent;
private String fileContentHash = null;

private boolean isBottomNavigationHidden = false;
private boolean isFullscreenToggled = false;
Expand Down Expand Up @@ -122,7 +137,7 @@ protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
viewBinding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(viewBinding.getRoot());

Constants.THUMBNAIL_RATIO = 1f;
setBottomBarListeners();

Expand All @@ -133,6 +148,7 @@ protected void onCreate(Bundle savedInstanceState) {
prefManager = PreferenceManager.getDefaultSharedPreferences(this);

mgr = (PrintManager) getSystemService(PRINT_SERVICE);
appDb = AppDatabase.getInstance(getApplicationContext());
onFirstInstall();
onFirstUpdate();

Expand Down Expand Up @@ -253,18 +269,59 @@ private void setBottomBarListeners() {
});
}

String computeHash() {
try {
MessageDigest digester = MessageDigest.getInstance("MD5");
if (downloadedPdfFileContent != null) {
int size = Math.min(HASH_SIZE, downloadedPdfFileContent.length);
digester.update(downloadedPdfFileContent, 0, size);
} else {
InputStream is = getContentResolver().openInputStream(uri);
byte[] buffer = new byte[HASH_SIZE];
int amountRead = is.read(buffer);
if (amountRead == -1) {
return null;
}
digester.update(buffer, 0, amountRead);
}
return String.format("%032x", new BigInteger(1, digester.digest()));
} catch (NoSuchAlgorithmException | IOException e) {
return null;
}
}

void configurePdfViewAndLoad(PDFView.Configurator viewConfigurator) {
if (pageNumber == 0) { // attempt to find a saved location
executor.execute(() -> { // off UI thread
fileContentHash = computeHash();
Integer maybePageNumber = fileContentHash == null
? Integer.valueOf(0)
: appDb.savedLocationDao().findSavedPage(fileContentHash);
handler.post(() -> // back on UI thread
configurePdfViewAndLoadWithPageNumber(
viewConfigurator,
maybePageNumber != null ? maybePageNumber : 0
)
);
});
} else {
configurePdfViewAndLoadWithPageNumber(viewConfigurator, pageNumber);
}
}

void configurePdfViewAndLoadWithPageNumber(PDFView.Configurator viewConfigurator, int pageNum) {
if (!prefManager.getBoolean("pdftheme_pref", false)) {
viewBinding.pdfView.setBackgroundColor(Color.LTGRAY);
} else {
viewBinding.pdfView.setBackgroundColor(0xFF212121);
}

viewBinding.pdfView.useBestQuality(prefManager.getBoolean("quality_pref", false));
viewBinding.pdfView.setMinZoom(0.5f);
viewBinding.pdfView.setMidZoom(2.0f);
viewBinding.pdfView.setMaxZoom(5.0f);
viewConfigurator
.defaultPage(pageNumber)
.defaultPage(pageNum)
.onPageChange(this::setCurrentPage)
.enableAnnotationRendering(true)
.enableAntialiasing(prefManager.getBoolean("alias_pref", true))
Expand Down Expand Up @@ -447,6 +504,13 @@ void navToSettings() {
}

private void setCurrentPage(int page, int pageCount) {
String hash = fileContentHash; // Don't want fileContentHash to change out from under us
if (hash != null) {
executor.execute(() -> // off UI thread
appDb.savedLocationDao().insert(new SavedLocation(hash, pageNumber))
);
}

pageNumber = page;
setTitle(String.format("%s %s / %s", pdfFileName + " ", page + 1, pageCount));
}
Expand Down Expand Up @@ -546,4 +610,3 @@ public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
}
}
}

23 changes: 23 additions & 0 deletions app/src/main/java/com/gsnathan/pdfviewer/SavedLocation.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.gsnathan.pdfviewer;

import androidx.annotation.NonNull;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.PrimaryKey;

import org.jetbrains.annotations.NotNull;

@Entity
public class SavedLocation {
public SavedLocation(@NotNull String hash, int pageNumber) {
this.hash = hash;
this.pageNumber = pageNumber;
}

@PrimaryKey
@NonNull
public String hash;

@ColumnInfo(name = "pageNumber")
public int pageNumber;
}
15 changes: 15 additions & 0 deletions app/src/main/java/com/gsnathan/pdfviewer/SavedLocationDao.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.gsnathan.pdfviewer;

import androidx.room.Dao;
import androidx.room.Insert;
import androidx.room.OnConflictStrategy;
import androidx.room.Query;

@Dao
public interface SavedLocationDao {
@Query("SELECT pageNumber FROM SavedLocation WHERE hash = :hash")
Integer findSavedPage(String hash);

@Insert(onConflict = OnConflictStrategy.REPLACE)
void insert(SavedLocation saveLocations);
}