2

I want to use the main logo from Flutter resources in my native Android code — for example, to display a notification. As you know, in Android you usually get resources from drawable folder like this R.drawable.icon. But then I have to copy the icon to Android drawable folder as well. Maybe there is a way to access Flutter resources (read — assets) from native code?

Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
diesersamat
  • 667
  • 2
  • 7
  • 18
  • tried to [analyze](https://developer.android.com/studio/build/apk-analyzer) the `.apk` file created by `flutter run` / `flutter build` tools? did you notice it contains `assets` folder in the root? – pskink May 28 '19 at 10:05

4 Answers4

14

There's a nice section sort-of about this in the flutter documentation.

Given an asset "icons/heart.png", for android (since 1.22):

FlutterLoader loader = FlutterInjector.instance().flutterLoader();

String key = loader.getLookupKeyForAsset("icons/heart.png");

For iOS (swift):

let key = registrar.lookupKey(forAsset: "icons/heart.png");

let path = Bundle.main.path(forResource: key, ofType: nil)

For iOS (obj-c):

NSString* key = [registrar lookupKeyForAsset:@"icons/heart.png"];

NSString* path = [[NSBundle mainBundle] pathForResource:key ofType:nil];

For android previous to Flutter version 1.22 (deprecated):

AssetManager assetManager = registrar.context().getAssets();

String key = registrar.lookupKeyForAsset("icons/heart.png");

AssetFileDescriptor fd = assetManager.openFd(key);

However, you won't be able to share a drawable item directly to flutter, and the main icon is a bit of a special case that you definitely can't share with flutter either. Flutter doesn't know what a 'drawable' is but rather deals with resources its own cross-platform way.

rmtmckenzie
  • 37,718
  • 9
  • 112
  • 99
  • what if I'm not on a plugin but in the MainActivity? https://stackoverflow.com/questions/65374762/how-to-access-flutter-assets-from-java – Gatonito Dec 19 '20 at 22:31
  • And how do you convert your AssetFileDescriptor to a Drawable, or a resource? – Waza_Be Mar 19 '21 at 06:55
  • PluginRegistry.Registrar is deprecated. Answer from @SurajNair contains the updated code. – shield May 06 '21 at 12:03
7

UPDATE FOR NEW VERSION

For flutter release 1.22 or above, FlutterLoader is only accessible via FlutterInjector.

import io.flutter.FlutterInjector;

 FlutterLoader loader = FlutterInjector.instance().flutterLoader();
 String key = loader.getLookupKeyForAsset("assets_file_name");
Suraj Nair
  • 1,729
  • 14
  • 14
  • 1
    and then, how do turn your key to a Drawable? – Waza_Be Mar 19 '21 at 06:52
  • The project I'm working on is using a deprecated package which gives error on the line `final FlutterLoader flutterLoader = FlutterLoader.getInstance()`, replacing it with your solution made it work. Thanks – Lalit Fauzdar Feb 24 '22 at 09:04
2

You need to get relative path of asset file.

Below is the helper method to access the file/image path from swift native code.

func flutterAssetLottieFilePath(imageName : String) -> String {
        var flutterViewController = FlutterViewController()
        flutterViewController = UIWindow.init(frame: UIScreen.main.bounds).rootViewController as! FlutterViewController
        let key = flutterViewController.lookupKey(forAsset:"assets/images/\(imageName).png")
        let path = Bundle.main.path(forResource: key, ofType: nil)
        return path ?? ""
    }
PradeepKN
  • 617
  • 7
  • 10
1

As of when I wrote this, the documentation was out of date. On my version of flutter, 1.17.1 here is an kotlin android example with the necessary imports above:

import android.content.Context
import io.flutter.embedding.engine.loader.FlutterLoader
import java.io.InputStream

val myAssetPath : Sting = "assets/my_asset"
val assetLookupKey =  FlutterLoader.getInstance().getLookupKeyForAsset(myAssetPath)
val inputStream: InputStream = applicationContext.assets.open(assetLookupKey)

// Read in the file from the InputStream... 

It should be noted that the value returned from this getLookupKeyForAsset method is usually your asset path, as included it on your pubspec.yaml under assets, simply prefixed with "flutter_assets/". So in the case of the above example, it would return flutter_assets/assets/my_asset

goldy1992
  • 893
  • 11
  • 17