diff --git a/android/app/build.gradle.kts b/android/app/build.gradle.kts index 8686b85..50bea74 100644 --- a/android/app/build.gradle.kts +++ b/android/app/build.gradle.kts @@ -26,6 +26,12 @@ android { versionName = flutter.versionName } + packaging { + resources { + excludes += "META-INF/DEPENDENCIES" + } + } + buildTypes { release { signingConfig = signingConfigs.getByName("debug") diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 0c41f54..0258a40 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -1,33 +1,37 @@ + - - + + + + + + + android:icon="@mipmap/launcher_icon" + android:label="رصــدیـار"> + android:name="io.flutter.embedding.android.NormalTheme" + android:resource="@style/NormalTheme" /> - - + + - - + + diff --git a/android/app/src/main/kotlin/ir/mnpc/rasadyar/MainActivity.kt b/android/app/src/main/kotlin/ir/mnpc/rasadyar/MainActivity.kt index a56ba32..8c73ca4 100644 --- a/android/app/src/main/kotlin/ir/mnpc/rasadyar/MainActivity.kt +++ b/android/app/src/main/kotlin/ir/mnpc/rasadyar/MainActivity.kt @@ -1,5 +1,57 @@ -package هir.mnpc.rasadyar +package ir.mnpc.rasadyar +import android.content.Intent +import android.net.Uri +import android.os.Build +import android.os.Bundle +import androidx.core.content.FileProvider import io.flutter.embedding.android.FlutterActivity +import io.flutter.embedding.engine.FlutterEngine +import io.flutter.plugin.common.MethodChannel +import java.io.File -class MainActivity : FlutterActivity() +class MainActivity : FlutterActivity() { + + private val CHANNEL = "apk_installer" + + override fun configureFlutterEngine(flutterEngine: FlutterEngine) { + super.configureFlutterEngine(flutterEngine) + + MethodChannel( + flutterEngine.dartExecutor.binaryMessenger, + CHANNEL + ).setMethodCallHandler { call, result -> + if (call.method == "installApk") { + val apkPath = call.argument("appPath") ?: "" + installApk(apkPath) + result.success(null) + } + } + + + } + + + private fun installApk(path: String) { + val file = File(path) + val intent = Intent(Intent.ACTION_VIEW) + intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK + val apkUri: Uri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + val uri = FileProvider.getUriForFile( + applicationContext, + "${BuildConfig.APPLICATION_ID}.fileprovider", + file + ) + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) + uri + } else { + Uri.fromFile(file) + } + + intent.setDataAndType(apkUri, "application/vnd.android.package-archive") + applicationContext.startActivity(intent) + + + } + +} diff --git a/android/app/src/main/res/xml/file_paths.xml b/android/app/src/main/res/xml/file_paths.xml new file mode 100644 index 0000000..03d4219 --- /dev/null +++ b/android/app/src/main/res/xml/file_paths.xml @@ -0,0 +1,6 @@ + + + + diff --git a/packages/core/lib/core.dart b/packages/core/lib/core.dart index 306e2fe..d1c0ae9 100644 --- a/packages/core/lib/core.dart +++ b/packages/core/lib/core.dart @@ -10,18 +10,18 @@ export 'package:flutter_secure_storage/flutter_secure_storage.dart'; export 'package:flutter_slidable/flutter_slidable.dart'; export 'package:font_awesome_flutter/font_awesome_flutter.dart'; export 'package:device_info_plus/device_info_plus.dart'; -export 'package:dio/dio.dart' show DioException; +export 'package:dio/dio.dart' ; +export 'package:pretty_dio_logger/pretty_dio_logger.dart'; //freezed export 'package:freezed_annotation/freezed_annotation.dart'; export 'package:geolocator/geolocator.dart'; -export 'package:get/get.dart'; +export 'package:get/get.dart' hide FormData, MultipartFile, Response; //di export 'package:get_it/get_it.dart'; export 'injection/di.dart'; //local storage export 'package:hive_ce_flutter/hive_flutter.dart'; -export 'package:flutter_secure_storage/flutter_secure_storage.dart'; export 'infrastructure/local/hive_local_storage.dart'; //encryption diff --git a/packages/core/lib/utils/apk_updater.dart b/packages/core/lib/utils/apk_updater.dart new file mode 100644 index 0000000..23776db --- /dev/null +++ b/packages/core/lib/utils/apk_updater.dart @@ -0,0 +1,22 @@ +import 'dart:io'; + +import 'package:dio/dio.dart'; +import 'package:flutter/services.dart'; +import 'package:path_provider/path_provider.dart'; + +class ApkUpdater { + static const _channel = MethodChannel('apk_installer'); + + static Future downloadAndInstall() async { + final dio = Dio(); + final apkUrl = "https://yourdomain.com/app.apk"; + + final dir = await getExternalStorageDirectory(); + final path = "${dir!.path}/update.apk"; + final file = File(path); + + await dio.download(apkUrl, path); + + await _channel.invokeMethod("installApk", {"path": path}); + } +} diff --git a/pubspec.lock b/pubspec.lock index 1ef2d3a..c2ae1cd 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -233,6 +233,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.2.0" + device_info_plus: + dependency: transitive + description: + name: device_info_plus + sha256: "0c6396126421b590089447154c5f98a5de423b70cfb15b1578fd018843ee6f53" + url: "https://pub.dev" + source: hosted + version: "11.4.0" + device_info_plus_platform_interface: + dependency: transitive + description: + name: device_info_plus_platform_interface + sha256: "0b04e02b30791224b31969eb1b50d723498f402971bff3630bca2ba839bd1ed2" + url: "https://pub.dev" + source: hosted + version: "7.0.2" dio: dependency: transitive description: @@ -1277,6 +1293,14 @@ packages: url: "https://pub.dev" source: hosted version: "5.13.0" + win32_registry: + dependency: transitive + description: + name: win32_registry + sha256: "6f1b564492d0147b330dd794fee8f512cec4977957f310f9951b5f9d83618dae" + url: "https://pub.dev" + source: hosted + version: "2.1.0" wkt_parser: dependency: transitive description: