mirror of
https://github.com/revanced/revanced-manager.git
synced 2025-06-13 04:57:37 +02:00
feat: Improve installation robustness (#1528)
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de> Co-authored-by: Ushie <ushiekane@gmail.com> Co-authored-by: Dhruvan Bhalara <53393418+dhruvanbhalara@users.noreply.github.com> Co-authored-by: Pun Butrach <pun.butrach@gmail.com>
This commit is contained in:
@ -32,17 +32,17 @@
|
||||
android:hardwareAccelerated="true"
|
||||
android:windowSoftInputMode="adjustResize">
|
||||
<meta-data
|
||||
android:name="io.flutter.embedding.android.NormalTheme"
|
||||
android:resource="@style/NormalTheme"/>
|
||||
android:name="io.flutter.embedding.android.NormalTheme"
|
||||
android:resource="@style/NormalTheme" />
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".ExportSettingsActivity"
|
||||
android:exported="true">
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".ExportSettingsActivity"
|
||||
android:exported="true">
|
||||
</activity>
|
||||
<meta-data
|
||||
android:name="flutterEmbedding"
|
||||
android:value="2" />
|
||||
@ -55,5 +55,22 @@
|
||||
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||
android:resource="@xml/file_paths" />
|
||||
</provider>
|
||||
|
||||
<receiver
|
||||
android:name=".utils.packageInstaller.InstallerReceiver"
|
||||
android:enabled="true"
|
||||
android:exported="false">
|
||||
<intent-filter>
|
||||
<action android:name="APP_INSTALL_ACTION" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
<receiver
|
||||
android:name=".utils.packageInstaller.UninstallerReceiver"
|
||||
android:enabled="true"
|
||||
android:exported="false">
|
||||
<intent-filter>
|
||||
<action android:name="APP_UNINSTALL_ACTION" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
</application>
|
||||
</manifest>
|
||||
|
@ -1,11 +1,16 @@
|
||||
package app.revanced.manager.flutter
|
||||
|
||||
import android.app.PendingIntent
|
||||
import android.app.SearchManager
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageInstaller
|
||||
import android.os.Build
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import app.revanced.manager.flutter.utils.Aapt
|
||||
import app.revanced.manager.flutter.utils.aligning.ZipAligner
|
||||
import app.revanced.manager.flutter.utils.packageInstaller.InstallerReceiver
|
||||
import app.revanced.manager.flutter.utils.packageInstaller.UninstallerReceiver
|
||||
import app.revanced.manager.flutter.utils.signing.Signer
|
||||
import app.revanced.manager.flutter.utils.zip.ZipFile
|
||||
import app.revanced.manager.flutter.utils.zip.structures.ZipEntry
|
||||
@ -184,12 +189,24 @@ class MainActivity : FlutterActivity() {
|
||||
}.toString().let(result::success)
|
||||
}
|
||||
|
||||
"installApk" -> {
|
||||
val apkPath = call.argument<String>("apkPath")!!
|
||||
PackageInstallerManager.result = result
|
||||
installApk(apkPath)
|
||||
}
|
||||
|
||||
"uninstallApp" -> {
|
||||
val packageName = call.argument<String>("packageName")!!
|
||||
uninstallApp(packageName)
|
||||
PackageInstallerManager.result = result
|
||||
}
|
||||
|
||||
else -> result.notImplemented()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun openBrowser(query: String?) {
|
||||
private fun openBrowser(query: String?) {
|
||||
val intent = Intent(Intent.ACTION_WEB_SEARCH).apply {
|
||||
putExtra(SearchManager.QUERY, query)
|
||||
}
|
||||
@ -407,4 +424,44 @@ class MainActivity : FlutterActivity() {
|
||||
handler.post { result.success(null) }
|
||||
}.start()
|
||||
}
|
||||
|
||||
private fun installApk(apkPath: String) {
|
||||
val packageInstaller: PackageInstaller = applicationContext.packageManager.packageInstaller
|
||||
val sessionParams = PackageInstaller.SessionParams(PackageInstaller.SessionParams.MODE_FULL_INSTALL)
|
||||
val sessionId: Int = packageInstaller.createSession(sessionParams)
|
||||
val session: PackageInstaller.Session = packageInstaller.openSession(sessionId)
|
||||
session.use { activeSession ->
|
||||
val sessionOutputStream = activeSession.openWrite(applicationContext.packageName, 0, -1)
|
||||
sessionOutputStream.use { outputStream ->
|
||||
val apkFile = File(apkPath)
|
||||
apkFile.inputStream().use { inputStream ->
|
||||
inputStream.copyTo(outputStream)
|
||||
}
|
||||
}
|
||||
}
|
||||
val receiverIntent = Intent(applicationContext, InstallerReceiver::class.java).apply {
|
||||
action = "APP_INSTALL_ACTION"
|
||||
}
|
||||
val receiverPendingIntent = PendingIntent.getBroadcast(context, sessionId, receiverIntent, PackageInstallerManager.flags)
|
||||
session.commit(receiverPendingIntent.intentSender)
|
||||
session.close()
|
||||
}
|
||||
|
||||
private fun uninstallApp(packageName: String) {
|
||||
val packageInstaller: PackageInstaller = applicationContext.packageManager.packageInstaller
|
||||
val receiverIntent = Intent(applicationContext, UninstallerReceiver::class.java).apply {
|
||||
action = "APP_UNINSTALL_ACTION"
|
||||
}
|
||||
val receiverPendingIntent = PendingIntent.getBroadcast(context, 0, receiverIntent, PackageInstallerManager.flags)
|
||||
packageInstaller.uninstall(packageName, receiverPendingIntent.intentSender)
|
||||
}
|
||||
|
||||
object PackageInstallerManager {
|
||||
var result: MethodChannel.Result? = null
|
||||
val flags = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
|
||||
} else {
|
||||
PendingIntent.FLAG_UPDATE_CURRENT
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,32 @@
|
||||
package app.revanced.manager.flutter.utils.packageInstaller
|
||||
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageInstaller
|
||||
import app.revanced.manager.flutter.MainActivity
|
||||
|
||||
class InstallerReceiver : BroadcastReceiver() {
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
when (val status = intent.getIntExtra(PackageInstaller.EXTRA_STATUS, -1)) {
|
||||
PackageInstaller.STATUS_PENDING_USER_ACTION -> {
|
||||
val confirmationIntent = intent.getParcelableExtra<Intent>(Intent.EXTRA_INTENT)
|
||||
if (confirmationIntent != null) {
|
||||
context.startActivity(confirmationIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK))
|
||||
}
|
||||
}
|
||||
|
||||
else -> {
|
||||
val packageName = intent.getStringExtra(PackageInstaller.EXTRA_PACKAGE_NAME)
|
||||
val message = intent.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE)
|
||||
val otherPackageName = intent.getStringExtra(PackageInstaller.EXTRA_OTHER_PACKAGE_NAME)
|
||||
MainActivity.PackageInstallerManager.result!!.success(mapOf(
|
||||
"status" to status,
|
||||
"packageName" to packageName,
|
||||
"message" to message,
|
||||
"otherPackageName" to otherPackageName
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
package app.revanced.manager.flutter.utils.packageInstaller
|
||||
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageInstaller
|
||||
import app.revanced.manager.flutter.MainActivity
|
||||
|
||||
class UninstallerReceiver : BroadcastReceiver() {
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
when (val status = intent.getIntExtra(PackageInstaller.EXTRA_STATUS, -1)) {
|
||||
PackageInstaller.STATUS_PENDING_USER_ACTION -> {
|
||||
val confirmationIntent = intent.getParcelableExtra<Intent>(Intent.EXTRA_INTENT)
|
||||
if (confirmationIntent != null) {
|
||||
context.startActivity(confirmationIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK))
|
||||
}
|
||||
}
|
||||
|
||||
else -> {
|
||||
MainActivity.PackageInstallerManager.result!!.success(status)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user