Skip to content

Commit 4f453b4

Browse files
committed
Add kotlin support, add share option
1 parent 8c82e2e commit 4f453b4

14 files changed

+542
-0
lines changed

build.gradle

+9
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
buildscript {
2+
repositories {
3+
google()
4+
mavenCentral()
5+
}
6+
dependencies {
7+
classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.8.0'
8+
}
9+
}
110
plugins {
211
id 'com.android.application' version '7.3.1' apply false
312
id 'com.android.library' version '7.3.1' apply false

lib/build.gradle

+3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
apply plugin: 'com.android.library'
22
apply plugin: 'maven-publish'
3+
apply plugin: 'org.jetbrains.kotlin.android'
34

45
group = 'com.artifex.mupdf'
56
version = '1.21.0a'
@@ -8,6 +9,8 @@ dependencies {
89
implementation 'androidx.appcompat:appcompat:1.3.1'
910
implementation 'com.google.android.material:material:1.6.1'
1011
api 'com.github.TeamAmaze:mupdf-android-fitz:1.0.1'
12+
implementation 'androidx.core:core:1.7.0'
13+
implementation 'androidx.core:core-ktx:1.7.0'
1114
}
1215

1316
android {

lib/src/main/AndroidManifest.xml

+2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
package="com.artifex.mupdf.viewer"
44
>
55
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
6+
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
7+
68
<application
79
android:theme="@style/Theme.Custom.Activity">
810
<activity

lib/src/main/java/com/artifex/mupdf/viewer/DocumentActivity.java

+17
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,21 @@
4040
import androidx.annotation.NonNull;
4141
import androidx.appcompat.view.ContextThemeWrapper;
4242
import androidx.appcompat.widget.PopupMenu;
43+
import androidx.core.content.FileProvider;
4344
import androidx.core.content.res.ResourcesCompat;
4445

4546
import com.artifex.mupdf.fitz.SeekableInputStream;
47+
import com.artifex.mupdf.viewer.share.ShareAdapter;
48+
import com.artifex.mupdf.viewer.share.ShareUtilsKt;
4649
import com.google.android.material.slider.Slider;
4750

51+
import java.io.File;
4852
import java.io.IOException;
4953
import java.io.InputStream;
5054
import java.util.ArrayList;
55+
import java.util.List;
5156
import java.util.Locale;
57+
import java.util.concurrent.Callable;
5258

5359
public class DocumentActivity extends Activity
5460
{
@@ -90,6 +96,7 @@ enum TopBarMode {Main, Search, More};
9096
private AlertDialog mAlertDialog;
9197
private ArrayList<OutlineActivity.Item> mFlatOutline;
9298
private boolean mReturnToLibraryActivity = false;
99+
private Uri intentUri;
93100

94101
protected int mDisplayDPI;
95102
private int mLayoutEM = 10;
@@ -210,6 +217,7 @@ public void onCreate(final Bundle savedInstanceState)
210217
if (Intent.ACTION_VIEW.equals(intent.getAction())
211218
|| Intent.ACTION_SEND.equals(intent.getAction())) {
212219
Uri uri = intent.getData();
220+
this.intentUri = uri;
213221
String mimetype = getIntent().getType();
214222
if (uri == null) {
215223
uri = intent.getParcelableExtra(Intent.EXTRA_STREAM);
@@ -830,6 +838,15 @@ R.drawable.background_curved_dark_2, getTheme()
830838
item.setChecked(mLinkHighlight);
831839
} else if (item.getItemId() == R.id.text_size) {
832840
mLayoutPopupMenu.show();
841+
} else if (item.getItemId() == R.id.share) {
842+
if (intentUri != null) {
843+
List<Uri> intentUriList = new ArrayList<>();
844+
intentUriList.add(intentUri);
845+
ShareAdapter shareAdapter = ShareUtilsKt.getShareIntents(intentUriList,
846+
this);
847+
ShareUtilsKt.showShareDialog(this, getLayoutInflater(), shareAdapter);
848+
}
849+
833850
}
834851
return true;
835852
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
/*
2+
* Copyright (C) 2021-2023 Arpit Khurana <arpitkh96@gmail.com>, Vishal Nehra <vishalmeham2@gmail.com>,
3+
* Emmanuel Messulam<emmanuelbendavid@gmail.com>, Raymond Lai <airwave209gt at gmail.com> and Contributors.
4+
*
5+
* This file is part of Amaze File Utilities.
6+
*
7+
* Amaze File Utilities is free software: you can redistribute it and/or modify
8+
* it under the terms of the GNU General Public License as published by
9+
* the Free Software Foundation, either version 3 of the License, or
10+
* (at your option) any later version.
11+
*
12+
* This program is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU General Public License
18+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
19+
*/
20+
21+
package com.artifex.mupdf.viewer.share;
22+
23+
import android.webkit.MimeTypeMap;
24+
25+
import androidx.annotation.Nullable;
26+
27+
import java.util.HashMap;
28+
import java.util.Locale;
29+
import java.util.regex.Pattern;
30+
31+
public final class MimeTypes {
32+
33+
public static final String ALL_MIME_TYPES = "*/*";
34+
35+
// construct a with an approximation of the capacity
36+
private static final HashMap<String, String> MIME_TYPES = new HashMap<>(1 + (int) (68 / 0.75));
37+
38+
static {
39+
40+
/*
41+
* ================= MIME TYPES ====================
42+
*/
43+
MIME_TYPES.put("asm", "text/x-asm");
44+
MIME_TYPES.put("json", "application/json");
45+
MIME_TYPES.put("js", "application/javascript");
46+
47+
MIME_TYPES.put("def", "text/plain");
48+
MIME_TYPES.put("in", "text/plain");
49+
MIME_TYPES.put("rc", "text/plain");
50+
MIME_TYPES.put("list", "text/plain");
51+
MIME_TYPES.put("log", "text/plain");
52+
MIME_TYPES.put("pl", "text/plain");
53+
MIME_TYPES.put("prop", "text/plain");
54+
MIME_TYPES.put("properties", "text/plain");
55+
MIME_TYPES.put("ini", "text/plain");
56+
MIME_TYPES.put("md", "text/markdown");
57+
58+
MIME_TYPES.put("epub", "application/epub+zip");
59+
MIME_TYPES.put("ibooks", "application/x-ibooks+zip");
60+
61+
MIME_TYPES.put("ifb", "text/calendar");
62+
MIME_TYPES.put("eml", "message/rfc822");
63+
MIME_TYPES.put("msg", "application/vnd.ms-outlook");
64+
65+
MIME_TYPES.put("ace", "application/x-ace-compressed");
66+
MIME_TYPES.put("bz", "application/x-bzip");
67+
MIME_TYPES.put("bz2", "application/x-bzip2");
68+
MIME_TYPES.put("cab", "application/vnd.ms-cab-compressed");
69+
MIME_TYPES.put("gz", "application/x-gzip");
70+
MIME_TYPES.put("7z", "application/x-7z-compressed");
71+
MIME_TYPES.put("lrf", "application/octet-stream");
72+
MIME_TYPES.put("jar", "application/java-archive");
73+
MIME_TYPES.put("xz", "application/x-xz");
74+
MIME_TYPES.put("lzma", "application/x-lzma");
75+
MIME_TYPES.put("Z", "application/x-compress");
76+
77+
MIME_TYPES.put("bat", "application/x-msdownload");
78+
MIME_TYPES.put("ksh", "text/plain");
79+
MIME_TYPES.put("sh", "application/x-sh");
80+
81+
MIME_TYPES.put("db", "application/octet-stream");
82+
MIME_TYPES.put("db3", "application/octet-stream");
83+
84+
MIME_TYPES.put("otf", "application/x-font-otf");
85+
MIME_TYPES.put("ttf", "application/x-font-ttf");
86+
MIME_TYPES.put("psf", "application/x-font-linux-psf");
87+
88+
MIME_TYPES.put("cgm", "image/cgm");
89+
MIME_TYPES.put("btif", "image/prs.btif");
90+
MIME_TYPES.put("dwg", "image/vnd.dwg");
91+
MIME_TYPES.put("dxf", "image/vnd.dxf");
92+
MIME_TYPES.put("fbs", "image/vnd.fastbidsheet");
93+
MIME_TYPES.put("fpx", "image/vnd.fpx");
94+
MIME_TYPES.put("fst", "image/vnd.fst");
95+
MIME_TYPES.put("mdi", "image/vnd.ms-mdi");
96+
MIME_TYPES.put("npx", "image/vnd.net-fpx");
97+
MIME_TYPES.put("xif", "image/vnd.xiff");
98+
MIME_TYPES.put("pct", "image/x-pict");
99+
MIME_TYPES.put("pic", "image/x-pict");
100+
MIME_TYPES.put("gif", "image/gif");
101+
102+
MIME_TYPES.put("adp", "audio/adpcm");
103+
MIME_TYPES.put("au", "audio/basic");
104+
MIME_TYPES.put("snd", "audio/basic");
105+
MIME_TYPES.put("m2a", "audio/mpeg");
106+
MIME_TYPES.put("m3a", "audio/mpeg");
107+
MIME_TYPES.put("oga", "audio/ogg");
108+
MIME_TYPES.put("spx", "audio/ogg");
109+
MIME_TYPES.put("aac", "audio/x-aac");
110+
MIME_TYPES.put("mka", "audio/x-matroska");
111+
MIME_TYPES.put("opus", "audio/ogg");
112+
113+
MIME_TYPES.put("jpgv", "video/jpeg");
114+
MIME_TYPES.put("jpgm", "video/jpm");
115+
MIME_TYPES.put("jpm", "video/jpm");
116+
MIME_TYPES.put("mj2", "video/mj2");
117+
MIME_TYPES.put("mjp2", "video/mj2");
118+
MIME_TYPES.put("mpa", "video/mpeg");
119+
MIME_TYPES.put("ogv", "video/ogg");
120+
MIME_TYPES.put("flv", "video/x-flv");
121+
MIME_TYPES.put("mkv", "video/x-matroska");
122+
MIME_TYPES.put("mts", "video/mp2t");
123+
}
124+
125+
/**
126+
* Get Mime Type of a file
127+
*
128+
* @param path the file of which mime type to get
129+
* @return Mime type in form of String
130+
*/
131+
public static String getMimeType(String path, boolean isDirectory) {
132+
if (isDirectory) {
133+
return null;
134+
}
135+
136+
String type = ALL_MIME_TYPES;
137+
final String extension = getExtension(path);
138+
139+
// mapping extension to system mime types
140+
if (extension != null && !extension.isEmpty()) {
141+
final String extensionLowerCase = extension.toLowerCase(Locale.getDefault());
142+
final MimeTypeMap mime = MimeTypeMap.getSingleton();
143+
type = mime.getMimeTypeFromExtension(extensionLowerCase);
144+
if (type == null) {
145+
type = MIME_TYPES.get(extensionLowerCase);
146+
}
147+
}
148+
if (type == null) type = ALL_MIME_TYPES;
149+
return type;
150+
}
151+
152+
public static boolean mimeTypeMatch(String mime, String input) {
153+
return Pattern.matches(mime.replace("*", ".*"), input);
154+
}
155+
156+
/**
157+
* Helper method for {@link #getMimeType(String, boolean)} to calculate the last '.' extension of
158+
* files
159+
*
160+
* @param path the path of file
161+
* @return extension extracted from name in lowercase
162+
*/
163+
public static String getExtension(@Nullable String path) {
164+
if (path != null && path.contains("."))
165+
return path.substring(path.lastIndexOf(".") + 1).toLowerCase();
166+
else return "";
167+
}
168+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/*
2+
* Copyright (C) 2021-2023 Arpit Khurana <arpitkh96@gmail.com>, Vishal Nehra <vishalmeham2@gmail.com>,
3+
* Emmanuel Messulam<emmanuelbendavid@gmail.com>, Raymond Lai <airwave209gt at gmail.com> and Contributors.
4+
*
5+
* This file is part of Amaze File Utilities.
6+
*
7+
* Amaze File Utilities is free software: you can redistribute it and/or modify
8+
* it under the terms of the GNU General Public License as published by
9+
* the Free Software Foundation, either version 3 of the License, or
10+
* (at your option) any later version.
11+
*
12+
* This program is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU General Public License
18+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
19+
*/
20+
21+
package com.artifex.mupdf.viewer.share
22+
23+
import android.content.Context
24+
import android.content.Intent
25+
import android.graphics.drawable.Drawable
26+
import android.view.LayoutInflater
27+
import android.view.View
28+
import android.view.ViewGroup
29+
import android.widget.ImageView
30+
import android.widget.TextView
31+
import androidx.recyclerview.widget.RecyclerView
32+
import com.artifex.mupdf.viewer.R
33+
34+
class ShareAdapter(
35+
val context: Context,
36+
private val intents: List<Intent>,
37+
private val labels: List<String>,
38+
private val drawables: List<Drawable>
39+
) : RecyclerView.Adapter<ShareAdapter.ViewHolder>() {
40+
41+
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
42+
val view: View =
43+
LayoutInflater.from(parent.context).inflate(R.layout.share_adapter_list, parent, false)
44+
return ViewHolder(view)
45+
}
46+
47+
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
48+
holder.run {
49+
imageView.setImageDrawable(drawables[position])
50+
textView.visibility = View.VISIBLE
51+
textView.text = labels[position]
52+
rootView.setOnClickListener {
53+
context.startActivity(intents[position])
54+
}
55+
}
56+
}
57+
58+
class ViewHolder(val rootView: View) : RecyclerView.ViewHolder(
59+
rootView
60+
) {
61+
62+
@JvmField
63+
val textView: TextView = rootView.findViewById(R.id.firstline)
64+
65+
@JvmField
66+
val imageView: ImageView = rootView.findViewById(R.id.icon)
67+
}
68+
69+
override fun getItemId(position: Int): Long {
70+
return position.toLong()
71+
}
72+
73+
override fun getItemCount(): Int {
74+
return intents.size
75+
}
76+
}

0 commit comments

Comments
 (0)