Skip to content

Commit

Permalink
Added "Share PDF file" feature
Browse files Browse the repository at this point in the history
  • Loading branch information
Sav22999 committed Jan 25, 2021
1 parent 93f6557 commit 678df49
Show file tree
Hide file tree
Showing 17 changed files with 274 additions and 24 deletions.
6 changes: 6 additions & 0 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ android {
buildToolsVersion "30.0.2"

defaultConfig {
applicationId "com.saverio.pdfviewer"
applicationId 'com.saverio.pdfviewer'
minSdkVersion 16
targetSdkVersion 30
versionCode 5
versionName "1.0"
versionCode 6
versionName '1.1'

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
Expand Down
3 changes: 3 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@
<activity android:name=".PDFViewer">
<intent-filter>
<action android:name="android.intent.action.VIEW" />

<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.APP_BROWSER" />

<data
android:mimeType="application/pdf"
android:scheme="content" />
Expand All @@ -28,6 +30,7 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

</application>

</manifest>
52 changes: 45 additions & 7 deletions app/src/main/java/com/saverio/pdfviewer/PDFViewer.kt
Original file line number Diff line number Diff line change
@@ -1,26 +1,36 @@
package com.saverio.pdfviewer

import RealPathUtil
import android.app.Activity
import android.content.ContentResolver
import android.content.ContentUris
import android.content.Context
import android.content.Intent
import android.database.Cursor
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.widget.Button
import android.os.Environment
import android.provider.DocumentsContract
import android.provider.MediaStore
import android.widget.ImageView
import android.widget.TextView
import android.widget.Toolbar
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.isGone
import com.github.barteksc.pdfviewer.PDFView
import org.json.JSONObject
import java.lang.Exception
import org.w3c.dom.Text
import java.security.MessageDigest
import java.text.SimpleDateFormat
import java.util.*


class PDFViewer : AppCompatActivity() {
lateinit var pdfViewer: PDFView
val PDF_SELECTION_CODE = 100

var fileOpened: String? = ""
var uriOpened: Uri? = null

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_pdf_viewer)
Expand Down Expand Up @@ -57,11 +67,16 @@ class PDFViewer : AppCompatActivity() {
openFromStorage(Uri.parse(uriToUse))
}

var backButton: ImageView = findViewById(R.id.buttonGoBackToolbar)
val backButton: ImageView = findViewById(R.id.buttonGoBackToolbar)
backButton.setOnClickListener {
updateLastFileOpened("")
finish()
}

val shareButton: ImageView = findViewById(R.id.buttonShareToolbar)
shareButton.setOnClickListener {
setShareButton()
}
}

private fun openFromStorage(uri: Uri? = null) {
Expand Down Expand Up @@ -105,10 +120,20 @@ class PDFViewer : AppCompatActivity() {
val selectedPdf = data.data
selectPdfFromURI(selectedPdf)

val shareButton: ImageView = findViewById(R.id.buttonShareToolbar)
shareButton.isGone = true
uriOpened = selectedPdf
if (uriOpened != null) {
fileOpened = RealPathUtil.getRealPath(this, uriOpened!!)
shareButton.isGone = false
}
val pagesNumber: TextView = findViewById(R.id.totalPagesToolbar)
pagesNumber.isGone = true

//checkRecentFiles(selectedPdf)

updateLastFileOpened(selectedPdf.toString())
setTitle(getTheFileName(selectedPdf.toString(), -1))
//setTitle(getTheFileName(selectedPdf.toString(), -1))
} else {
//file not selected
finish()
Expand Down Expand Up @@ -139,6 +164,7 @@ class PDFViewer : AppCompatActivity() {

val totalPages: TextView = findViewById(R.id.totalPagesToolbar)
totalPages.text = "#" + (currentPage + 1).toString()
totalPages.isGone = false
}

private fun getPdfPage(pathName: String): Int {
Expand Down Expand Up @@ -261,7 +287,7 @@ class PDFViewer : AppCompatActivity() {
).getString("last_opened_file", "")
}

fun updateLastFileOpened(uri: String) {
fun updateLastFileOpened(uri: String?) {
getSharedPreferences("last_opened_file", Context.MODE_PRIVATE).edit()
.putString("last_opened_file", uri).apply()
}
Expand All @@ -274,4 +300,16 @@ class PDFViewer : AppCompatActivity() {
fun ByteArray.toHex(): String {
return joinToString("") { "%02x".format(it) }
}

fun setShareButton() {
intent.getStringExtra("iName")
val shareIntent = Intent(Intent.ACTION_SEND)
shareIntent.putExtra(
Intent.EXTRA_STREAM,
uriOpened
)
shareIntent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
shareIntent.type = "application/pdf"
startActivity(Intent.createChooser(shareIntent, "Share"))
}
}
177 changes: 177 additions & 0 deletions app/src/main/java/com/saverio/pdfviewer/RealPathUtil.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
import android.annotation.SuppressLint
import android.content.ContentUris
import android.content.Context
import android.content.CursorLoader
import android.database.Cursor
import android.net.Uri
import android.os.Build
import android.os.Environment
import android.provider.DocumentsContract
import android.provider.MediaStore
import android.text.TextUtils

object RealPathUtil {

fun getRealPath(context: Context, fileUri: Uri): String? {
// SDK >= 11 && SDK < 19
return if (Build.VERSION.SDK_INT < 19) {
getRealPathFromURIAPI11to18(context, fileUri)
} else {
getRealPathFromURIAPI19(context, fileUri)
}// SDK > 19 (Android 4.4) and up
}

@SuppressLint("NewApi")
fun getRealPathFromURIAPI11to18(context: Context, contentUri: Uri): String? {
val proj = arrayOf(MediaStore.Images.Media.DATA)
var result: String? = null

val cursorLoader = CursorLoader(context, contentUri, proj, null, null, null)
val cursor = cursorLoader.loadInBackground()

if (cursor != null) {
val columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA)
cursor.moveToFirst()
result = cursor.getString(columnIndex)
cursor.close()
}
return result
}

/**
* Get a file path from a Uri. This will get the the path for Storage Access
* Framework Documents, as well as the _data field for the MediaStore and
* other file-based ContentProviders.
*
* @param context The context.
* @param uri The Uri to query.
* @author Niks
*/
@SuppressLint("NewApi")
fun getRealPathFromURIAPI19(context: Context, uri: Uri): String? {

val isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT

// DocumentProvider
if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
// ExternalStorageProvider
if (isExternalStorageDocument(uri)) {
val docId = DocumentsContract.getDocumentId(uri)
val split = docId.split(":".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
val type = split[0]

if ("primary".equals(type, ignoreCase = true)) {
return Environment.getExternalStorageDirectory().toString() + "/" + split[1]
}
} else if (isDownloadsDocument(uri)) {
var cursor: Cursor? = null
try {
cursor = context.contentResolver.query(uri, arrayOf(MediaStore.MediaColumns.DISPLAY_NAME), null, null, null)
cursor!!.moveToNext()
val fileName = cursor.getString(0)
val path = Environment.getExternalStorageDirectory().toString() + "/Download/" + fileName
if (!TextUtils.isEmpty(path)) {
return path
}
} finally {
cursor?.close()
}
val id = DocumentsContract.getDocumentId(uri)
if (id.startsWith("raw:")) {
return id.replaceFirst("raw:".toRegex(), "")
}
val contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads"), java.lang.Long.valueOf(id))

return getDataColumn(context, contentUri, null, null)
} else if (isMediaDocument(uri)) {
val docId = DocumentsContract.getDocumentId(uri)
val split = docId.split(":".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
val type = split[0]

var contentUri: Uri? = null
when (type) {
"image" -> contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
"video" -> contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI
"audio" -> contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
}

val selection = "_id=?"
val selectionArgs = arrayOf(split[1])

return getDataColumn(context, contentUri, selection, selectionArgs)
}// MediaProvider
// DownloadsProvider
} else if ("content".equals(uri.scheme!!, ignoreCase = true)) {

// Return the remote address
return if (isGooglePhotosUri(uri)) uri.lastPathSegment else getDataColumn(context, uri, null, null)
} else if ("file".equals(uri.scheme!!, ignoreCase = true)) {
return uri.path
}// File
// MediaStore (and general)

return null
}

/**
* Get the value of the data column for this Uri. This is useful for
* MediaStore Uris, and other file-based ContentProviders.
*
* @param context The context.
* @param uri The Uri to query.
* @param selection (Optional) Filter used in the query.
* @param selectionArgs (Optional) Selection arguments used in the query.
* @return The value of the _data column, which is typically a file path.
* @author Niks
*/
private fun getDataColumn(context: Context, uri: Uri?, selection: String?,
selectionArgs: Array<String>?): String? {

var cursor: Cursor? = null
val column = "_data"
val projection = arrayOf(column)

try {
cursor = context.contentResolver.query(uri!!, projection, selection, selectionArgs, null)
if (cursor != null && cursor.moveToFirst()) {
val index = cursor.getColumnIndexOrThrow(column)
return cursor.getString(index)
}
} finally {
cursor?.close()
}
return null
}

/**
* @param uri The Uri to check.
* @return Whether the Uri authority is ExternalStorageProvider.
*/
private fun isExternalStorageDocument(uri: Uri): Boolean {
return "com.android.externalstorage.documents" == uri.authority
}

/**
* @param uri The Uri to check.
* @return Whether the Uri authority is DownloadsProvider.
*/
private fun isDownloadsDocument(uri: Uri): Boolean {
return "com.android.providers.downloads.documents" == uri.authority
}

/**
* @param uri The Uri to check.
* @return Whether the Uri authority is MediaProvider.
*/
private fun isMediaDocument(uri: Uri): Boolean {
return "com.android.providers.media.documents" == uri.authority
}

/**
* @param uri The Uri to check.
* @return Whether the Uri authority is Google Photos.
*/
private fun isGooglePhotosUri(uri: Uri): Boolean {
return "com.google.android.apps.photos.content" == uri.authority
}
}
Loading

0 comments on commit 678df49

Please sign in to comment.