libpdfviewer: Genesis
2
.gitmodules
vendored
@ -1,3 +1,3 @@
|
|||||||
[submodule "pdfjs-dist"]
|
[submodule "pdfjs-dist"]
|
||||||
path = third_party/pdfjs-dist
|
path = app/pdfjs-dist
|
||||||
url = https://github.com/mozilla/pdfjs-dist.git
|
url = https://github.com/mozilla/pdfjs-dist.git
|
||||||
|
@ -9,7 +9,7 @@ if (useKeystoreProperties) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id("com.android.application")
|
id("com.android.library")
|
||||||
id("kotlin-android")
|
id("kotlin-android")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -29,21 +29,13 @@ android {
|
|||||||
buildToolsVersion = "32.0.0"
|
buildToolsVersion = "32.0.0"
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId = "org.grapheneos.pdfviewer"
|
minSdk = 21
|
||||||
minSdk = 26
|
|
||||||
targetSdk = 31
|
targetSdk = 31
|
||||||
versionCode = 10
|
|
||||||
versionName = versionCode.toString()
|
|
||||||
resourceConfigurations.add("en")
|
resourceConfigurations.add("en")
|
||||||
}
|
}
|
||||||
|
|
||||||
buildTypes {
|
buildTypes {
|
||||||
getByName("debug") {
|
|
||||||
applicationIdSuffix = ".debug"
|
|
||||||
}
|
|
||||||
|
|
||||||
getByName("release") {
|
getByName("release") {
|
||||||
isShrinkResources = true
|
|
||||||
isMinifyEnabled = true
|
isMinifyEnabled = true
|
||||||
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
|
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
|
||||||
if (useKeystoreProperties) {
|
if (useKeystoreProperties) {
|
||||||
|
@ -2,25 +2,7 @@
|
|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="org.grapheneos.pdfviewer"
|
package="org.grapheneos.pdfviewer"
|
||||||
android:targetSandboxVersion="2">
|
android:targetSandboxVersion="2">
|
||||||
<application android:icon="@mipmap/ic_launcher"
|
<application>
|
||||||
android:roundIcon="@mipmap/ic_launcher_round"
|
|
||||||
android:label="@string/app_name"
|
|
||||||
android:theme="@style/AppTheme"
|
|
||||||
android:allowBackup="true">
|
|
||||||
<activity android:name=".PdfViewer"
|
|
||||||
android:exported="true">
|
|
||||||
<intent-filter>
|
|
||||||
<action android:name="android.intent.action.MAIN" />
|
|
||||||
<category android:name="android.intent.category.LAUNCHER" />
|
|
||||||
</intent-filter>
|
|
||||||
<intent-filter>
|
|
||||||
<action android:name="android.intent.action.VIEW" />
|
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
|
||||||
<category android:name="android.intent.category.BROWSABLE" />
|
|
||||||
<data android:mimeType="application/pdf" />
|
|
||||||
</intent-filter>
|
|
||||||
</activity>
|
|
||||||
|
|
||||||
<meta-data android:name="android.webkit.WebView.MetricsOptOut"
|
<meta-data android:name="android.webkit.WebView.MetricsOptOut"
|
||||||
android:value="true" />
|
android:value="true" />
|
||||||
<meta-data android:name="android.webkit.WebView.EnableSafeBrowsing"
|
<meta-data android:name="android.webkit.WebView.EnableSafeBrowsing"
|
||||||
|
@ -1 +1 @@
|
|||||||
../../../../third_party/pdfjs-dist/build/pdf.min.js
|
../../../pdfjs-dist/build/pdf.min.js
|
2
app/src/main/assets/pdf.worker.js
vendored
@ -1 +1 @@
|
|||||||
../../../../third_party/pdfjs-dist/build/pdf.worker.min.js
|
../../../pdfjs-dist/build/pdf.worker.min.js
|
Before Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 11 KiB |
@ -2,8 +2,6 @@ package org.grapheneos.pdfviewer;
|
|||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.view.GestureDetector;
|
|
||||||
import android.view.MotionEvent;
|
|
||||||
import android.view.ScaleGestureDetector;
|
import android.view.ScaleGestureDetector;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
@ -13,7 +11,6 @@ import android.view.View;
|
|||||||
|
|
||||||
class GestureHelper {
|
class GestureHelper {
|
||||||
public interface GestureListener {
|
public interface GestureListener {
|
||||||
boolean onTapUp();
|
|
||||||
// Can be replaced with ratio when supported
|
// Can be replaced with ratio when supported
|
||||||
void onZoomIn(float value);
|
void onZoomIn(float value);
|
||||||
void onZoomOut(float value);
|
void onZoomOut(float value);
|
||||||
@ -22,15 +19,6 @@ class GestureHelper {
|
|||||||
|
|
||||||
@SuppressLint("ClickableViewAccessibility")
|
@SuppressLint("ClickableViewAccessibility")
|
||||||
static void attach(Context context, View gestureView, GestureListener listener) {
|
static void attach(Context context, View gestureView, GestureListener listener) {
|
||||||
|
|
||||||
final GestureDetector detector = new GestureDetector(context,
|
|
||||||
new GestureDetector.SimpleOnGestureListener() {
|
|
||||||
@Override
|
|
||||||
public boolean onSingleTapUp(MotionEvent motionEvent) {
|
|
||||||
return listener.onTapUp();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
final ScaleGestureDetector scaleDetector = new ScaleGestureDetector(context,
|
final ScaleGestureDetector scaleDetector = new ScaleGestureDetector(context,
|
||||||
new ScaleGestureDetector.SimpleOnScaleGestureListener() {
|
new ScaleGestureDetector.SimpleOnScaleGestureListener() {
|
||||||
final float SPAN_RATIO = 600;
|
final float SPAN_RATIO = 600;
|
||||||
@ -67,7 +55,6 @@ class GestureHelper {
|
|||||||
});
|
});
|
||||||
|
|
||||||
gestureView.setOnTouchListener((view, motionEvent) -> {
|
gestureView.setOnTouchListener((view, motionEvent) -> {
|
||||||
detector.onTouchEvent(motionEvent);
|
|
||||||
scaleDetector.onTouchEvent(motionEvent);
|
scaleDetector.onTouchEvent(motionEvent);
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
@ -1,18 +1,16 @@
|
|||||||
package org.grapheneos.pdfviewer;
|
package org.grapheneos.pdfviewer;
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.content.Context;
|
||||||
import android.app.Activity;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.res.ColorStateList;
|
import android.content.res.ColorStateList;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.util.AttributeSet;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.Gravity;
|
import android.view.Gravity;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuInflater;
|
import android.view.MenuInflater;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
|
||||||
import android.webkit.CookieManager;
|
import android.webkit.CookieManager;
|
||||||
import android.webkit.JavascriptInterface;
|
import android.webkit.JavascriptInterface;
|
||||||
import android.webkit.WebResourceRequest;
|
import android.webkit.WebResourceRequest;
|
||||||
@ -24,13 +22,11 @@ import android.widget.TextView;
|
|||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
import androidx.loader.app.LoaderManager;
|
import androidx.loader.app.LoaderManager;
|
||||||
import androidx.loader.content.Loader;
|
import androidx.loader.content.Loader;
|
||||||
|
|
||||||
import com.google.android.material.snackbar.Snackbar;
|
|
||||||
|
|
||||||
import org.grapheneos.pdfviewer.databinding.WebviewBinding;
|
|
||||||
import org.grapheneos.pdfviewer.fragment.DocumentPropertiesFragment;
|
import org.grapheneos.pdfviewer.fragment.DocumentPropertiesFragment;
|
||||||
import org.grapheneos.pdfviewer.fragment.JumpToPageFragment;
|
import org.grapheneos.pdfviewer.fragment.JumpToPageFragment;
|
||||||
import org.grapheneos.pdfviewer.loader.DocumentPropertiesLoader;
|
import org.grapheneos.pdfviewer.loader.DocumentPropertiesLoader;
|
||||||
@ -40,13 +36,9 @@ import java.io.InputStream;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class PdfViewer extends AppCompatActivity implements LoaderManager.LoaderCallbacks<List<CharSequence>> {
|
public class PdfViewer extends WebView implements LoaderManager.LoaderCallbacks<List<CharSequence>> {
|
||||||
public static final String TAG = "PdfViewer";
|
public static final String TAG = "PdfViewer";
|
||||||
|
|
||||||
private static final String STATE_URI = "uri";
|
|
||||||
private static final String STATE_PAGE = "page";
|
|
||||||
private static final String STATE_ZOOM_RATIO = "zoomRatio";
|
|
||||||
private static final String STATE_DOCUMENT_ORIENTATION_DEGREES = "documentOrientationDegrees";
|
|
||||||
private static final String KEY_PROPERTIES = "properties";
|
private static final String KEY_PROPERTIES = "properties";
|
||||||
|
|
||||||
private static final String CONTENT_SECURITY_POLICY =
|
private static final String CONTENT_SECURITY_POLICY =
|
||||||
@ -92,12 +84,10 @@ public class PdfViewer extends AppCompatActivity implements LoaderManager.Loader
|
|||||||
private static final float MAX_ZOOM_RATIO = 1.5f;
|
private static final float MAX_ZOOM_RATIO = 1.5f;
|
||||||
private static final int ALPHA_LOW = 130;
|
private static final int ALPHA_LOW = 130;
|
||||||
private static final int ALPHA_HIGH = 255;
|
private static final int ALPHA_HIGH = 255;
|
||||||
private static final int ACTION_OPEN_DOCUMENT_REQUEST_CODE = 1;
|
|
||||||
private static final int STATE_LOADED = 1;
|
private static final int STATE_LOADED = 1;
|
||||||
private static final int STATE_END = 2;
|
private static final int STATE_END = 2;
|
||||||
private static final int PADDING = 10;
|
private static final int PADDING = 10;
|
||||||
|
|
||||||
private Uri mUri;
|
|
||||||
public int mPage;
|
public int mPage;
|
||||||
public int mNumPages;
|
public int mNumPages;
|
||||||
private float mZoomRatio = 1f;
|
private float mZoomRatio = 1f;
|
||||||
@ -107,70 +97,27 @@ public class PdfViewer extends AppCompatActivity implements LoaderManager.Loader
|
|||||||
private List<CharSequence> mDocumentProperties;
|
private List<CharSequence> mDocumentProperties;
|
||||||
private InputStream mInputStream;
|
private InputStream mInputStream;
|
||||||
|
|
||||||
private WebviewBinding binding;
|
|
||||||
private TextView mTextView;
|
private TextView mTextView;
|
||||||
private Toast mToast;
|
private Toast mToast;
|
||||||
private Snackbar snackbar;
|
|
||||||
|
|
||||||
private class Channel {
|
public AppCompatActivity activity;
|
||||||
@JavascriptInterface
|
String fileName;
|
||||||
public int getWindowInsetTop() {
|
Long fileSize;
|
||||||
return windowInsetTop;
|
|
||||||
}
|
|
||||||
|
|
||||||
@JavascriptInterface
|
void init(Context context) {
|
||||||
public int getPage() {
|
setBackgroundColor(Color.TRANSPARENT);
|
||||||
return mPage;
|
|
||||||
}
|
|
||||||
|
|
||||||
@JavascriptInterface
|
|
||||||
public float getZoomRatio() {
|
|
||||||
return mZoomRatio;
|
|
||||||
}
|
|
||||||
|
|
||||||
@JavascriptInterface
|
|
||||||
public int getDocumentOrientationDegrees() {
|
|
||||||
return mDocumentOrientationDegrees;
|
|
||||||
}
|
|
||||||
|
|
||||||
@JavascriptInterface
|
|
||||||
public void setNumPages(int numPages) {
|
|
||||||
mNumPages = numPages;
|
|
||||||
runOnUiThread(PdfViewer.this::invalidateOptionsMenu);
|
|
||||||
}
|
|
||||||
|
|
||||||
@JavascriptInterface
|
|
||||||
public void setDocumentProperties(final String properties) {
|
|
||||||
if (mDocumentProperties != null) {
|
|
||||||
throw new SecurityException("mDocumentProperties not null");
|
|
||||||
}
|
|
||||||
|
|
||||||
final Bundle args = new Bundle();
|
|
||||||
args.putString(KEY_PROPERTIES, properties);
|
|
||||||
runOnUiThread(() -> LoaderManager.getInstance(PdfViewer.this).restartLoader(DocumentPropertiesLoader.ID, args, PdfViewer.this));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@SuppressLint({"SetJavaScriptEnabled", "ClickableViewAccessibility"})
|
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
binding = WebviewBinding.inflate(getLayoutInflater());
|
|
||||||
setContentView(binding.getRoot());
|
|
||||||
|
|
||||||
binding.webview.setBackgroundColor(Color.TRANSPARENT);
|
|
||||||
|
|
||||||
if (BuildConfig.DEBUG) {
|
if (BuildConfig.DEBUG) {
|
||||||
WebView.setWebContentsDebuggingEnabled(true);
|
WebView.setWebContentsDebuggingEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.webview.setOnApplyWindowInsetsListener((view, insets) -> {
|
setOnApplyWindowInsetsListener((view, insets) -> {
|
||||||
windowInsetTop = insets.getSystemWindowInsetTop();
|
windowInsetTop = insets.getSystemWindowInsetTop();
|
||||||
binding.webview.evaluateJavascript("updateInset()", null);
|
evaluateJavascript("updateInset()", null);
|
||||||
return insets;
|
return insets;
|
||||||
});
|
});
|
||||||
|
|
||||||
final WebSettings settings = binding.webview.getSettings();
|
final WebSettings settings = getSettings();
|
||||||
settings.setAllowContentAccess(false);
|
settings.setAllowContentAccess(false);
|
||||||
settings.setAllowFileAccess(false);
|
settings.setAllowFileAccess(false);
|
||||||
settings.setCacheMode(WebSettings.LOAD_NO_CACHE);
|
settings.setCacheMode(WebSettings.LOAD_NO_CACHE);
|
||||||
@ -178,12 +125,12 @@ public class PdfViewer extends AppCompatActivity implements LoaderManager.Loader
|
|||||||
|
|
||||||
CookieManager.getInstance().setAcceptCookie(false);
|
CookieManager.getInstance().setAcceptCookie(false);
|
||||||
|
|
||||||
binding.webview.addJavascriptInterface(new Channel(), "channel");
|
addJavascriptInterface(new Channel(), "channel");
|
||||||
|
|
||||||
binding.webview.setWebViewClient(new WebViewClient() {
|
setWebViewClient(new WebViewClient() {
|
||||||
private WebResourceResponse fromAsset(final String mime, final String path) {
|
private WebResourceResponse fromAsset(final String mime, final String path) {
|
||||||
try {
|
try {
|
||||||
InputStream inputStream = getAssets().open(path.substring(1));
|
InputStream inputStream = context.getAssets().open(path.substring(1));
|
||||||
return new WebResourceResponse(mime, null, inputStream);
|
return new WebResourceResponse(mime, null, inputStream);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
return null;
|
return null;
|
||||||
@ -237,30 +184,12 @@ public class PdfViewer extends AppCompatActivity implements LoaderManager.Loader
|
|||||||
@Override
|
@Override
|
||||||
public void onPageFinished(WebView view, String url) {
|
public void onPageFinished(WebView view, String url) {
|
||||||
mDocumentState = STATE_LOADED;
|
mDocumentState = STATE_LOADED;
|
||||||
invalidateOptionsMenu();
|
activity.invalidateOptionsMenu();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
GestureHelper.attach(PdfViewer.this, binding.webview,
|
GestureHelper.attach(context, this,
|
||||||
new GestureHelper.GestureListener() {
|
new GestureHelper.GestureListener() {
|
||||||
@Override
|
|
||||||
public boolean onTapUp() {
|
|
||||||
if (mUri != null) {
|
|
||||||
binding.webview.evaluateJavascript("isTextSelected()", selection -> {
|
|
||||||
if (!Boolean.parseBoolean(selection)) {
|
|
||||||
if ((getWindow().getDecorView().getSystemUiVisibility() &
|
|
||||||
View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) {
|
|
||||||
hideSystemUi();
|
|
||||||
} else {
|
|
||||||
showSystemUi();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onZoomIn(float value) {
|
public void onZoomIn(float value) {
|
||||||
zoomIn(value, false);
|
zoomIn(value, false);
|
||||||
@ -277,56 +206,82 @@ public class PdfViewer extends AppCompatActivity implements LoaderManager.Loader
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
mTextView = new TextView(this);
|
mTextView = new TextView(context);
|
||||||
mTextView.setBackgroundColor(Color.DKGRAY);
|
mTextView.setBackgroundColor(Color.DKGRAY);
|
||||||
mTextView.setTextColor(ColorStateList.valueOf(Color.WHITE));
|
mTextView.setTextColor(ColorStateList.valueOf(Color.WHITE));
|
||||||
mTextView.setTextSize(18);
|
mTextView.setTextSize(18);
|
||||||
mTextView.setPadding(PADDING, 0, PADDING, 0);
|
mTextView.setPadding(PADDING, 0, PADDING, 0);
|
||||||
|
|
||||||
// If loaders are not being initialized in onCreate(), the result will not be delivered
|
|
||||||
// after orientation change (See FragmentHostCallback), thus initialize the
|
|
||||||
// loader manager impl so that the result will be delivered.
|
|
||||||
LoaderManager.getInstance(this);
|
|
||||||
|
|
||||||
snackbar = Snackbar.make(binding.webview, "", Snackbar.LENGTH_LONG);
|
|
||||||
|
|
||||||
final Intent intent = getIntent();
|
|
||||||
if (Intent.ACTION_VIEW.equals(intent.getAction())) {
|
|
||||||
if (!"application/pdf".equals(intent.getType())) {
|
|
||||||
snackbar.setText(R.string.invalid_mime_type).show();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
mUri = intent.getData();
|
|
||||||
mPage = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (savedInstanceState != null) {
|
public PdfViewer(@NonNull Context context) {
|
||||||
mUri = savedInstanceState.getParcelable(STATE_URI);
|
super(context);
|
||||||
mPage = savedInstanceState.getInt(STATE_PAGE);
|
init(context);
|
||||||
mZoomRatio = savedInstanceState.getFloat(STATE_ZOOM_RATIO);
|
|
||||||
mDocumentOrientationDegrees = savedInstanceState.getInt(STATE_DOCUMENT_ORIENTATION_DEGREES);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mUri != null) {
|
public PdfViewer(@NonNull Context context, @Nullable AttributeSet attrs) {
|
||||||
if ("file".equals(mUri.getScheme())) {
|
super(context, attrs);
|
||||||
snackbar.setText(R.string.legacy_file_uri).show();
|
init(context);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
loadPdf();
|
public PdfViewer(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
||||||
|
super(context, attrs, defStyleAttr);
|
||||||
|
init(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onCreateOptionMenu(Menu menu) {
|
||||||
|
MenuInflater inflater = activity.getMenuInflater();
|
||||||
|
inflater.inflate(R.menu.pdf_viewer, menu);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class Channel {
|
||||||
|
@JavascriptInterface
|
||||||
|
public int getWindowInsetTop() {
|
||||||
|
return windowInsetTop;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JavascriptInterface
|
||||||
|
public int getPage() {
|
||||||
|
return mPage;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JavascriptInterface
|
||||||
|
public float getZoomRatio() {
|
||||||
|
return mZoomRatio;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JavascriptInterface
|
||||||
|
public int getDocumentOrientationDegrees() {
|
||||||
|
return mDocumentOrientationDegrees;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JavascriptInterface
|
||||||
|
public void setNumPages(int numPages) {
|
||||||
|
mNumPages = numPages;
|
||||||
|
activity.runOnUiThread(activity::invalidateOptionsMenu);
|
||||||
|
}
|
||||||
|
|
||||||
|
@JavascriptInterface
|
||||||
|
public void setDocumentProperties(final String properties) {
|
||||||
|
if (mDocumentProperties != null) {
|
||||||
|
throw new SecurityException("mDocumentProperties not null");
|
||||||
|
}
|
||||||
|
|
||||||
|
final Bundle args = new Bundle();
|
||||||
|
args.putString(KEY_PROPERTIES, properties);
|
||||||
|
activity.runOnUiThread(() -> LoaderManager.getInstance(PdfViewer.this.activity).restartLoader(DocumentPropertiesLoader.ID, args, PdfViewer.this));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public Loader<List<CharSequence>> onCreateLoader(int id, Bundle args) {
|
public Loader<List<CharSequence>> onCreateLoader(int id, Bundle args) {
|
||||||
return new DocumentPropertiesLoader(this, args.getString(KEY_PROPERTIES), mNumPages, mUri);
|
return new DocumentPropertiesLoader(activity, args.getString(KEY_PROPERTIES), mNumPages, fileName, fileSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLoadFinished(@NonNull Loader<List<CharSequence>> loader, List<CharSequence> data) {
|
public void onLoadFinished(@NonNull Loader<List<CharSequence>> loader, List<CharSequence> data) {
|
||||||
mDocumentProperties = data;
|
mDocumentProperties = data;
|
||||||
LoaderManager.getInstance(this).destroyLoader(DocumentPropertiesLoader.ID);
|
LoaderManager.getInstance(activity).destroyLoader(DocumentPropertiesLoader.ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -334,23 +289,18 @@ public class PdfViewer extends AppCompatActivity implements LoaderManager.Loader
|
|||||||
mDocumentProperties = null;
|
mDocumentProperties = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadPdf() {
|
public void loadPdf(InputStream inputStream, String fileName, Long fileSize) {
|
||||||
try {
|
mPage = 1;
|
||||||
if (mInputStream != null) {
|
mDocumentProperties = null;
|
||||||
mInputStream.close();
|
mInputStream = inputStream;
|
||||||
}
|
this.fileName = fileName;
|
||||||
mInputStream = getContentResolver().openInputStream(mUri);
|
this.fileSize = fileSize;
|
||||||
} catch (IOException e) {
|
loadUrl("https://localhost/viewer.html");
|
||||||
snackbar.setText(R.string.io_error).show();
|
activity.invalidateOptionsMenu();
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
showSystemUi();
|
|
||||||
binding.webview.loadUrl("https://localhost/viewer.html");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void renderPage(final int zoom) {
|
private void renderPage(final int zoom) {
|
||||||
binding.webview.evaluateJavascript("onRenderPage(" + zoom + ")", null);
|
evaluateJavascript("onRenderPage(" + zoom + ")", null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void documentOrientationChanged(final int orientationDegreesOffset) {
|
private void documentOrientationChanged(final int orientationDegreesOffset) {
|
||||||
@ -361,18 +311,11 @@ public class PdfViewer extends AppCompatActivity implements LoaderManager.Loader
|
|||||||
renderPage(0);
|
renderPage(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void openDocument() {
|
|
||||||
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
|
|
||||||
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
|
||||||
intent.setType("application/pdf");
|
|
||||||
startActivityForResult(intent, ACTION_OPEN_DOCUMENT_REQUEST_CODE);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void zoomIn(float value, boolean end) {
|
private void zoomIn(float value, boolean end) {
|
||||||
if (mZoomRatio < MAX_ZOOM_RATIO) {
|
if (mZoomRatio < MAX_ZOOM_RATIO) {
|
||||||
mZoomRatio = Math.min(mZoomRatio + value, MAX_ZOOM_RATIO);
|
mZoomRatio = Math.min(mZoomRatio + value, MAX_ZOOM_RATIO);
|
||||||
renderPage(end ? 1 : 2);
|
renderPage(end ? 1 : 2);
|
||||||
invalidateOptionsMenu();
|
activity.invalidateOptionsMenu();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -380,7 +323,7 @@ public class PdfViewer extends AppCompatActivity implements LoaderManager.Loader
|
|||||||
if (mZoomRatio > MIN_ZOOM_RATIO) {
|
if (mZoomRatio > MIN_ZOOM_RATIO) {
|
||||||
mZoomRatio = Math.max(mZoomRatio - value, MIN_ZOOM_RATIO);
|
mZoomRatio = Math.max(mZoomRatio - value, MIN_ZOOM_RATIO);
|
||||||
renderPage(end ? 1 : 2);
|
renderPage(end ? 1 : 2);
|
||||||
invalidateOptionsMenu();
|
activity.invalidateOptionsMenu();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -403,48 +346,7 @@ public class PdfViewer extends AppCompatActivity implements LoaderManager.Loader
|
|||||||
mPage = selected_page;
|
mPage = selected_page;
|
||||||
renderPage(0);
|
renderPage(0);
|
||||||
showPageNumber();
|
showPageNumber();
|
||||||
invalidateOptionsMenu();
|
activity.invalidateOptionsMenu();
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void showSystemUi() {
|
|
||||||
getWindow().getDecorView().setSystemUiVisibility(
|
|
||||||
View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
|
|
||||||
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
|
|
||||||
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void hideSystemUi() {
|
|
||||||
getWindow().getDecorView().setSystemUiVisibility(
|
|
||||||
View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
|
|
||||||
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
|
|
||||||
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
|
|
||||||
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
|
|
||||||
View.SYSTEM_UI_FLAG_FULLSCREEN |
|
|
||||||
View.SYSTEM_UI_FLAG_IMMERSIVE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSaveInstanceState(@NonNull Bundle savedInstanceState) {
|
|
||||||
super.onSaveInstanceState(savedInstanceState);
|
|
||||||
savedInstanceState.putParcelable(STATE_URI, mUri);
|
|
||||||
savedInstanceState.putInt(STATE_PAGE, mPage);
|
|
||||||
savedInstanceState.putFloat(STATE_ZOOM_RATIO, mZoomRatio);
|
|
||||||
savedInstanceState.putInt(STATE_DOCUMENT_ORIENTATION_DEGREES, mDocumentOrientationDegrees);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onActivityResult(int requestCode, int resultCode, Intent resultData) {
|
|
||||||
super.onActivityResult(requestCode, resultCode, resultData);
|
|
||||||
|
|
||||||
if (requestCode == ACTION_OPEN_DOCUMENT_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
|
|
||||||
if (resultData != null) {
|
|
||||||
mUri = resultData.getData();
|
|
||||||
mPage = 1;
|
|
||||||
mDocumentProperties = null;
|
|
||||||
loadPdf();
|
|
||||||
invalidateOptionsMenu();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -453,22 +355,13 @@ public class PdfViewer extends AppCompatActivity implements LoaderManager.Loader
|
|||||||
mToast.cancel();
|
mToast.cancel();
|
||||||
}
|
}
|
||||||
mTextView.setText(String.format("%s/%s", mPage, mNumPages));
|
mTextView.setText(String.format("%s/%s", mPage, mNumPages));
|
||||||
mToast = new Toast(getApplicationContext());
|
mToast = new Toast(activity);
|
||||||
mToast.setGravity(Gravity.BOTTOM | Gravity.END, PADDING, PADDING);
|
mToast.setGravity(Gravity.BOTTOM | Gravity.END, PADDING, PADDING);
|
||||||
mToast.setDuration(Toast.LENGTH_SHORT);
|
mToast.setDuration(Toast.LENGTH_SHORT);
|
||||||
mToast.setView(mTextView);
|
mToast.setView(mTextView);
|
||||||
mToast.show();
|
mToast.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onCreateOptionsMenu(Menu menu) {
|
|
||||||
super.onCreateOptionsMenu(menu);
|
|
||||||
MenuInflater inflater = getMenuInflater();
|
|
||||||
inflater.inflate(R.menu.pdf_viewer, menu);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onPrepareOptionsMenu(Menu menu) {
|
public boolean onPrepareOptionsMenu(Menu menu) {
|
||||||
final int[] ids = { R.id.action_zoom_in, R.id.action_zoom_out, R.id.action_jump_to_page,
|
final int[] ids = { R.id.action_zoom_in, R.id.action_zoom_out, R.id.action_jump_to_page,
|
||||||
R.id.action_next, R.id.action_previous, R.id.action_first, R.id.action_last,
|
R.id.action_next, R.id.action_previous, R.id.action_first, R.id.action_last,
|
||||||
@ -499,7 +392,6 @@ public class PdfViewer extends AppCompatActivity implements LoaderManager.Loader
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
final int itemId = item.getItemId();
|
final int itemId = item.getItemId();
|
||||||
if (itemId == R.id.action_previous) {
|
if (itemId == R.id.action_previous) {
|
||||||
@ -514,9 +406,6 @@ public class PdfViewer extends AppCompatActivity implements LoaderManager.Loader
|
|||||||
} else if (itemId == R.id.action_last) {
|
} else if (itemId == R.id.action_last) {
|
||||||
onJumpToPageInDocument(mNumPages);
|
onJumpToPageInDocument(mNumPages);
|
||||||
return true;
|
return true;
|
||||||
} else if (itemId == R.id.action_open) {
|
|
||||||
openDocument();
|
|
||||||
return true;
|
|
||||||
} else if (itemId == R.id.action_zoom_out) {
|
} else if (itemId == R.id.action_zoom_out) {
|
||||||
zoomOut(0.25f, true);
|
zoomOut(0.25f, true);
|
||||||
return true;
|
return true;
|
||||||
@ -532,14 +421,13 @@ public class PdfViewer extends AppCompatActivity implements LoaderManager.Loader
|
|||||||
} else if (itemId == R.id.action_view_document_properties) {
|
} else if (itemId == R.id.action_view_document_properties) {
|
||||||
DocumentPropertiesFragment
|
DocumentPropertiesFragment
|
||||||
.newInstance(mDocumentProperties)
|
.newInstance(mDocumentProperties)
|
||||||
.show(getSupportFragmentManager(), DocumentPropertiesFragment.TAG);
|
.show(activity.getSupportFragmentManager(), DocumentPropertiesFragment.TAG);
|
||||||
return true;
|
return true;
|
||||||
} else if (itemId == R.id.action_jump_to_page) {
|
} else if (itemId == R.id.action_jump_to_page) {
|
||||||
new JumpToPageFragment()
|
JumpToPageFragment.newInstance(this)
|
||||||
.show(getSupportFragmentManager(), JumpToPageFragment.TAG);
|
.show(activity.getSupportFragmentManager(), JumpToPageFragment.TAG);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
return super.onOptionsItemSelected(item);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,15 +20,12 @@ public class JumpToPageFragment extends DialogFragment {
|
|||||||
private final static String STATE_PICKER_MAX = "picker_max";
|
private final static String STATE_PICKER_MAX = "picker_max";
|
||||||
|
|
||||||
private NumberPicker mPicker;
|
private NumberPicker mPicker;
|
||||||
|
PdfViewer pdfViewer;
|
||||||
|
|
||||||
@Override
|
public static JumpToPageFragment newInstance(PdfViewer pdfViewer) {
|
||||||
public void onActivityCreated(Bundle savedInstanceState) {
|
JumpToPageFragment f = new JumpToPageFragment();
|
||||||
super.onActivityCreated(savedInstanceState);
|
f.pdfViewer = pdfViewer;
|
||||||
if (savedInstanceState != null) {
|
return f;
|
||||||
mPicker.setMinValue(savedInstanceState.getInt(STATE_PICKER_MIN));
|
|
||||||
mPicker.setMaxValue(savedInstanceState.getInt(STATE_PICKER_MAX));
|
|
||||||
mPicker.setValue(savedInstanceState.getInt(STATE_PICKER_CUR));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@ -36,8 +33,8 @@ public class JumpToPageFragment extends DialogFragment {
|
|||||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||||
mPicker = new NumberPicker(getActivity());
|
mPicker = new NumberPicker(getActivity());
|
||||||
mPicker.setMinValue(1);
|
mPicker.setMinValue(1);
|
||||||
mPicker.setMaxValue(((PdfViewer)requireActivity()).mNumPages);
|
mPicker.setMaxValue(pdfViewer.mNumPages);
|
||||||
mPicker.setValue(((PdfViewer)requireActivity()).mPage);
|
mPicker.setValue(pdfViewer.mPage);
|
||||||
|
|
||||||
final FrameLayout layout = new FrameLayout(getActivity());
|
final FrameLayout layout = new FrameLayout(getActivity());
|
||||||
layout.addView(mPicker, new FrameLayout.LayoutParams(
|
layout.addView(mPicker, new FrameLayout.LayoutParams(
|
||||||
@ -49,7 +46,7 @@ public class JumpToPageFragment extends DialogFragment {
|
|||||||
.setView(layout)
|
.setView(layout)
|
||||||
.setPositiveButton(android.R.string.ok, (dialogInterface, i) -> {
|
.setPositiveButton(android.R.string.ok, (dialogInterface, i) -> {
|
||||||
mPicker.clearFocus();
|
mPicker.clearFocus();
|
||||||
((PdfViewer)requireActivity()).onJumpToPageInDocument(mPicker.getValue());
|
pdfViewer.onJumpToPageInDocument(mPicker.getValue());
|
||||||
})
|
})
|
||||||
.setNegativeButton(android.R.string.cancel, null)
|
.setNegativeButton(android.R.string.cancel, null)
|
||||||
.create();
|
.create();
|
||||||
|
@ -1,10 +1,7 @@
|
|||||||
package org.grapheneos.pdfviewer.loader;
|
package org.grapheneos.pdfviewer.loader;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.database.Cursor;
|
|
||||||
import android.graphics.Typeface;
|
import android.graphics.Typeface;
|
||||||
import android.net.Uri;
|
|
||||||
import android.provider.OpenableColumns;
|
|
||||||
import android.text.SpannableStringBuilder;
|
import android.text.SpannableStringBuilder;
|
||||||
import android.text.Spanned;
|
import android.text.Spanned;
|
||||||
import android.text.style.StyleSpan;
|
import android.text.style.StyleSpan;
|
||||||
@ -12,6 +9,8 @@ import android.util.Log;
|
|||||||
|
|
||||||
import androidx.loader.content.AsyncTaskLoader;
|
import androidx.loader.content.AsyncTaskLoader;
|
||||||
|
|
||||||
|
import org.grapheneos.pdfviewer.R;
|
||||||
|
import org.grapheneos.pdfviewer.Utils;
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
@ -19,9 +18,6 @@ import java.text.ParseException;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.grapheneos.pdfviewer.R;
|
|
||||||
import org.grapheneos.pdfviewer.Utils;
|
|
||||||
|
|
||||||
public class DocumentPropertiesLoader extends AsyncTaskLoader<List<CharSequence>> {
|
public class DocumentPropertiesLoader extends AsyncTaskLoader<List<CharSequence>> {
|
||||||
public static final String TAG = "DocumentPropertiesLoader";
|
public static final String TAG = "DocumentPropertiesLoader";
|
||||||
|
|
||||||
@ -29,16 +25,17 @@ public class DocumentPropertiesLoader extends AsyncTaskLoader<List<CharSequence>
|
|||||||
|
|
||||||
private final String mProperties;
|
private final String mProperties;
|
||||||
private final int mNumPages;
|
private final int mNumPages;
|
||||||
private final Uri mUri;
|
|
||||||
|
|
||||||
private Cursor mCursor;
|
String fileName;
|
||||||
|
Long fileSize;
|
||||||
|
|
||||||
public DocumentPropertiesLoader(Context context, String properties, int numPages, Uri uri) {
|
public DocumentPropertiesLoader(Context context, String properties, int numPages, String fileName, Long fileSize) {
|
||||||
super(context);
|
super(context);
|
||||||
|
|
||||||
mProperties = properties;
|
mProperties = properties;
|
||||||
mNumPages = numPages;
|
mNumPages = numPages;
|
||||||
mUri = uri;
|
this.fileName = fileName;
|
||||||
|
this.fileSize = fileSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -48,23 +45,8 @@ public class DocumentPropertiesLoader extends AsyncTaskLoader<List<CharSequence>
|
|||||||
final String[] names = context.getResources().getStringArray(R.array.property_names);
|
final String[] names = context.getResources().getStringArray(R.array.property_names);
|
||||||
final List<CharSequence> properties = new ArrayList<>(names.length);
|
final List<CharSequence> properties = new ArrayList<>(names.length);
|
||||||
|
|
||||||
mCursor = context.getContentResolver().query(mUri, null, null, null, null);
|
properties.add(getProperty(null, names[0], fileName));
|
||||||
if (mCursor != null) {
|
|
||||||
mCursor.moveToFirst();
|
|
||||||
|
|
||||||
final int indexName = mCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
|
|
||||||
if (indexName >= 0) {
|
|
||||||
properties.add(getProperty(null, names[0], mCursor.getString(indexName)));
|
|
||||||
}
|
|
||||||
|
|
||||||
final int indexSize = mCursor.getColumnIndex(OpenableColumns.SIZE);
|
|
||||||
if (indexSize >= 0) {
|
|
||||||
final long fileSize = Long.parseLong(mCursor.getString(indexSize));
|
|
||||||
properties.add(getProperty(null, names[1], Utils.parseFileSize(fileSize)));
|
properties.add(getProperty(null, names[1], Utils.parseFileSize(fileSize)));
|
||||||
}
|
|
||||||
|
|
||||||
mCursor.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final JSONObject json = new JSONObject(mProperties);
|
final JSONObject json = new JSONObject(mProperties);
|
||||||
@ -89,9 +71,7 @@ public class DocumentPropertiesLoader extends AsyncTaskLoader<List<CharSequence>
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deliverResult(List<CharSequence> properties) {
|
public void deliverResult(List<CharSequence> properties) {
|
||||||
if (isReset()) {
|
if (!isReset() && isStarted()) {
|
||||||
onReleaseResources();
|
|
||||||
} else if (isStarted()) {
|
|
||||||
super.deliverResult(properties);
|
super.deliverResult(properties);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -106,26 +86,11 @@ public class DocumentPropertiesLoader extends AsyncTaskLoader<List<CharSequence>
|
|||||||
cancelLoad();
|
cancelLoad();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCanceled(List<CharSequence> properties) {
|
|
||||||
super.onCanceled(properties);
|
|
||||||
|
|
||||||
onReleaseResources();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onReset() {
|
protected void onReset() {
|
||||||
super.onReset();
|
super.onReset();
|
||||||
|
|
||||||
onStopLoading();
|
onStopLoading();
|
||||||
onReleaseResources();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void onReleaseResources() {
|
|
||||||
if (mCursor != null) {
|
|
||||||
mCursor.close();
|
|
||||||
mCursor = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private CharSequence getProperty(final JSONObject json, String name, String specName) {
|
private CharSequence getProperty(final JSONObject json, String name, String specName) {
|
||||||
|
Before Width: | Height: | Size: 153 B |
Before Width: | Height: | Size: 133 B |
Before Width: | Height: | Size: 206 B |
Before Width: | Height: | Size: 283 B |
Before Width: | Height: | Size: 372 B |
@ -1,30 +0,0 @@
|
|||||||
<!--
|
|
||||||
Copyright (C) 2021 Google Inc.
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
-->
|
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:width="108dp"
|
|
||||||
android:height="108dp"
|
|
||||||
android:viewportWidth="108"
|
|
||||||
android:viewportHeight="108">
|
|
||||||
<group
|
|
||||||
android:scaleX="2.43375"
|
|
||||||
android:scaleY="2.43375"
|
|
||||||
android:translateX="24.795"
|
|
||||||
android:translateY="24.795">
|
|
||||||
<path
|
|
||||||
android:fillColor="#000000"
|
|
||||||
android:pathData="M18,4L6,4C4.9,4 4,4.9 4,6v12c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2L20,6C20,4.9 19.1,4 18,4ZM9.5,11.5C9.5,12.33 8.83,13 8,13L7,13v1.25C7,14.66 6.66,15 6.25,15 5.84,15 5.5,14.66 5.5,14.25L5.5,10c0,-0.55 0.45,-1 1,-1L8,9c0.83,0 1.5,0.67 1.5,1.5zM14.5,13.5c0,0.83 -0.67,1.5 -1.5,1.5h-2c-0.28,0 -0.5,-0.22 -0.5,-0.5v-5C10.5,9.22 10.72,9 11,9h2c0.83,0 1.5,0.67 1.5,1.5zM18.5,9.75c0,0.41 -0.34,0.75 -0.75,0.75L17,10.5v1h0.75c0.41,0 0.75,0.34 0.75,0.75 0,0.41 -0.34,0.75 -0.75,0.75L17,13v1.25C17,14.66 16.66,15 16.25,15 15.84,15 15.5,14.66 15.5,14.25L15.5,10c0,-0.55 0.45,-1 1,-1h1.25c0.41,0 0.75,0.34 0.75,0.75zM7,11.5h1v-1L7,10.5ZM12,13.5h1v-3h-1z" />
|
|
||||||
</group>
|
|
||||||
</vector>
|
|
@ -1,5 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<WebView xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:id="@+id/webview"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="fill_parent" />
|
|
@ -19,12 +19,6 @@
|
|||||||
android:title="@string/action_next"
|
android:title="@string/action_next"
|
||||||
app:showAsAction="ifRoom" />
|
app:showAsAction="ifRoom" />
|
||||||
|
|
||||||
<item
|
|
||||||
android:id="@+id/action_open"
|
|
||||||
android:icon="@drawable/ic_insert_drive_file_white_24dp"
|
|
||||||
android:title="@string/action_open"
|
|
||||||
app:showAsAction="ifRoom" />
|
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_zoom_out"
|
android:id="@+id/action_zoom_out"
|
||||||
android:icon="@drawable/ic_zoom_out_white_24dp"
|
android:icon="@drawable/ic_zoom_out_white_24dp"
|
||||||
|
@ -1,5 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
<background android:drawable="@color/ic_launcher_background"/>
|
|
||||||
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
|
|
||||||
</adaptive-icon>
|
|
@ -1,5 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
<background android:drawable="@color/ic_launcher_background"/>
|
|
||||||
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
|
|
||||||
</adaptive-icon>
|
|
@ -1,3 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<resources xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
tools:shrinkMode="strict" />
|
|
@ -1,9 +0,0 @@
|
|||||||
<resources>
|
|
||||||
|
|
||||||
<!-- Base application theme. -->
|
|
||||||
<style name="AppTheme" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
|
|
||||||
<!-- Customize your theme here. -->
|
|
||||||
<item name="android:windowBackground">#000000</item>
|
|
||||||
</style>
|
|
||||||
|
|
||||||
</resources>
|
|
@ -1,4 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<resources>
|
|
||||||
<color name="ic_launcher_background">#FFFFFF</color>
|
|
||||||
</resources>
|
|
@ -4,7 +4,6 @@
|
|||||||
<!--<string name="action_settings">Settings</string>-->
|
<!--<string name="action_settings">Settings</string>-->
|
||||||
<string name="action_previous">Previous page</string>
|
<string name="action_previous">Previous page</string>
|
||||||
<string name="action_next">Next page</string>
|
<string name="action_next">Next page</string>
|
||||||
<string name="action_open">Open document</string>
|
|
||||||
<string name="action_first">First page</string>
|
<string name="action_first">First page</string>
|
||||||
<string name="action_last">Last page</string>
|
<string name="action_last">Last page</string>
|
||||||
<string name="action_zoom_out">Zoom out</string>
|
<string name="action_zoom_out">Zoom out</string>
|
||||||
|
@ -1,8 +0,0 @@
|
|||||||
<resources>
|
|
||||||
|
|
||||||
<!-- Base application theme. -->
|
|
||||||
<style name="AppTheme" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
|
|
||||||
<!-- Customize your theme here. -->
|
|
||||||
</style>
|
|
||||||
|
|
||||||
</resources>
|
|