mirror of
https://github.com/readest/readest.git
synced 2026-04-29 03:50:52 +00:00
feat: in-app updater for Android (#885)
This commit is contained in:
parent
5c23642ac0
commit
8efad90932
48 changed files with 720 additions and 366 deletions
|
|
@ -4,6 +4,7 @@ import android.app.Activity
|
|||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.util.Log
|
||||
import androidx.core.content.FileProvider
|
||||
import androidx.browser.customtabs.CustomTabsIntent
|
||||
import app.tauri.annotation.Command
|
||||
import app.tauri.annotation.InvokeArg
|
||||
|
|
@ -24,6 +25,11 @@ class CopyURIRequestArgs {
|
|||
var dst: String? = null
|
||||
}
|
||||
|
||||
@InvokeArg
|
||||
class InstallPackageRequestArgs {
|
||||
var path: String? = null
|
||||
}
|
||||
|
||||
@TauriPlugin
|
||||
class NativeBridgePlugin(private val activity: Activity): Plugin(activity) {
|
||||
private val implementation = NativeBridge()
|
||||
|
|
@ -74,4 +80,34 @@ class NativeBridgePlugin(private val activity: Activity): Plugin(activity) {
|
|||
}
|
||||
invoke.resolve(ret)
|
||||
}
|
||||
|
||||
@Command
|
||||
fun install_package(invoke: Invoke) {
|
||||
val args = invoke.parseArgs(InstallPackageRequestArgs::class.java)
|
||||
val ret = JSObject()
|
||||
try {
|
||||
val file = File(args.path ?: "")
|
||||
if (file.exists()) {
|
||||
val intent = Intent(Intent.ACTION_VIEW)
|
||||
val apkUri = FileProvider.getUriForFile(activity, "${activity.packageName}.fileprovider", file)
|
||||
intent.setDataAndType(apkUri, "application/vnd.android.package-archive")
|
||||
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
val packageManager = activity.packageManager
|
||||
val resolveInfos = packageManager.queryIntentActivities(intent, 0)
|
||||
for (resolveInfo in resolveInfos) {
|
||||
val packageName = resolveInfo.activityInfo.packageName
|
||||
activity.grantUriPermission(packageName, apkUri, Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||
}
|
||||
activity.startActivity(intent)
|
||||
ret.put("success", true)
|
||||
} else {
|
||||
ret.put("success", false)
|
||||
ret.put("error", "File does not exist")
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
ret.put("success", false)
|
||||
ret.put("error", e.message)
|
||||
}
|
||||
invoke.resolve(ret)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ const COMMANDS: &[&str] = &[
|
|||
"auth_with_custom_tab",
|
||||
"copy_uri_to_path",
|
||||
"use_background_audio",
|
||||
"install_package",
|
||||
];
|
||||
|
||||
fn main() {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
# Automatically generated - DO NOT EDIT!
|
||||
|
||||
"$schema" = "../../schemas/schema.json"
|
||||
|
||||
[[permission]]
|
||||
identifier = "allow-install-package"
|
||||
description = "Enables the install_package command without any pre-configured scope."
|
||||
commands.allow = ["install_package"]
|
||||
|
||||
[[permission]]
|
||||
identifier = "deny-install-package"
|
||||
description = "Denies the install_package command without any pre-configured scope."
|
||||
commands.deny = ["install_package"]
|
||||
|
|
@ -8,6 +8,7 @@ Default permissions for the plugin
|
|||
- `allow-auth-with-custom-tab`
|
||||
- `allow-copy-uri-to-path`
|
||||
- `allow-use-background-audio`
|
||||
- `allow-install-package`
|
||||
|
||||
## Permission Table
|
||||
|
||||
|
|
@ -99,6 +100,32 @@ Denies the copy_uri_to_path command without any pre-configured scope.
|
|||
<tr>
|
||||
<td>
|
||||
|
||||
`native-bridge:allow-install-package`
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
Enables the install_package command without any pre-configured scope.
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`native-bridge:deny-install-package`
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
Denies the install_package command without any pre-configured scope.
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
`native-bridge:allow-use-background-audio`
|
||||
|
||||
</td>
|
||||
|
|
|
|||
|
|
@ -1,3 +1,9 @@
|
|||
[default]
|
||||
description = "Default permissions for the plugin"
|
||||
permissions = ["allow-auth-with-safari", "allow-auth-with-custom-tab", "allow-copy-uri-to-path", "allow-use-background-audio"]
|
||||
permissions = [
|
||||
"allow-auth-with-safari",
|
||||
"allow-auth-with-custom-tab",
|
||||
"allow-copy-uri-to-path",
|
||||
"allow-use-background-audio",
|
||||
"allow-install-package",
|
||||
]
|
||||
|
|
|
|||
|
|
@ -330,6 +330,18 @@
|
|||
"const": "deny-copy-uri-to-path",
|
||||
"markdownDescription": "Denies the copy_uri_to_path command without any pre-configured scope."
|
||||
},
|
||||
{
|
||||
"description": "Enables the install_package command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "allow-install-package",
|
||||
"markdownDescription": "Enables the install_package command without any pre-configured scope."
|
||||
},
|
||||
{
|
||||
"description": "Denies the install_package command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "deny-install-package",
|
||||
"markdownDescription": "Denies the install_package command without any pre-configured scope."
|
||||
},
|
||||
{
|
||||
"description": "Enables the use_background_audio command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
|
|
@ -343,10 +355,10 @@
|
|||
"markdownDescription": "Denies the use_background_audio command without any pre-configured scope."
|
||||
},
|
||||
{
|
||||
"description": "Default permissions for the plugin\n#### This default permission set includes:\n\n- `allow-auth-with-safari`\n- `allow-auth-with-custom-tab`\n- `allow-copy-uri-to-path`\n- `allow-use-background-audio`",
|
||||
"description": "Default permissions for the plugin\n#### This default permission set includes:\n\n- `allow-auth-with-safari`\n- `allow-auth-with-custom-tab`\n- `allow-copy-uri-to-path`\n- `allow-use-background-audio`\n- `allow-install-package`",
|
||||
"type": "string",
|
||||
"const": "default",
|
||||
"markdownDescription": "Default permissions for the plugin\n#### This default permission set includes:\n\n- `allow-auth-with-safari`\n- `allow-auth-with-custom-tab`\n- `allow-copy-uri-to-path`\n- `allow-use-background-audio`"
|
||||
"markdownDescription": "Default permissions for the plugin\n#### This default permission set includes:\n\n- `allow-auth-with-safari`\n- `allow-auth-with-custom-tab`\n- `allow-copy-uri-to-path`\n- `allow-use-background-audio`\n- `allow-install-package`"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,3 +35,11 @@ pub(crate) async fn use_background_audio<R: Runtime>(
|
|||
) -> Result<()> {
|
||||
app.native_bridge().use_background_audio(payload)
|
||||
}
|
||||
|
||||
#[command]
|
||||
pub(crate) async fn install_package<R: Runtime>(
|
||||
app: AppHandle<R>,
|
||||
payload: InstallPackageRequest,
|
||||
) -> Result<InstallPackageResponse> {
|
||||
app.native_bridge().install_package(payload)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,4 +29,11 @@ impl<R: Runtime> NativeBridge<R> {
|
|||
pub fn use_background_audio(&self, _payload: UseBackgroundAudioRequest) -> crate::Result<()> {
|
||||
Err(crate::Error::UnsupportedPlatformError)
|
||||
}
|
||||
|
||||
pub fn install_package(
|
||||
&self,
|
||||
_payload: InstallPackageRequest,
|
||||
) -> crate::Result<InstallPackageResponse> {
|
||||
Err(crate::Error::UnsupportedPlatformError)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ pub fn init<R: Runtime>() -> TauriPlugin<R> {
|
|||
commands::auth_with_custom_tab,
|
||||
commands::copy_uri_to_path,
|
||||
commands::use_background_audio,
|
||||
commands::install_package,
|
||||
])
|
||||
.setup(|app, api| {
|
||||
#[cfg(mobile)]
|
||||
|
|
|
|||
|
|
@ -55,3 +55,14 @@ impl<R: Runtime> NativeBridge<R> {
|
|||
.map_err(Into::into)
|
||||
}
|
||||
}
|
||||
|
||||
impl<R: Runtime> NativeBridge<R> {
|
||||
pub fn install_package(
|
||||
&self,
|
||||
payload: InstallPackageRequest,
|
||||
) -> crate::Result<InstallPackageResponse> {
|
||||
self.0
|
||||
.run_mobile_plugin("install_package", payload)
|
||||
.map_err(Into::into)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,3 +31,16 @@ pub struct CopyURIResponse {
|
|||
pub struct UseBackgroundAudioRequest {
|
||||
pub enabled: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct InstallPackageRequest {
|
||||
pub path: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct InstallPackageResponse {
|
||||
pub success: bool,
|
||||
pub error: Option<String>,
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue