美文网首页
flutter app升级

flutter app升级

作者: 林祖朋 | 来源:发表于2019-12-11 10:04 被阅读0次

    App的升级,主要是Android和IOS的升级。

    问题起因:
    小编尝试了现有的flutter第三方升级,效果不是很理想,带来很多的问题,比如编译不通过,跳转失败,无法安装等问题。于是决定用flutter与原生交互一下,看能否解决这个问题。

    思路:
    Android升级,主要有两种方式,跳转应用商店和应用内下载升级。这里主要探讨应用内下载方式。IOS升级则是直接跳转AppStore。经过综合考虑,针对于Android升级,先用flutter程序去下载最新的Apk到指定的位置。然后调用原生方法去升级。对于IOS升级,直接调用原生方法,去AppStore升级。

    详细流程代码:

     //与原生通信的通道。
      var methodChannel = MethodChannel('com.lin.app/main');
    
      void _up() async {
       
        if (Platform.isAndroid) {
          //安卓下载并升级
          //这里将apk下载到应用下的cache文件夹。避免了请求内存权限。
          Directory tempDir = await getTemporaryDirectory();
          //apk的文件地址
          _savePath = tempDir.path + "/app.apk";
    
          HttpTool.download(widget._downLoadApkUrl, _savePath, _cancelToken,
              (int count, int total) {
            print("下载进度$count");
            print("下载总量$total");
    
            if (count == total) {
              //安装apk
              // MyToast.show("go安装apk");
              onClickInstallApk();
            } else {
              _yesUping = true;
    
              _progress = count ~/ (1024 * 1024);
              _total = total ~/ (1024 * 1024);
    
              setState(() {});
            }
          });
        } else if (Platform.isIOS) {
          //ios 直接跳应用商店
          onClickGotoAppStore();
        }
      }
    
     void onClickInstallApk() async {
        await methodChannel.invokeListMethod("installApk");
      }
    
      void onClickGotoAppStore() async {
        await methodChannel.invokeListMethod("goUp");
      }
    
    

    Android端准备如下:

    1.在AndroidManifest.xml中需添加一下:

        <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
    

    2.在application中:

    <!-- 适配Android 7.0 拍照 和安装app -->
            <provider
    
                tools:replace="android:authorities"
                android:name="androidx.core.content.FileProvider"
                android:authorities="${applicationId}.provider"
                android:exported="false"
                android:grantUriPermissions="true">
                <meta-data
                    tools:replace="android:resource"
                    android:name="android.support.FILE_PROVIDER_PATHS"
                    android:resource="@xml/provider_paths" />
            </provider>
    

    3.在app/res/xml中新建provider_paths文件,详细内容如下:

    <?xml version="1.0" encoding="utf-8"?>
    <paths xmlns:android="http://schemas.android.com/apk/res/android">
    
       <cache-path
           name="cache_files"
           path="."/>
    
    </paths>
    

    MainActivity处理方式:

    package com.yuhang.mall;
    
    import android.content.Intent;
    import android.net.Uri;
    import android.os.Build;
    import android.os.Bundle;
    
    
    import androidx.core.content.FileProvider;
    
    import java.io.File;
    
    import io.flutter.app.FlutterActivity;
    import io.flutter.plugin.common.MethodCall;
    import io.flutter.plugin.common.MethodChannel;
    import io.flutter.plugins.GeneratedPluginRegistrant;
    
    public class MainActivity extends FlutterActivity {
    
        /*
           1、通道名字,为任意但唯一的字符串,一般以包名开头区分
           2、必须和Dart代码中的通道名字一致
        */
        private static final String CHANNEL = "com.lin.app/main";
        //方法名字,必须和Dart端保持一致
        private static final String InstallApk = "installApk";
    
      @Override
      protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    
        GeneratedPluginRegistrant.registerWith(this);
    
        new MethodChannel(getFlutterView(),CHANNEL).setMethodCallHandler(new MethodChannel.MethodCallHandler() {
            @Override
            public void onMethodCall(MethodCall call, MethodChannel.Result result) {
                switch (call.method){
                    case InstallApk:
                        goInstall();
                        break;
                     default:
                         break;
                }
            }
        });
    
      }
    
        private void goInstall() {
         //apk路径一定得和flutter下载apk的位置一致。
          String apkName=getCacheDir().getPath()+"/app.apk";
            try {
                Intent intent = new Intent(Intent.ACTION_VIEW);
                intent.addCategory(Intent.CATEGORY_DEFAULT);
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                if (Build.VERSION.SDK_INT >= 24) {
                   //7.0以下处理
                    Uri apkUri = FileProvider.getUriForFile(MainActivity.this,
                             "com.lin.app.provider", new File(apkName));
                    intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                    intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
                } else {
                    intent.setDataAndType(Uri.parse("file://" + apkName), "application/vnd.android.package-archive");
                }
                startActivity(intent);
            } catch (Exception e) {
    
            }
        }
    
    }
    

    IOS端:
    在Runner下新建FlutterNativePlugin.h,详细代码如下:

    #import <Foundation/Foundation.h>
    #import <Flutter/Flutter.h>
    
    NS_ASSUME_NONNULL_BEGIN
    
    @interface FlutterNativePlugin : NSObject <FlutterPlugin>
    
    @end
    
    NS_ASSUME_NONNULL_END
    

    在Runner下新建FlutterNativePlugin.m,详细代码如下:

    #import <Foundation/Foundation.h>
    
    #import "FlutterNativePlugin.h"
    
    @implementation FlutterNativePlugin
    
    + (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar> *)registrar {
        FlutterMethodChannel *channel = [FlutterMethodChannel methodChannelWithName:@"com.lin.app/main" binaryMessenger:[registrar messenger]];
        FlutterNativePlugin *instance = [[FlutterNativePlugin alloc]init];
        [registrar addMethodCallDelegate:instance channel:channel];
    }
    
    - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result {
        if ([call.method isEqualToString:@"goUp"]) {
            NSLog(@"success to goUp");
            //跳转去appstore 100000000是appId
            [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"itms-apps://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=1000000000"]];
            
        }else {
            result(FlutterMethodNotImplemented);
        }
    }
    
    @end
    
    

    在AppDelegate中。

    ········
    - (BOOL)application:(UIApplication *)application
        didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
      [GeneratedPluginRegistrant registerWithRegistry:self];
        
      [FlutterNativePlugin registerWithRegistrar:[self registrarForPlugin:@"FlutterNativePlugin"]];
    
      return [super application:application didFinishLaunchingWithOptions:launchOptions];
    }
    ·······
    

    相关文章

      网友评论

          本文标题:flutter app升级

          本文链接:https://www.haomeiwen.com/subject/cfxogctx.html