Aix build success but not downloading

javac:
[mkdir] Created dir: /compiler/android/build/LZeLU/classes
[javac] Compiling 1 source file to /compiler/android/build/LZeLU/classes
[javac] warning: [options] bootstrap class path not set in conjunction with -source 1.7
[javac] Note: Wrote file file:/compiler/android/build/LZeLU/classes/simple_components.json
[javac] Note: Wrote file file:/compiler/android/build/LZeLU/classes/simple_components.txt
[javac] Note: Wrote file file:/compiler/android/build/LZeLU/classes/simple_components_build_info.json
[javac] Note: Wrote file file:/compiler/android/build/LZeLU/classes/AutogeneratedOdeMessages.java
[javac] Note: Wrote file file:/compiler/android/build/LZeLU/classes/ComponentsTranslation.java

process:
[mkdir] Created dir: /compiler/android/out/LZeLU
[mkdir] Created dir: /compiler/android/build/LZeLU/externalComponents
[mkdir] Created dir: /compiler/android/build/LZeLU/externalComponents-classes
[java]
[java] Extensions : Generating extensions

unjarAllExtensionLibraries:

jarAllExtensions:

dexAllExtensions:

extensions:

BUILD SUCCESSFUL
Total time: 1 second

this is the error

Same here. I’m curious if anyone is working on fixing the errors.

I think you’re doing something wrong. If you could show us your code so we might provide help.

package hu.nspace.mapsforgeview;

import android.content.Context;

import android.view.View;

import com.google.appinventor.components.annotations.*;

import com.google.appinventor.components.runtime.*;

import com.google.appinventor.components.common.ComponentCategory;

import org.mapsforge.map.android.graphics.AndroidGraphicFactory;

import org.mapsforge.map.android.util.AndroidUtil;

import org.mapsforge.map.layer.cache.TileCache;

import org.mapsforge.map.layer.renderer.TileRendererLayer;

import org.mapsforge.map.android.view.MapView;

import org.mapsforge.map.model.MapViewPosition;

import org.mapsforge.map.reader.MapFile;

//import org.mapsforge.map.reader.MapDataStore;

import java.io.File;

import java.io.FileInputStream;

@DesignerComponent(

version = 1,

description = "Offline Mapsforge 0.26.1 view component",

category = ComponentCategory.EXTENSION,

nonVisible = false,

iconName = "images/map.png"

)

@SimpleObject

public class MapsforgeView extends AndroidViewComponent {

// private View view;

private MapView mapView;

private MapFile mapFile;

private TileRendererLayer renderer;

private TileCache tileCache;

private MapViewPosition mapViewPosition;

public MapsforgeView(ComponentContainer container) {

super(container.$form());

Context context = container.$context();

AndroidGraphicFactory.createInstance(context);

mapView = new MapView(context);

// Alapbeállítások

mapView.setClickable(true);

mapView.getMapScaleBar().setVisible(true);

mapView.setZoomLevel((byte) 10);

// UI-hoz hozzárendelés

container.$add(this);

}

// Egyszerű getter a view-hoz (nem kell @Override)

public MapView getView() {

return mapView;

}

@SimpleFunction(description = "Load .map file from path with XmlRenderTheme")

public void LoadMap(String mapFilePath, String renderThemePath) {

try {

File file = new File(mapFilePath);

if (file.exists()) {

// MapFile betöltése

mapFile = new MapFile(mapFilePath);

// MapDataStore mapDataStore = new MapFile(mapFile);

// TileCache létrehozása (méret és DPI értékek tetszőlegesen módosíthatók)

tileCache = AndroidUtil.createTileCache(

mapView.getContext(),

"mapcache",

mapView.getModel().displayModel.getTileSize(),

1f,

mapView.getModel().frameBufferModel.getOverdrawFactor(),

true);

// TileRendererLayer létrehozása

renderer = new TileRendererLayer(

tileCache,

mapFile,

//mapDataStore,

mapView.getModel().mapViewPosition,

//null,

true, // renderLabels

true, // renderHillshading

true, // renderMapData

null

);

mapView.getLayerManager().getLayers().add(renderer);

// középre állítjuk Budapestet

``//mapView.setCenter``(new LatLong(48.0, 20.0));

mapView.setZoomLevel((byte) 12);

}

// TODO: Integráld a renderer-t a View-be

// Pl.: renderer hozzáadása egy MapView-hoz (külön komponens)

} catch (Exception e) {

e.printStackTrace();

}

}

}

These changes are required:

  1. nonVisible = true in DesignerComponent annotation.
  2. @SimpleObject(external = true)
  3. Extend AndroidNonvisibleComponent instead of AndroidViewComponent.

same issue with me .aix not downloaded

Code

package com.saheb.bglocationext;

import android.Manifest;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;

import androidx.core.app.ActivityCompat;
import androidx.core.app.NotificationCompat;
import androidx.core.content.ContextCompat;

import com.google.appinventor.components.annotations.*;
import com.google.appinventor.components.common.ComponentCategory;
import com.google.appinventor.components.runtime.*;

/**
 * Background Location Extension for Niotron / Kodular / MIT App Inventor
 * Created by Saheb | Optimized by ChatGPT
 */
@DesignerComponent(
        version = 1,
        description = "A non-visible extension to get continuous background location updates, even if the app is closed.",
        category = ComponentCategory.EXTENSION,
        nonVisible = true,
        iconName = "")
@UsesPermissions(permissionNames =
        "android.permission.ACCESS_FINE_LOCATION," +
        "android.permission.ACCESS_COARSE_LOCATION," +
        "android.permission.ACCESS_BACKGROUND_LOCATION," +
        "android.permission.FOREGROUND_SERVICE")
public class BgLocationExt extends AndroidNonvisibleComponent {

    private final Context context;
    private static BgLocationExt instance;

    // Default update intervals
    private long timeInterval = 5000; // 5 seconds
    private float distanceInterval = 5; // 5 meters

    public BgLocationExt(ComponentContainer container) {
        super(container.$form());
        this.context = container.$context();
        instance = this;
    }

    // --- PROPERTIES ---

    @SimpleProperty(description = "Sets the minimum time interval (in milliseconds) for location updates.")
    public void TimeInterval(long interval) {
        this.timeInterval = interval;
    }

    @SimpleProperty(description = "Returns the current time interval (in milliseconds) for location updates.")
    public long TimeInterval() {
        return this.timeInterval;
    }

    @SimpleProperty(description = "Sets the minimum distance (in meters) for location updates.")
    public void DistanceInterval(float distance) {
        this.distanceInterval = distance;
    }

    @SimpleProperty(description = "Returns the current distance (in meters) for location updates.")
    public float DistanceInterval() {
        return this.distanceInterval;
    }

    // --- MAIN FUNCTIONS ---

    @SimpleFunction(description = "Starts the background location service.")
    public void StartLocationService() {
        Intent serviceIntent = new Intent(context, LocationService.class);
        serviceIntent.putExtra("timeInterval", timeInterval);
        serviceIntent.putExtra("distanceInterval", distanceInterval);
        ContextCompat.startForegroundService(context, serviceIntent);
    }

    @SimpleFunction(description = "Stops the background location service.")
    public void StopLocationService() {
        Intent serviceIntent = new Intent(context, LocationService.class);
        context.stopService(serviceIntent);
    }

    // --- EVENTS ---

    @SimpleEvent(description = "Event triggered whenever a new location update is received.")
    public void LocationChanged(double latitude, double longitude) {
        EventDispatcher.dispatchEvent(this, "LocationChanged", latitude, longitude);
    }

    // Helper for service to trigger event
    public static void onLocationReceived(final double lat, final double lon) {
        if (instance != null && instance.form != null) {
            instance.form.runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    instance.LocationChanged(lat, lon);
                }
            });
        }
    }

    // --- BACKGROUND SERVICE CLASS ---

    public static class LocationService extends Service implements LocationListener {

        private LocationManager locationManager;
        private static final String CHANNEL_ID = "BgLocationExtChannel";
        private static final int NOTIFICATION_ID = 1;

        @Override
        public void onCreate() {
            super.onCreate();
            locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        }

        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            createNotificationChannel();

            // Intent to reopen app when notification tapped
            PackageManager pm = getPackageManager();
            Intent notificationIntent = pm.getLaunchIntentForPackage(getPackageName());
            PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_IMMUTABLE);

            Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
                    .setContentTitle("Background Location Active")
                    .setContentText("Tracking your location in the background.")
                    .setSmallIcon(android.R.drawable.ic_menu_mylocation)
                    .setContentIntent(pendingIntent)
                    .build();

            startForeground(NOTIFICATION_ID, notification);

            long time = intent.getLongExtra("timeInterval", 5000);
            float dist = intent.getFloatExtra("distanceInterval", 5);

            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
                    ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                stopSelf();
                return START_NOT_STICKY;
            }

            try {
                locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, time, dist, this);
            } catch (Exception e) {
                e.printStackTrace();
            }

            try {
                locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, time, dist, this);
            } catch (Exception e) {
                e.printStackTrace();
            }

            // Restart service if killed
            return START_STICKY;
        }

        @Override
        public void onDestroy() {
            super.onDestroy();
            if (locationManager != null) {
                locationManager.removeUpdates(this);
            }
        }

        @Override
        public IBinder onBind(Intent intent) {
            return null;
        }

        @Override
        public void onLocationChanged(Location location) {
            BgLocationExt.onLocationReceived(location.getLatitude(), location.getLongitude());
        }

        @Override
        public void onStatusChanged(String provider, int status, Bundle extras) {}
        @Override
        public void onProviderEnabled(String provider) {}
        @Override
        public void onProviderDisabled(String provider) {}

        private void createNotificationChannel() {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                NotificationChannel serviceChannel = new NotificationChannel(
                        CHANNEL_ID,
                        "Background Location Channel",
                        NotificationManager.IMPORTANCE_LOW
                );
                NotificationManager manager = getSystemService(NotificationManager.class);
                if (manager != null) {
                    manager.createNotificationChannel(serviceChannel);
                }
            }
        }
    }
}

Execution Log

Started Compiling Project BgLocationExt
Buildfile: /compiler/androidX/build.xml

javac:
[mkdir] Created dir: /compiler/androidX/build/WKnBV/classes
[javac] Compiling 1 source file to /compiler/androidX/build/WKnBV/classes
[javac] warning: [options] bootstrap class path not set in conjunction with -source 1.7
[javac] Note: Wrote file file:/compiler/androidX/build/WKnBV/classes/simple_components.json
[javac] Note: Wrote file file:/compiler/androidX/build/WKnBV/classes/simple_components.txt
[javac] Note: Wrote file file:/compiler/androidX/build/WKnBV/classes/simple_components_build_info.json
[javac] Note: Wrote file file:/compiler/androidX/build/WKnBV/classes/AutogeneratedOdeMessages.java
[javac] Note: Wrote file file:/compiler/androidX/build/WKnBV/classes/ComponentsTranslation.java
[javac] Note: /compiler/androidX/src/WKnBV/com/saheb/bglocationext/BgLocationExt.java uses or overrides a deprecated API.
[javac] Note: Recompile with -Xlint:deprecation for details.

process:
[mkdir] Created dir: /compiler/androidX/out/WKnBV
[mkdir] Created dir: /compiler/androidX/build/WKnBV/externalComponents
[mkdir] Created dir: /compiler/androidX/build/WKnBV/externalComponents-classes
[java]
[java] Extensions : Generating extensions

unjarAllExtensionLibraries:

jarAllExtensions:

dexAllExtensions:

extensions:

BUILD SUCCESSFUL
Total time: 1 second

Read my previous reply.

bonjour,

même problème avec ce code:

package com.mycompany.textanalyser;

import android.util.Log;

import com.google.appinventor.components.annotations.SimpleFunction;

import com.google.appinventor.components.annotations.SimpleObject;

import com.google.appinventor.components.runtime.AndroidNonvisibleComponent;

import com.google.appinventor.components.runtime.ComponentContainer;

import java.util.regex.Matcher;

import java.util.regex.Pattern;

/**

* Une extension App Inventor pour extraire des motifs spécifiques (emails, nombres, hyperliens)

* d’une chaîne de texte ou de HTML en utilisant les expressions régulières.

* Cette extension est non-visible.

*/

@SimpleObject(external=true) // Retrait de l’argument ‘description’ pour compatibilité de compilation

public class TextExtractor extends AndroidNonvisibleComponent {

private static final String LOG_TAG = "TextExtractorExtension";



// Constantes d'expressions régulières (Regex)

// Regex pour les adresses email (simple mais efficace)

private static final String EMAIL_REGEX = "\\\\b\[A-Za-z0-9.\_%+-\]+@\[A-Za-z0-9.-\]+\\\\.\[A-Za-z\]{2,}\\\\b";

// Regex pour les nombres entiers ou décimaux (incluant la notation scientifique simple)

private static final String NUMBER_REGEX = "\[-+\]?\\\\b\\\\d+(\\\\.\\\\d+)?(\[eE\]\[-+\]?\\\\d+)?\\\\b";

// Regex pour les hyperliens (URL commençant par http ou https)

private static final String URL_REGEX = "https?://\[\\\\w\\\\d./\\\\-\_#?&=%\]+";



/\*\*

 \* Constructeur de l'extension.

 \* @param container Le conteneur du composant (écran).

 \*/

public TextExtractor(ComponentContainer container) {

    super(container.$form());

    Log.d(LOG_TAG, "TextExtractor Extension Initialized");

}



/\*\*

 \* Fonction générique pour extraire la première occurrence qui correspond à une regex donnée.

 \* @param text Le texte source (peut être du texte brut ou du HTML).

 \* @param regexString L'expression régulière (Regex) à utiliser pour la recherche.

 \* @return La première correspondance trouvée, ou une chaîne vide si rien n'est trouvé.

 \*/

@SimpleFunction(description = "Extrait la première chaîne correspondant à l'expression régulière fournie. " +

                             "Retourne une chaîne vide si aucune correspondance n'est trouvée.")

public String ExtractByRegex(String text, String regexString) {

    if (text == null || regexString == null || text.isEmpty() || regexString.isEmpty()) {

        return "";

    }

    try {

        Pattern pattern = Pattern.compile(regexString);

        Matcher matcher = pattern.matcher(text);



        if (matcher.find()) {

            // Retourne la première chaîne trouvée

            return matcher.group();

        }

    } catch (Exception e) {

        Log.e(LOG_TAG, "Erreur dans ExtractByRegex: " + e.getMessage());

        // En cas d'erreur (ex: regex invalide), retourner vide

        return "";

    }

    return "";

}



/\*\*

 \* Extrait la première adresse email trouvée dans le texte.

 \* @param text Le texte source.

 \* @return La première adresse email, ou une chaîne vide.

 \*/

@SimpleFunction(description = "Extrait la première adresse email trouvée dans le texte. " +

                             "Utilise une Regex standard pour l'email.")

public String ExtractEmail(String text) {

    return ExtractByRegex(text, EMAIL_REGEX);

}



/\*\*

 \* Extrait le premier nombre (entier ou décimal) trouvé dans le texte.

 \* @param text Le texte source.

 \* @return Le premier nombre trouvé sous forme de chaîne, ou une chaîne vide.

 \*/

@SimpleFunction(description = "Extrait le premier nombre (entier ou décimal) trouvé dans le texte. " +

                             "Utilise une Regex standard pour les nombres.")

public String ExtractNumber(String text) {

    return ExtractByRegex(text, NUMBER_REGEX);

}



/\*\*

 \* Extrait le premier hyperlien (URL commençant par http ou https) trouvé.

 \* @param text Le texte source (utile pour analyser du HTML).

 \* @return Le premier hyperlien, ou une chaîne vide.

 \*/

@SimpleFunction(description = "Extrait le premier hyperlien (URL commençant par http ou https) trouvé dans le texte. " +

                             "Utilise une Regex pour les URLs.")

public String ExtractHyperlink(String text) {

    return ExtractByRegex(text, URL_REGEX);

}



/\*\*

 \* Extrait un mot ou une phrase spécifique du texte en utilisant une simple recherche de chaîne.

 \* Cette fonction pourrait être utilisée par l'utilisateur pour une recherche simple sans Regex.

 \* @param text Le texte source.

 \* @param phrase La phrase ou le mot à rechercher.

 \* @return La phrase/mot si trouvé, sinon une chaîne vide.

 \*/

@SimpleFunction(description = "Extrait une phrase ou un mot spécifique du texte source. " +

                             "Retourne la phrase si elle est trouvée, sinon une chaîne vide. " +

                             "Ceci est sensible à la casse.")

public String ExtractSpecificPhrase(String text, String phrase) {

    if (text == null || phrase == null || text.isEmpty() || phrase.isEmpty()) {

        return "";

    }

    if (text.contains(phrase)) {

        return phrase;

    }

    return "";

}

}

Post only in English!

1 Like

Hello,
I apologize for writing in French.
I have the same problem with this code:

package com.mycompany.textanalyser;

import android.util.Log;

import com.google.appinventor.components.annotations.SimpleFunction;

import com.google.appinventor.components.annotations.SimpleObject;

import com.google.appinventor.components.runtime.AndroidNonvisibleComponent;

import com.google.appinventor.components.runtime.ComponentContainer;

import java.util.regex.Matcher;

import java.util.regex.Pattern;

/**

* Une extension App Inventor pour extraire des motifs spécifiques (emails, nombres, hyperliens)

* d’une chaîne de texte ou de HTML en utilisant les expressions régulières.

* Cette extension est non-visible.

*/

@SimpleObject(external=true) // Retrait de l’argument ‘description’ pour compatibilité de compilation

public class TextExtractor extends AndroidNonvisibleComponent {

private static final String LOG_TAG = "TextExtractorExtension";



// Constantes d'expressions régulières (Regex)

// Regex pour les adresses email (simple mais efficace)

private static final String EMAIL_REGEX = "\\\\b\[A-Za-z0-9.\_%+-\]+@\[A-Za-z0-9.-\]+\\\\.\[A-Za-z\]{2,}\\\\b";

// Regex pour les nombres entiers ou décimaux (incluant la notation scientifique simple)

private static final String NUMBER_REGEX = "\[-+\]?\\\\b\\\\d+(\\\\.\\\\d+)?(\[eE\]\[-+\]?\\\\d+)?\\\\b";

// Regex pour les hyperliens (URL commençant par http ou https)

private static final String URL_REGEX = "https?://\[\\\\w\\\\d./\\\\-\_#?&=%\]+";



/\*\*

 \* Constructeur de l'extension.

 \* @param container Le conteneur du composant (écran).

 \*/

public TextExtractor(ComponentContainer container) {

    super(container.$form());

    Log.d(LOG_TAG, "TextExtractor Extension Initialized");

}



/\*\*

 \* Fonction générique pour extraire la première occurrence qui correspond à une regex donnée.

 \* @param text Le texte source (peut être du texte brut ou du HTML).

 \* @param regexString L'expression régulière (Regex) à utiliser pour la recherche.

 \* @return La première correspondance trouvée, ou une chaîne vide si rien n'est trouvé.

 \*/

@SimpleFunction(description = "Extrait la première chaîne correspondant à l'expression régulière fournie. " +

                             "Retourne une chaîne vide si aucune correspondance n'est trouvée.")

public String ExtractByRegex(String text, String regexString) {

    if (text == null || regexString == null || text.isEmpty() || regexString.isEmpty()) {

        return "";

    }

    try {

        Pattern pattern = Pattern.compile(regexString);

        Matcher matcher = pattern.matcher(text);



        if (matcher.find()) {

            // Retourne la première chaîne trouvée

            return matcher.group();

        }

    } catch (Exception e) {

        Log.e(LOG_TAG, "Erreur dans ExtractByRegex: " + e.getMessage());

        // En cas d'erreur (ex: regex invalide), retourner vide

        return "";

    }

    return "";

}



/\*\*

 \* Extrait la première adresse email trouvée dans le texte.

 \* @param text Le texte source.

 \* @return La première adresse email, ou une chaîne vide.

 \*/

@SimpleFunction(description = "Extrait la première adresse email trouvée dans le texte. " +

                             "Utilise une Regex standard pour l'email.")

public String ExtractEmail(String text) {

    return ExtractByRegex(text, EMAIL_REGEX);

}



/\*\*

 \* Extrait le premier nombre (entier ou décimal) trouvé dans le texte.

 \* @param text Le texte source.

 \* @return Le premier nombre trouvé sous forme de chaîne, ou une chaîne vide.

 \*/

@SimpleFunction(description = "Extrait le premier nombre (entier ou décimal) trouvé dans le texte. " +

                             "Utilise une Regex standard pour les nombres.")

public String ExtractNumber(String text) {

    return ExtractByRegex(text, NUMBER_REGEX);

}



/\*\*

 \* Extrait le premier hyperlien (URL commençant par http ou https) trouvé.

 \* @param text Le texte source (utile pour analyser du HTML).

 \* @return Le premier hyperlien, ou une chaîne vide.

 \*/

@SimpleFunction(description = "Extrait le premier hyperlien (URL commençant par http ou https) trouvé dans le texte. " +

                             "Utilise une Regex pour les URLs.")

public String ExtractHyperlink(String text) {

    return ExtractByRegex(text, URL_REGEX);

}



/\*\*

 \* Extrait un mot ou une phrase spécifique du texte en utilisant une simple recherche de chaîne.

 \* Cette fonction pourrait être utilisée par l'utilisateur pour une recherche simple sans Regex.

 \* @param text Le texte source.

 \* @param phrase La phrase ou le mot à rechercher.

 \* @return La phrase/mot si trouvé, sinon une chaîne vide.

 \*/

@SimpleFunction(description = "Extrait une phrase ou un mot spécifique du texte source. " +

                             "Retourne la phrase si elle est trouvée, sinon une chaîne vide. " +

                             "Ceci est sensible à la casse.")

public String ExtractSpecificPhrase(String text, String phrase) {

    if (text == null || phrase == null || text.isEmpty() || phrase.isEmpty()) {

        return "";

    }

    if (text.contains(phrase)) {

        return phrase;

    }

    return "";

}

}