Compare commits

..

No commits in common. "android" and "1.0" have entirely different histories.
android ... 1.0

41 changed files with 158 additions and 413 deletions

1
.gitattributes vendored Normal file
View file

@ -0,0 +1 @@
*.webp filter=lfs diff=lfs merge=lfs -text

10
.gitignore vendored
View file

@ -1,7 +1,12 @@
*.iml
/.gradle
.gradle
/local.properties
/.idea
/.idea/caches
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/assetWizardSettings.xml
.DS_Store
/build
/captures
@ -9,4 +14,3 @@
.cxx
local.properties
*:Zone.Identifier
app/release/

3
.idea/.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
# Default ignored files
/shelf/
/workspace.xml

6
.idea/compiler.xml Normal file
View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<bytecodeTargetLevel target="11" />
</component>
</project>

View file

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="deploymentTargetDropDown">
<targetSelectedWithDropDown>
<Target>
<type value="QUICK_BOOT_TARGET" />
<deviceKey>
<Key>
<type value="VIRTUAL_DEVICE_PATH" />
<value value="C:\Users\anri\.android\avd\Mi_Note_10_Lite_API_30.avd" />
</Key>
</deviceKey>
</Target>
</targetSelectedWithDropDown>
<timeTargetWasSelectedWithDropDown value="2021-09-02T10:40:03.136810500Z" />
</component>
</project>

20
.idea/gradle.xml Normal file
View file

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleMigrationSettings" migrationVersion="1" />
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="testRunner" value="GRADLE" />
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" />
</set>
</option>
<option name="resolveModulePerSourceSet" value="false" />
</GradleProjectSettings>
</option>
</component>
</project>

View file

@ -0,0 +1,6 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="AndroidElementNotAllowed" enabled="false" level="WARNING" enabled_by_default="false" />
</profile>
</component>

34
.idea/misc.xml Normal file
View file

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DesignSurface">
<option name="filePathToZoomLevelMap">
<map>
<entry key="..\:/Users/anri/AndroidStudioProjects/MobiDL/app/src/main/res/drawable-v24/ic_launcher_foreground.xml" value="0.3402777777777778" />
<entry key="..\:/Users/anri/AndroidStudioProjects/MobiDL/app/src/main/res/drawable/ic_launcher_background.xml" value="0.3402777777777778" />
<entry key="..\:/Users/anri/AndroidStudioProjects/MobiDL/app/src/main/res/drawable/ic_launcher_foreground_test.xml" value="0.3402777777777778" />
<entry key="..\:/Users/anri/AndroidStudioProjects/MobiDL/app/src/main/res/drawable/ic_plus.xml" value="0.20337837837837838" />
<entry key="..\:/Users/anri/AndroidStudioProjects/MobiDL/app/src/main/res/drawable/ic_return.xml" value="0.3402777777777778" />
<entry key="..\:/Users/anri/AndroidStudioProjects/MobiDL/app/src/main/res/drawable/ic_settings.xml" value="0.3402777777777778" />
<entry key="..\:/Users/anri/AndroidStudioProjects/MobiDL/app/src/main/res/drawable/shadow.xml" value="0.3277777777777778" />
<entry key="..\:/Users/anri/AndroidStudioProjects/MobiDL/app/src/main/res/layout/activity_app_infos.xml" value="0.33" />
<entry key="..\:/Users/anri/AndroidStudioProjects/MobiDL/app/src/main/res/layout/activity_app_list.xml" value="0.3015625" />
<entry key="..\:/Users/anri/AndroidStudioProjects/MobiDL/app/src/main/res/layout/activity_login.xml" value="0.25" />
<entry key="..\:/Users/anri/AndroidStudioProjects/MobiDL/app/src/main/res/layout/activity_main.xml" value="0.22" />
<entry key="..\:/Users/anri/AndroidStudioProjects/MobiDL/app/src/main/res/layout/activity_settings.xml" value="0.25" />
<entry key="..\:/Users/anri/AndroidStudioProjects/MobiDL/app/src/main/res/layout/activity_showInfos.xml" value="0.2171875" />
<entry key="..\:/Users/anri/AndroidStudioProjects/MobiDL/app/src/main/res/layout/list_item_view.xml" value="0.29739583333333336" />
<entry key="..\:/Users/anri/AndroidStudioProjects/MobiDL/app/src/main/res/layout/list_item_view_app_download.xml" value="0.228125" />
<entry key="..\:/Users/anri/AndroidStudioProjects/MobiDL/app/src/main/res/layout/list_item_view_app_list.xml" value="0.25729166666666664" />
<entry key="..\:/Users/anri/AndroidStudioProjects/MobiDL/app/src/main/res/menu/menu_main.xml" value="0.33" />
<entry key="..\:/Users/anri/AndroidStudioProjects/MobiDL/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml" value="0.3402777777777778" />
<entry key="..\:/Users/anri/AndroidStudioProjects/MobiDL/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml" value="0.3402777777777778" />
</map>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="Android Studio default JDK" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>

6
.idea/vcs.xml Normal file
View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

View file

@ -1,12 +1,4 @@
# MobiDL
## Disclaimer
This branch corresponds to the scraper written in Kotlin *for Android*, check [this branch](https://git.kennel.ml/Anri/mobilismScrap/src/branch/python) for the one written in Python.<br>
# Disclaimer
This branch corresponds to the scraper written in Kotlin *for Android*, check [this branch](https://gitlab.com/Mylloon/mobilismScrap/-/tree/python) for the one written in Python.
## Download
You can download the app in the [release page](https://git.kennel.ml/Anri/mobilismScrap/releases).
Application compatible with Android 12.
### Requirements
Minimum: Android 6.0 (Marshmallow) <br>
Recommended: Android 8.0 (Oreo)
Using Git LFS for the `.webp` files

View file

@ -11,7 +11,7 @@ android {
minSdk 23
targetSdk 31
versionCode 1
versionName "1.2.2"
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
@ -32,12 +32,11 @@ android {
}
dependencies {
implementation 'androidx.core:core-ktx:1.7.0'
implementation 'androidx.appcompat:appcompat:1.4.1'
implementation 'com.google.android.material:material:1.5.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
implementation 'androidx.core:core-ktx:1.6.0'
implementation 'androidx.appcompat:appcompat:1.3.1'
implementation 'com.google.android.material:material:1.4.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.0'
implementation 'com.github.kittinunf.fuel:fuel:2.3.1'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.1'
implementation 'com.google.code.gson:gson:2.8.6'
implementation 'androidx.work:work-runtime-ktx:2.7.1'
}

View file

@ -1,11 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.mylloon.mobidl" >
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"
tools:ignore="QueryAllPackagesPermission" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<application
android:allowBackup="true"
@ -27,16 +23,6 @@
<meta-data
android:name="preloaded_fonts"
android:resource="@array/preloaded_fonts" />
<receiver
android:name="BootReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
</application>
</manifest>

View file

@ -1,4 +0,0 @@
{
"tiktok": "musically",
"twitch livestream multiplayer": "twitch"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

View file

@ -4,7 +4,6 @@ package com.mylloon.mobidl
import android.Manifest
import android.annotation.SuppressLint
import android.app.AlertDialog
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
@ -17,73 +16,18 @@ import android.os.Looper
import android.text.Editable
import android.text.InputType
import android.text.TextWatcher
import android.text.method.ScrollingMovementMethod
import android.util.DisplayMetrics
import android.view.*
import android.widget.*
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.work.*
import com.google.android.material.floatingactionbutton.FloatingActionButton
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import kotlinx.coroutines.*
import java.util.*
import java.util.concurrent.ExecutionException
import java.util.concurrent.TimeUnit
private fun isWorkScheduled(context: Context): Boolean {
val instance = WorkManager.getInstance(context)
val statuses = instance.getWorkInfosByTag("com.mylloon.mobidl.BackgroundUpdateCheck")
return try {
var running = false
val workInfoList = statuses.get()
for (workInfo in workInfoList) {
val state = workInfo.state
running = (state == WorkInfo.State.RUNNING) or (state == WorkInfo.State.ENQUEUED)
}
running
} catch (e: ExecutionException) {
e.printStackTrace()
println("No job already running")
false
} catch (e: InterruptedException) {
e.printStackTrace()
println("No job already running")
false
}
}
fun newJob(context: Context) {
val myConstraints = Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED) //checks whether device should have Network Connection
.build()
val job = PeriodicWorkRequestBuilder<BackgroundUpdateCheck>(1, TimeUnit.DAYS)
.setConstraints(myConstraints)
.build()
WorkManager.getInstance(context).enqueue(job)
}
class BootReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
if (!isWorkScheduled(context)) {
println("Create a update check job in background...")
when (intent.action) {
Intent.ACTION_DATE_CHANGED -> {
newJob(context)
}
Intent.ACTION_BOOT_COMPLETED -> {
val sharedPref = context.getSharedPreferences("com.mylloon.MobiDL",
AppCompatActivity.MODE_PRIVATE)
sharedPref.edit().putInt("notifID", 0).apply()
newJob(context)
}
}
}
}
}
class MainActivity : AppCompatActivity() {
private var settingsButton: Menu? = null // before starting the app there is no settings button
@ -91,8 +35,8 @@ class MainActivity : AppCompatActivity() {
private var inSettings: Boolean = false // by default your not in settings page
private var inAppList: Boolean = false // by default your not in app list page
private var inAppInfo: Boolean = false // by default your not in app info page
private var sharedPref: SharedPreferences? = null // first run detection
private val sharedPrefName = "com.mylloon.MobiDL" // shared pref name
private var prefs: SharedPreferences? = null // first run detection
private val sharedPref = "com.mylloon.MobiDL" // shared pref name
private var timeOfLastToast: Long = System.currentTimeMillis() - 2000
private var listInfos: MutableList<Map<String, String?>>? = null
private var appMobilismInfos: Map<String, String?>? = null
@ -118,54 +62,15 @@ class MainActivity : AppCompatActivity() {
val context = applicationContext() // get app context
// read apps from the app preference
val sharedPref = context.getSharedPreferences(sharedPrefName, MODE_PRIVATE)
val sharedPref = context.getSharedPreferences(sharedPref, MODE_PRIVATE)
val data: Set<String>? = sharedPref.getStringSet("apps", null)
return data?.toMutableList() ?: mutableListOf()
}
private fun getValuesAppNeedToBeUpdated(): MutableMap<String, Boolean> { // list of the apps (from the storage if exists)
val context = applicationContext() // get app context
// read apps from the app preference
val sharedPref = context.getSharedPreferences(sharedPrefName, MODE_PRIVATE)
val dataApp: Set<String>? = sharedPref.getStringSet("appsUpdate", null)
val dataBool: Set<String>? = sharedPref.getStringSet("boolUpdate", null)
val dataAppList = dataApp?.toList()
val dataBoolList = dataBool?.toList()
val finalMap = mutableMapOf<String, Boolean>()
if ((dataAppList != null) and (dataBoolList != null)) {
for (i in dataAppList!!.indices) {
if (i in dataBoolList!!.indices) {
finalMap[dataAppList[i]] =
dataBoolList[i].substring(i.toString().length).toBoolean()
}
}
}
return finalMap
}
private fun storeValuesAppNeedToBeUpdated(updateApps: MutableMap<String, Boolean>) {
val updateAppsName: Set<String> = updateApps.keys
val updateAppsBool: MutableCollection<Boolean> = updateApps.values
val updateAppsBoolList: List<Boolean> = updateAppsBool.toList()
val updateAppsBoolSet: MutableList<String> = mutableListOf()
for (i in updateAppsBoolList.indices) {
updateAppsBoolSet.add(i.toString() + updateAppsBoolList[i].toString())
}
with(applicationContext().getSharedPreferences(sharedPrefName, MODE_PRIVATE).edit()) {
this?.putStringSet("appsUpdate", updateAppsName)
this?.putStringSet("boolUpdate", updateAppsBoolSet.toSet())
this?.apply()
}
}
override fun onCreate(savedInstanceState: Bundle?) { // Main function
super.onCreate(savedInstanceState)
sharedPref = getSharedPreferences(sharedPrefName, MODE_PRIVATE)
prefs = getSharedPreferences("com.mylloon.MobiDL", MODE_PRIVATE)
try {
if (Credentials().get(0) == null) { // test if credentials have already been registered
@ -221,7 +126,6 @@ class MainActivity : AppCompatActivity() {
private fun mainPage(toDelete: String? = null) {
if (toDelete == null) {
setContentView(R.layout.activity_main) // display main page
if (!isWorkScheduled(applicationContext)) newJob(applicationContext) // run background job if not already running
if (!settingsButtonVisible) { // check if the settings button isn't already showed
Handler(Looper.getMainLooper()).postDelayed({
toggleSettingsButtonVisibility()
@ -231,7 +135,6 @@ class MainActivity : AppCompatActivity() {
val user = Credentials().get(0).toString()
this.title = "${getString(R.string.app_name)} (${getString(R.string.connected_as)} $user)"
val valuesRecyclerView = getValuesRecyclerView() // list of all the element in the main page
val checkedItemListOfApps = getValuesAppNeedToBeUpdated()
class Adapter(private val values: List<String>) :
RecyclerView.Adapter<Adapter.ViewHolder>() {
@ -258,30 +161,20 @@ class MainActivity : AppCompatActivity() {
button?.setOnLongClickListener {
val builder: AlertDialog.Builder =
AlertDialog.Builder(instance)
builder.setTitle("${getString(R.string.config)} ${button?.text} ?")
builder.setTitle("${getString(R.string.remove)} ${button?.text} ?")
builder.setPositiveButton(R.string.remove) { _, _ ->
instance?.mainPage(
button?.text.toString()
)
checkedItemListOfApps[button?.text.toString()] = false
storeValuesAppNeedToBeUpdated(checkedItemListOfApps)
}
val appInstalled = isItAnInstalledApp(button?.text.toString())
if (appInstalled != null) {
val checkedItems = booleanArrayOf(
checkedItemListOfApps[button?.text.toString()] == true
)
builder.setMultiChoiceItems(
arrayOf(getString(R.string.updateCheck)),
checkedItems
) { _, _, isChecked ->
checkedItemListOfApps[button?.text.toString()] = isChecked
storeValuesAppNeedToBeUpdated(checkedItemListOfApps)
}
builder.setNegativeButton(R.string.forceUpdate) { _, _ ->
Notif().work(applicationContext,
button?.text.toString())
}
val checkedItems = booleanArrayOf(
false // get this info from the app files somewhere
)
builder.setMultiChoiceItems(
arrayOf(getString(R.string.updateCheck)),
checkedItems
) { _, _, isChecked ->
println("Update for ${button?.text.toString()}: " + if (isChecked) "enabled" else "disabled" + "")
}
builder.setNeutralButton(R.string.cancel) { dialog, _ -> dialog.cancel() }
builder.show()
@ -310,8 +203,11 @@ class MainActivity : AppCompatActivity() {
if (toDelete != null) {
valuesRecyclerView.remove(toDelete)
val context = applicationContext() // get app context
// read apps from the app preference
sharedPref!!.edit().putStringSet("apps", valuesRecyclerView.toSet()).apply()
val sharedPref = context.getSharedPreferences(sharedPref, MODE_PRIVATE)
sharedPref.edit().putStringSet("apps", valuesRecyclerView.toSet()).apply()
recyclerView.adapter = Adapter(valuesRecyclerView)
}
recyclerView.layoutManager = LinearLayoutManager(this)
@ -321,8 +217,11 @@ class MainActivity : AppCompatActivity() {
fun addApp(app: String) {
valuesRecyclerView.add(app)
val context = applicationContext() // get app context
// read apps from the app preference
sharedPref!!.edit().putStringSet("apps", valuesRecyclerView.toSet()).apply()
val sharedPref = context.getSharedPreferences(sharedPref, MODE_PRIVATE)
sharedPref.edit().putStringSet("apps", valuesRecyclerView.toSet()).apply()
recyclerView.adapter = Adapter(valuesRecyclerView)
}
@ -348,21 +247,6 @@ class MainActivity : AppCompatActivity() {
}
}
fun isItAnInstalledApp(app: String): String? {
var appName = app
val registeredAnswered: Map<String, String> = Gson().fromJson(
assets.open("appNames.json").bufferedReader()
.use { it.readText() },
object : TypeToken<Map<String, String>>() {}.type
)
for ((key, value) in registeredAnswered) appName =
if (Regex(appName.lowercase()).containsMatchIn(key)) value else appName.lowercase()
for (packageInfo in packageManager.getInstalledPackages(PackageManager.GET_META_DATA)) {
if (Regex(appName).containsMatchIn(packageInfo.packageName)) return packageInfo.versionName
}
return null
}
private fun callScrapper(
user: String,
password: String,
@ -525,28 +409,16 @@ class MainActivity : AppCompatActivity() {
@SuppressLint("SetTextI18n")
private fun showAppInfoPage() {
setContentView(R.layout.activity_app_infos) // display app info detailed page
if (!settingsButtonVisible) toggleSettingsButtonVisibility() // check if the settings button isn't already showed and show it if necessary
inAppInfo = true
val link = appMobilismInfos!!["link"]
if (link != null) {
val infoApp: MutableMap<String, String?>
var links: MutableMap<String, List<String>> = mutableMapOf()
var errorHappen = false
val links: MutableMap<String, List<String>>
runBlocking {
infoApp = Scraper().parseInfos(link)
try {
links = Scraper().parseDownloadLinks(infoApp["downloadLinks"]!!)
} catch (e: Exception) {
Toast.makeText(
instance,
"${getString(R.string.noLinkFound)}...",
Toast.LENGTH_SHORT
).show()
errorHappen = true
}
}
if (errorHappen) return else {
setContentView(R.layout.activity_app_infos) // display app info detailed page
if (!settingsButtonVisible) toggleSettingsButtonVisibility() // check if the settings button isn't already showed and show it if necessary
inAppInfo = true
links = Scraper().parseDownloadLinks(infoApp["downloadLinks"]!!)
}
class Adapter(private val values: List<String>) :
RecyclerView.Adapter<Adapter.ViewHolder>() {
@ -584,26 +456,16 @@ class MainActivity : AppCompatActivity() {
}
}
}
val title = findViewById<TextView>(R.id.textViewAppName)
title.text = appMobilismInfos!!["title"]
title.setOnClickListener {
startActivity(Intent(Intent.ACTION_VIEW,
Uri.parse("https://forum.mobilism.org$link")))
}
findViewById<TextView>(R.id.textViewAppName).text = appMobilismInfos!!["title"]
findViewById<TextView>(R.id.textViewAppAuthor).text = appMobilismInfos!!["author"]
findViewById<TextView>(R.id.textViewAppDate).text = appMobilismInfos!!["date"]
val changelogs = findViewById<TextView>(R.id.textViewAppChangelogs)
changelogs.text = infoApp["changelogs"]
changelogs.movementMethod = ScrollingMovementMethod()
findViewById<TextView>(R.id.textViewAppChangelogs).text = infoApp["changelogs"]
val listDownloads = mutableListOf<String>()
val recyclerViewAppDownloads: RecyclerView =
findViewById(R.id.recyclerViewAppDownloads) // get recyclerview
recyclerViewAppDownloads.layoutManager = LinearLayoutManager(this)
val displayMetrics = DisplayMetrics()
recyclerViewAppDownloads.layoutParams.height = displayMetrics.heightPixels / 3
for (arch in links.keys) {
val recyclerViewAppDownloads: RecyclerView =
findViewById(R.id.recyclerViewAppDownloads) // get recyclerview
recyclerViewAppDownloads.layoutManager = LinearLayoutManager(this)
for ((count, _) in links[arch]!!.withIndex()) {
listDownloads += "$arch - ${count + 1}"
}
@ -645,9 +507,9 @@ class MainActivity : AppCompatActivity() {
override fun onResume() {
super.onResume()
if (sharedPref!!.getBoolean("firstrun", true)) {
if (prefs!!.getBoolean("firstrun", true)) {
Credentials().generateKey() // Generate RSA keys
sharedPref!!.edit().putBoolean("firstrun", false)
prefs!!.edit().putBoolean("firstrun", false)
.apply() // first run done, now the next ones won't be "first".
}
}

View file

@ -1,169 +0,0 @@
package com.mylloon.mobidl
import android.annotation.SuppressLint
import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.BitmapFactory
import android.graphics.Color
import android.net.Uri
import android.os.Build
import androidx.appcompat.app.AppCompatActivity
import androidx.work.Worker
import androidx.work.WorkerParameters
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
var sharedPrefName = "com.mylloon.MobiDL" // shared pref name
class BackgroundUpdateCheck(appContext: Context, workerParams: WorkerParameters) :
Worker(appContext, workerParams) {
private val ctx = appContext
override fun doWork(): Result {
fun getValuesAppNeedToBeUpdated(): MutableMap<String, Boolean> { // list of the apps (from the storage if exists)
val context = MainActivity.applicationContext() // get app context
// read apps from the app preference
val sharedPref = context.getSharedPreferences(sharedPrefName,
AppCompatActivity.MODE_PRIVATE)
val dataApp: Set<String>? = sharedPref.getStringSet("appsUpdate", null)
val dataBool: Set<String>? = sharedPref.getStringSet("boolUpdate", null)
val dataAppList = dataApp?.toList()
val dataBoolList = dataBool?.toList()
val finalMap = mutableMapOf<String, Boolean>()
if ((dataAppList != null) and (dataBoolList != null)) {
for (i in dataAppList!!.indices) {
if (i in dataBoolList!!.indices) {
finalMap[dataAppList[i]] =
dataBoolList[i].substring(i.toString().length).toBoolean()
}
}
}
return finalMap
}
val apps = getValuesAppNeedToBeUpdated()
for (app in apps.keys) {
if (apps[app] == true) {
println("Checking update for $app...")
Notif().work(ctx, app)
}
}
println("Update check: Done.")
return Result.success()
}
}
class Notif {
private lateinit var notificationManager: NotificationManager
private lateinit var notificationChannel: NotificationChannel
private lateinit var builder: Notification.Builder
private val channelId = "i.apps.notifications"
private val description = R.string.descriptionNotification
@SuppressLint("UnspecifiedImmutableFlag")
fun newNotification(
context: Context,
notificationID: Int,
appName: String,
version: String,
url: String,
) {
notificationManager = context.getSystemService(NotificationManager::class.java)
val pendingIntent = PendingIntent.getActivity(context,
notificationID,
Intent(Intent.ACTION_VIEW, Uri.parse(url)),
(PendingIntent.FLAG_UPDATE_CURRENT))
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // checking if android version is greater than oreo(API 26) or not
notificationChannel = NotificationChannel(channelId,
context.getString(description),
NotificationManager.IMPORTANCE_LOW)
notificationChannel.enableLights(true)
notificationChannel.lightColor = Color.GREEN
notificationChannel.enableVibration(false)
notificationManager.createNotificationChannel(notificationChannel)
builder = Notification.Builder(context, channelId)
.setContentTitle("${context.getString(R.string.newUpdateTitleNotification)} $appName")
.setContentText("${context.getString(R.string.newUpdateVersionNotification)} $version ${
context.getString(R.string.newUpdateAvailableNotification)
}")
.setSmallIcon(R.drawable.download)
.setLargeIcon(BitmapFactory.decodeResource(context.resources, R.mipmap.ic_launcher))
.setContentIntent(pendingIntent)
.setAutoCancel(true)
} else {
builder = Notification.Builder(context)
.setContentTitle("${context.getString(R.string.newUpdateTitleNotification)} $appName")
.setContentText("${context.getString(R.string.newUpdateVersionNotification)} $version ${
context.getString(R.string.newUpdateAvailableNotification)
}")
.setSmallIcon(R.drawable.download)
.setLargeIcon(BitmapFactory.decodeResource(context.resources, R.mipmap.ic_launcher))
.setContentIntent(pendingIntent)
.setAutoCancel(true)
}
notificationManager.notify(notificationID, builder.build())
val sharedPref =
context.getSharedPreferences(sharedPrefName, AppCompatActivity.MODE_PRIVATE)
sharedPref.edit().putInt("notifID", notificationID + 1).apply()
}
fun work(context: Context, app: String) {
var appName = app
val registeredAnswered: Map<String, String> = Gson().fromJson(
context.assets.open("appNames.json").bufferedReader()
.use { it.readText() },
object : TypeToken<Map<String, String>>() {}.type
)
for ((key, value) in registeredAnswered) appName =
if (Regex(appName.lowercase()).containsMatchIn(key)) value else appName.lowercase()
var installedAppVersion: String? = null
for (packageInfo in context.packageManager.getInstalledPackages(PackageManager.GET_META_DATA)) {
if (Regex(appName).containsMatchIn(packageInfo.packageName)) installedAppVersion =
packageInfo.versionName
}
if (installedAppVersion == null) return
else {
try {
val res =
Scraper(Credentials().get(0), Credentials().get(1), app).search() ?: return
if (res[0].containsKey("gotResults")) {
var latestVersion = res[1]["title"]!!
latestVersion = Regex("""(?<=v?)\d+\.\d+(\.\d+)?""").findAll(latestVersion)
.map { it.groupValues[0] }.toList()[0]
val arrayInstalledVersion: MutableList<String> =
installedAppVersion.split(".") as MutableList<String>
val arrayLatestVersion: MutableList<String> =
latestVersion.split(".") as MutableList<String>
while (arrayInstalledVersion.size > arrayLatestVersion.size) arrayLatestVersion.add(
"0")
while (arrayInstalledVersion.size < arrayLatestVersion.size) arrayInstalledVersion.add(
"0")
var needUpdate = false
for (i in arrayInstalledVersion.indices) {
if (arrayLatestVersion[i].toInt() > arrayInstalledVersion[i].toInt()) needUpdate =
true
}
if (needUpdate) {
val sharedPref = context.getSharedPreferences(sharedPrefName,
AppCompatActivity.MODE_PRIVATE)
return newNotification(context,
sharedPref.getInt("notifID", 0),
app,
latestVersion,
"https://forum.mobilism.org${res[1]["link"]}")
}
}
} catch (e: Exception) {
return
}
}
}
}

View file

@ -196,8 +196,8 @@ class Scraper(
"No changelog found."
}
elements["downloadLinks"] = try {
htmlPage = htmlPage.replace(Regex("Download Instructions:</span>(.*?)?<br />"),
"Download Instructions:</span><br />")
htmlPage = htmlPage.replace(Regex("Download Instructions:</span>(.*?)?<br /><s"),
"Download Instructions:</span><br /><s")
var tmp =
Regex("""Download Instructions:</span> ?<br />(.*|[\s\S]*)<br /><br />Trouble downloading|</a></div>""").findAll(
htmlPage)

View file

@ -1,5 +0,0 @@
<vector android:height="24dp" android:tint="#8E44AD"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M5,20h14v-2H5V20zM19,9h-4V3H9v6H5l7,7L19,9z"/>
</vector>

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:19994ee5e957b8d8f6a2fbef8e00b35d608d3e4d7a68911e67ca07047f5cf6ba
size 3360

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:c24a8e75ece7af2ac1671c9882d635c2986eaf5172984e7fcb77576bfe398865
size 5042

View file

@ -57,11 +57,10 @@
<TextView
android:id="@+id/textViewAppChangelogs"
android:layout_width="337dp"
android:layout_height="183dp"
android:layout_width="334dp"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:fontFamily="monospace"
android:scrollbars="vertical"
android:textAlignment="viewStart"
android:textSize="16sp"
android:textStyle="italic"
@ -84,14 +83,14 @@
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerViewAppDownloads"
android:layout_width="350dp"
android:layout_height="262dp"
android:layout_width="334dp"
android:layout_height="524dp"
android:layout_marginTop="12dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.491"
app:layout_constraintHorizontal_bias="0.493"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textViewAppDownloadsTitle"
app:layout_constraintVertical_bias="0.036" />
app:layout_constraintVertical_bias="0.125" />
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -3,7 +3,7 @@
android:id="@+id/linear_layout_app_list"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="70dp"
android:layout_height="50dp"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:paddingStart="5dp"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 129 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 129 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

After

Width:  |  Height:  |  Size: 129 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 129 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 129 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 129 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 129 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 129 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 129 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 129 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 129 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.4 KiB

After

Width:  |  Height:  |  Size: 129 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

After

Width:  |  Height:  |  Size: 129 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.7 KiB

After

Width:  |  Height:  |  Size: 129 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 130 B

View file

@ -31,12 +31,4 @@
<string name="noURL">Aucune URL n\'a été trouvé pour ce post</string>
<string name="changelogs">Changements</string>
<string name="downloads">Téléchargements</string>
<string name="noLinkFound">Aucun lien trouvé</string>
<string name="descriptionNotification">Mise à jour des applications</string>
<string name="newUpdateTitleNotification">Nouvelle version pour</string>
<string name="newUpdateVersionNotification">Version</string>
<string name="newUpdateAvailableNotification">disponible</string>
<string name="forceUpdate">Force recherche de MàJ</string>
<string name="rename">Renommer</string>
<string name="config">Configurer</string>
</resources>

View file

@ -13,20 +13,11 @@
<string name="newAppDialogTitle">New app name</string>
<string name="validate">Validate</string>
<string name="remove">Remove</string>
<string name="config">Config</string>
<string name="cancel">Cancel</string>
<string name="forceUpdate">Force update search</string>
<string name="rename">Rename</string>
<string name="updateCheck">Update check</string>
<string name="notConnected">You are not logged in, redirection to the login page</string>
<string name="dropBro">drop bro</string>
<!-- Notifications -->
<string name="descriptionNotification">Application Update</string>
<string name="newUpdateTitleNotification">New version for</string>
<string name="newUpdateVersionNotification">Version</string>
<string name="newUpdateAvailableNotification">available</string>
<!-- Settings page -->
<string name="titleSettings">Settings</string>
<string name="changeCredentials">Change credentials</string>
@ -49,5 +40,4 @@
<!-- App Infos -->
<string name="changelogs">Changelogs</string>
<string name="downloads">Downloads</string>
<string name="noLinkFound">No link found</string>
</resources>

View file

@ -5,7 +5,7 @@ buildscript {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:7.1.2'
classpath 'com.android.tools.build:gradle:7.0.2'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.30"
// NOTE: Do not place your application dependencies here; they belong

View file

@ -1,6 +1,6 @@
#Wed Aug 25 01:29:46 CEST 2021
distributionBase=GRADLE_USER_HOME
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-bin.zip
distributionPath=wrapper/dists
zipStorePath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME