Looking for help in extension development

nice :sparkling_heart:
@Joejsanz i have many extension project already completed 80-100%, i want to share with you, can u tell me where i send you, telegram, whatsapp, discord, instagram etc. because your profile is hidden, i can't message you. :rocket:

Are you doing same thing to everyone :smile:

@Prem_Gupta

We have an extension development section you can post your unfinished extensions for help...

Please don't ask for such help in other developers public topics.

2 Likes

I now moved it to Open Source Development
Taifun

I publish one of those here:

this extension code is for add custom font Family, but these 3 version work in build apk but not work in companion. can any developer fix this issue?

1st V:


    /**
     * Sets the custom font family for messages.
     * Provide the path to the font file (e.g., 'myfont.ttf').
     */
    @DesignerProperty(editorType = PropertyTypeConstants.PROPERTY_TYPE_ASSET, defaultValue = "")
    @SimpleProperty(description = "Sets the custom font family for messages. Provide the path to the font file (e.g., 'myfont.ttf').")
    public void CustomFontFamily(String typefacePath) {
        loadTypeface(typefacePath);
    }

    /**
     * Loads the typeface from assets or external path depending on mode
     *
     * @param typefacePath Path to the font file
     */
    private void loadTypeface(String typefacePath) {
        if (typefacePath == null || typefacePath.trim().isEmpty()) {
            Log.w("FontLoader", "Typeface path is empty or null.");
            typeface = Typeface.DEFAULT;
            return;
        }

        try {
            if (isCompanion()) {
                String packageName = form.getPackageName();
                String platform = detectPlatform(packageName);

                String resolvedPath = android.os.Build.VERSION.SDK_INT > 28
                        ? "/storage/emulated/0/Android/data/" + packageName + "/files/assets/" + typefacePath
                        : "/storage/emulated/0/" + platform + "/assets/" + typefacePath;

                File fontFile = new File(resolvedPath);
                if (fontFile.exists()) {
                    typeface = Typeface.createFromFile(fontFile);
                } else {
                    Log.w("FontLoader", "Font file not found: " + resolvedPath);
                    typeface = Typeface.DEFAULT;
                }
            } else {
                typeface = Typeface.createFromAsset(form.$context().getAssets(), typefacePath);
            }
        } catch (Exception e) {
            Log.e("FontLoader", "Error loading typeface from path: " + typefacePath, e);
            typeface = Typeface.DEFAULT;
        }
    }

    /**
     * Checks if running in App Inventor companion
     *
     * @return True if running in companion, false otherwise
     */
    private boolean isCompanion() {
        String packageName = form.getPackageName(); // Standardized usage
        return packageName.contains("makeroid") ||
                packageName.contains("kodular") ||
                packageName.contains("Niotron") ||
                packageName.contains("Appzard") ||
                packageName.contains("appinventor") ||
                packageName.contains("androidbuilder");
    }

    /**
     * Detects the platform name based on package name
     *
     * @param packageName The app's package name
     * @return Platform name string
     */
    private String detectPlatform(String packageName) {
        if (packageName.contains("makeroid")) return "Makeroid";
        if (packageName.contains("kodular")) return "Kodular";
        if (packageName.contains("Niotron")) return "Niotron";
        if (packageName.contains("Appzard")) return "Appzard";
        if (packageName.contains("androidbuilder")) return "AndroidBuilder";
        return "AppInventor";
    }

2nd V:

    @DesignerProperty(editorType = PropertyTypeConstants.PROPERTY_TYPE_ASSET, defaultValue = "")
    @SimpleProperty(description = "Set custom font family")
    public void FontFamily(String typefacePath) {
        try {
            if (isCompanions()) {
                typeface = Typeface.createFromFile(getCompanionAssetPath(typefacePath));
            } else {
                typeface = Typeface.createFromAsset(
                        context.getAssets(),
                        typefacePath);
            }
        } catch (Exception e) {
            Log.e("ChatUIv5", "Error loading font: " + e.getMessage());
            typeface = Typeface.DEFAULT;
        }
    }

    /**
     * Gets asset path for companion
     *
     * @param assetName The asset filename
     * @return Full path to the asset
     */
    private String getCompanionAssetPath(String assetName) {
        String packageName = context.getPackageName();
        String basePath;

        if (packageName.contains("makeroid")) {
            basePath = "/storage/emulated/0/Makeroid/assets/";
        } else if (packageName.contains("kodular")) {
            basePath = "/storage/emulated/0/Kodular/assets/";
        } else if (packageName.contains("appinventor")) {
            basePath = "/storage/emulated/0/AppInventor/assets/";
        } else if (packageName.contains("niotron")) {
            basePath = "/storage/emulated/0/Niotron/assets/";
        } else if (packageName.contains("androidbuilder")) {
            basePath = "/storage/emulated/0/AndroidBuilder/assets/";
        } else if (packageName.contains("appzard")) {
            basePath = "/storage/emulated/0/Appzard/assets/";
        } else {
            basePath = "/storage/emulated/0/Android/data/" + packageName + "/files/assets/";
        }

        return basePath + assetName;
    }

    /**
     * Checks if running in App Inventor companion
     *
     * @return True if running in companion, false otherwise
     */
    private boolean isCompanions() {
        String packageName = context.getPackageName();
        return packageName.contains("makeroid") ||
                packageName.contains("kodular") ||
                packageName.contains("Niotron") ||
                packageName.contains("Appzard") ||
                packageName.contains("appinventor") ||
                packageName.contains("androidbuilder");
    }

3rd V:


    @DesignerProperty(editorType = PropertyTypeConstants.PROPERTY_TYPE_ASSET, defaultValue = "")
    @SimpleProperty(description = "Set the font family for messages")
    public void FontFamily(String typefacePath) {
        loadTypefaces(typefacePath);
    }
    private void loadTypefaces(String typefacePath) {
        try {
            if (isCompanionss()) {
                final String packageName = form.getPackageName();
                final String platform = packageName.contains("makeroid")
                        ? "Makeroid"
                        : packageName.contains("Niotron")
                        ? "Niotron"
                        : packageName.contains("Appzard")
                        ? "Appzard"
                        : "AppInventor";
                typefacePath = android.os.Build.VERSION.SDK_INT > 28
                        ? "/storage/emulated/0/Android/data/" + packageName + "/files/assets/" + typefacePath
                        : "/storage/emulated/0/" + platform + "/assets/" + typefacePath;
                typeface = Typeface.createFromFile(new File(typefacePath));
            } else {
                typeface = Typeface.createFromAsset(form.$context().getAssets(), typefacePath);
            }
        } catch (Exception e) {
            e.printStackTrace();
            typeface = Typeface.DEFAULT;
        }
    }

    private boolean isCompanionss() {
        return context.getPackageName().contains("makeroid") ||
                context.getPackageName().contains("Niotron") ||
                context.getPackageName().contains("Appzard") ||
                context.getPackageName().contains("aicompanion3");
    }

This works for me:

  public static Typeface getTypeFace(Form form, String fontFile) {
    if (fontFile == null || fontFile.isEmpty()) {
      return null;
    }
    Typeface typeface = null;
    if (!fontFile.contains("/")) {
      if (form instanceof ReplForm) {
        if (Build.VERSION.SDK_INT > 28) {
          File file = new File("/storage/emulated/0/Android/data/edu.mit.appinventor.aicompanion3/files/assets/" + fontFile);
          typeface = Typeface.createFromFile(file);
        } else {
          File file = new File("/storage/emulated/0/AppInventor/assets/" + fontFile);
          typeface = Typeface.createFromFile(file);
        }
        File file = new File("/storage/emulated/0/Android/data/edu.mit.appinventor.aicompanion3/files/assets/" + fontFile);
        typeface = Typeface.createFromFile(file);
      } else {
        typeface = Typeface.createFromAsset(form.$context().getAssets(), fontFile);
      }
    }
    return typeface;
  }
1 Like