Skip to content

Commit

Permalink
root detection and rate fragment
Browse files Browse the repository at this point in the history
  • Loading branch information
crazy committed Feb 6, 2019
1 parent 1c146bc commit 5815d33
Show file tree
Hide file tree
Showing 6 changed files with 262 additions and 5 deletions.
4 changes: 2 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
ext.kotlin_version = '1.3.20'
ext.kotlin_version = '1.3.21'
repositories {
google()
jcenter()

}
dependencies {
classpath 'com.android.tools.build:gradle:3.3.0'
classpath 'com.android.tools.build:gradle:3.3.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
Expand Down
3 changes: 2 additions & 1 deletion kotlinextensions/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,9 @@ dependencies {
implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'
implementation 'com.squareup.okhttp3:logging-interceptor:3.9.1'
implementation 'io.reactivex.rxjava2:rxkotlin:2.2.0'
implementation 'io.reactivex.rxjava2:rxkotlin:2.3.0'
implementation 'com.jakewharton.rxbinding2:rxbinding-kotlin:2.2.0'
implementation 'androidx.core:core-ktx:1.0.1'

// glide
kapt 'com.github.bumptech.glide:compiler:4.8.0'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ import android.content.Intent
import android.net.Uri
import android.view.View
import android.view.inputmethod.InputMethodManager
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import java.io.File
import java.io.BufferedReader
import java.io.InputStreamReader


/**
Expand Down Expand Up @@ -79,4 +81,34 @@ fun Context.openWebPage(url: String) {
longToast("No application can handle this request. Please install a web browser or check your URL.")
e.printStackTrace()
}
}
}

fun Context.sendEmail(myEmail:String, subject:String, text:String) {
val i = Intent(Intent.ACTION_SEND)
i.type = "message/rfc822"
i.putExtra(Intent.EXTRA_EMAIL, arrayOf(myEmail))
i.putExtra(Intent.EXTRA_TEXT, text)
i.putExtra(Intent.EXTRA_SUBJECT, subject)

try {
startActivity(Intent.createChooser(i, "Send e-mail..."))
} catch (ex: android.content.ActivityNotFoundException) {
shortToast("There are no email clients installed.")
}
}

fun Context.sendEmail(emails:Array<String>, subject:String, text:String) {
val i = Intent(Intent.ACTION_SEND)
i.type = "message/rfc822"
i.putExtra(Intent.EXTRA_EMAIL, emails)
i.putExtra(Intent.EXTRA_TEXT, text)
i.putExtra(Intent.EXTRA_SUBJECT, subject)

try {
startActivity(Intent.createChooser(i, "Send e-mail..."))
} catch (ex: android.content.ActivityNotFoundException) {
shortToast("There are no email clients installed.")
}
}


Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package com.crazylegend.kotlinextensions.root

import java.io.BufferedReader
import java.io.File
import java.io.InputStreamReader


/**
* Created by crazy on 2/6/19 to long live and prosper !
*/

object RootUtils {

val isDeviceRooted: Boolean
get() = checkRootMethod1() || checkRootMethod2() || checkRootMethod3()

private fun checkRootMethod1(): Boolean {
val buildTags = android.os.Build.TAGS
return buildTags != null && buildTags.contains("test-keys")
}

private fun checkRootMethod2(): Boolean {
val paths = arrayOf(
"/system/app/Superuser.apk",
"/sbin/su",
"/system/bin/su",
"/system/xbin/su",
"/data/local/xbin/su",
"/data/local/bin/su",
"/system/sd/xbin/su",
"/system/bin/failsafe/su",
"/data/local/su",
"/su/bin/su"
)
for (path in paths) {
if (File(path).exists()) return true
}
return false
}

private fun checkRootMethod3(): Boolean {
var process: Process? = null
return try {
process = Runtime.getRuntime().exec(arrayOf("/system/xbin/which", "su"))
val bufferedReader = BufferedReader(InputStreamReader(process!!.inputStream))
bufferedReader.readLine() != null
} catch (t: Throwable) {
false
} finally {
process?.destroy()
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package com.crazylegend.kotlinextensions.root

import java.io.BufferedReader
import java.io.File
import java.io.InputStreamReader


/**
* Created by crazy on 2/6/19 to long live and prosper !
*/



fun isRooted(): Boolean {

// get from build info
val buildTags = android.os.Build.TAGS
if (buildTags != null && buildTags.contains("test-keys")) {
return true
}

// check if /system/app/Superuser.apk is present
try {
val file = File("/system/app/Superuser.apk")
if (file.exists()) {
return true
}
} catch (e1: Exception) {
// ignore
}

// try executing commands
return (canExecuteCommand("/system/xbin/which su")
|| canExecuteCommand("/system/bin/which su") || canExecuteCommand("which su"))
}

// executes a command on the system
private fun canExecuteCommand(command: String): Boolean {
return try {
Runtime.getRuntime().exec(command)
true
} catch (e: Exception) {
false
}
}

fun isRootAvailable(): Boolean {
for (pathDir in System.getenv("PATH")!!.split(":".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()) {
if (File(pathDir, "su").exists()) {
return true
}
}
return false
}

fun isRootGiven(): Boolean {
if (isRootAvailable()) {
var process: Process? = null
try {
process = Runtime.getRuntime().exec(arrayOf("su", "-c", "id"))
val bufferedReader = BufferedReader(InputStreamReader(process!!.inputStream))
val output = bufferedReader.readLine()
if (output != null && output.toLowerCase().contains("uid=0"))
return true
} catch (e: Exception) {
e.printStackTrace()
} finally {
process?.destroy()
}
}

return false
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package com.crazylegend.kotlinextensions.view

import android.app.Dialog
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.content.SharedPreferences
import android.net.Uri
import androidx.appcompat.app.AlertDialog
import androidx.core.content.edit
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.FragmentManager
import com.crazylegend.kotlinextensions.R


/**
* Created by crazy on 2/6/19 to long live and prosper !
*/
class RateItDialogFragment : DialogFragment() {


override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return AlertDialog.Builder(requireActivity())
.setTitle("Rate us ?")
.setMessage("If you're enjoying this application, kindly give us a rate and support us.")
.setPositiveButton("Rate us") { _, _ ->
startActivity(
Intent(
Intent.ACTION_VIEW,
Uri.parse("market://details?id=" + requireActivity().packageName)
)
)

getSharedPreferences(requireActivity()).edit(true) {
this.putBoolean(DISABLED, true)
}
dismiss()
}
.setNeutralButton(
"Remind Me later"
) { _, _ -> dismiss() }
.setNegativeButton("Don't show again") { _, _ ->
getSharedPreferences(requireActivity()).edit(true) {
this.putBoolean(DISABLED, true)
}
dismiss()
}.create()
}

companion object {
private const val LAUNCHES_UNTIL_PROMPT = 10
private const val DAYS_UNTIL_PROMPT = 3
private const val MILLIS_UNTIL_PROMPT = DAYS_UNTIL_PROMPT * 24 * 60 * 60 * 1000
private const val PREF_NAME = "APP_RATER"
private const val LAST_PROMPT = "LAST_PROMPT"
private const val LAUNCHES = "LAUNCHES"
private const val DISABLED = "DISABLED"

fun show(context: Context, fragmentManager: FragmentManager) {
var shouldShow = false
val sharedPreferences = getSharedPreferences(context)
val currentTime = System.currentTimeMillis()
var lastPromptTime = sharedPreferences.getLong(LAST_PROMPT, 0)
if (lastPromptTime == 0L) {
lastPromptTime = currentTime
sharedPreferences.edit(true) {
this.putLong(LAST_PROMPT, lastPromptTime)
}
}

if (!sharedPreferences.getBoolean(DISABLED, false)) {
val launches = sharedPreferences.getInt(LAUNCHES, 0) + 1
if (launches > LAUNCHES_UNTIL_PROMPT) {
if (currentTime > lastPromptTime + MILLIS_UNTIL_PROMPT) {
shouldShow = true
}
}
sharedPreferences.edit(true) {
this.putInt(LAUNCHES, launches)
}
}

if (shouldShow) {


sharedPreferences.edit(true) {
this.putInt(LAUNCHES, 0).putLong(LAST_PROMPT, System.currentTimeMillis()).apply()
}
RateItDialogFragment().show(fragmentManager, null)

}
}

private fun getSharedPreferences(context: Context): SharedPreferences {
return context.getSharedPreferences(PREF_NAME, 0)
}
}
}

0 comments on commit 5815d33

Please sign in to comment.