nice
@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.
Are you doing same thing to everyone
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 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