[Free] ⚠ ImageNotifier

With some help from @Juan_Antonio I believe we have found the issue. He had a go at building the extension the AI2 way, and this generated an error on this line

alert.setPositiveButton("OK", (dialog, whichButton) -> 
lambda expressions are not supported in -source 1.7

it used to allow projects to compile but not now ?

I can find a different way to set the positive button.

Yay, now builds and allows projects to compile :smiley:

Thanks all for help and support, especially @Juan_Antonio :clap:

JAVA
package uk.co.metricrat.imagenotifier;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.*;
import android.graphics.*;
import android.util.*;
import android.view.*;
import android.widget.*;
import android.widget.LinearLayout;
import com.google.appinventor.components.runtime.*;
import com.google.appinventor.components.annotations.SimpleEvent;
import com.google.appinventor.components.annotations.SimpleFunction;
import com.google.appinventor.components.runtime.AndroidNonvisibleComponent;
import com.google.appinventor.components.runtime.ComponentContainer;

public class ImageNotifier extends AndroidNonvisibleComponent {

    private final Activity activity;

    public ImageNotifier(ComponentContainer container) {
        super(container.$form());
        this.activity = this.form.$context();
    }

    @SimpleFunction(description = "Shows a provided image and an OK button, with title and caption. Use maxSize to increase or decrease image size. A value " +
            "of 600 works well for square, portrait and landscape images. An absolute path is required to all images on the device.")
    public void ShowImageNotifier(final String title, final String imagePath, final String caption, final int maxSize) {
        Bitmap bitmapPicture = BitmapFactory.decodeFile(imagePath);
        final ImageView imageView = new ImageView(this.activity);

        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inSampleSize = 8;
        Bitmap resizedBitmap = getResizedBitmap(bitmapPicture,maxSize);

        imageView.setImageBitmap(resizedBitmap);
        imageView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);

        AlertDialog.Builder alert = new AlertDialog.Builder(activity);

        alert.setTitle(title);
        LinearLayout layout = new LinearLayout(activity);
        layout.setOrientation(LinearLayout.VERTICAL);
        layout.addView(imageView);
        final TextView capText = new TextView(this.activity);
        capText.setText(caption);
        capText.setGravity(Gravity.CENTER);
        layout.addView(capText);
        alert.setView(layout);
        alert.setPositiveButton("OK", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int whichButton) {
                AfterImageNotifier();
            }
        });
        alert.setCancelable(false);
        alert.show();
    }

    // Event raised after the user has responded to imageNotifier.
    @SimpleEvent(description = "Event raised after the user has responded to ImageNotifier.")
    public void AfterImageNotifier() {
        EventDispatcher.dispatchEvent(this, "AfterImageNotifier");
    }

    @SimpleFunction(description = "Shows a provided base64 string as an image, an OK button, a title and a caption. Use maxSize to increase or decrease " +
            "image size. A value of 600 works well for square, portrait and landscape images.")
    public void ShowImageNotifierFromBase64String(final String title, final String base64String, final String caption, final int maxSize) {

        final ImageView imageView = new ImageView(this.activity);

        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inSampleSize = 8;
        byte[] decodedString = Base64.decode(base64String, Base64.DEFAULT);
        Bitmap decodedByte = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);
        Bitmap resizedBitmap = getResizedBitmap(decodedByte,maxSize);
        imageView.setImageBitmap(resizedBitmap);
        imageView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);

        AlertDialog.Builder alert = new AlertDialog.Builder(activity);

        alert.setTitle(title);
        LinearLayout layout = new LinearLayout(activity);
        layout.setOrientation(LinearLayout.VERTICAL);
        layout.addView(imageView);
        final TextView capText = new TextView(this.activity);
        capText.setText(caption);
        capText.setGravity(Gravity.CENTER);
        layout.addView(capText);
        alert.setView(layout);
        alert.setPositiveButton("OK", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int whichButton) {
                AfterBase64ImageNotifier();
            }
        });
        alert.setCancelable(false);
        alert.show();
    }

    // Event raised after the user has responded to base64ImageNotifier.
    @SimpleEvent(description = "Event raised after the user has responded to base64ImageNotifier.")
    public void AfterBase64ImageNotifier() {
        EventDispatcher.dispatchEvent(this, "AfterBase64ImageNotifier");
    }

    //* For resize bitmap with width and height ratio.
    public static Bitmap getResizedBitmap(Bitmap image, int maxSize) {
        int width = image.getWidth();
        int height = image.getHeight();

        float bitmapRatio = (float) width / (float) height;
        if (bitmapRatio > 1) {
            width = maxSize;
            height = (int) (width / bitmapRatio);
        } else {
            height = maxSize;
            width = (int) (height * bitmapRatio);
        }
        return Bitmap.createScaledBitmap(image, width, height, true);
    }


}


uk.co.metricrat.imagenotifierV4.aix

I'll update first post in due course. (edit, link now updated)

2 Likes

App Inventor has never allowed for lambda functions in components/extensions. In the ant build.xml for components we specify Java 7 as the source/target versions and lambdas were add in Java 8. You should use an anonymous inner class instead.

My IDE, IntelliJ Idea, suggests the notifier.java way as a problem, and to convert

alert.setPositiveButton("OK", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int whichButton) {
                AfterImageNotifier();
            }
        });

to a lambda expression....

alert.setPositiveButton("OK", (dialog, whichButton) -> AfterImageNotifier());

However, as this does not compile, I have used the notifier.java method for the positive button.

In the project properties you can tell IntelliJ that the project language is Java 7 so it should stop recommending Java 8 features:

1 Like

@shreyash advises that RUSH's desugaring feature (which I did not use!) will allow lambda (JAVA8) features to run in AI2

1 Like

I wanted to get this extension. SO nice!!! Thank you​:smiley::hugs:

imagenotifier runs in companion, when compiled gives error

Runtime Error, Attempt to invoke virtual method "intandroid.graphics.getwidtih()" on a null object reference.

Are you using the latest version of the extension, available from the download link?

These blocks (thanks @Anke) work with a compiled app on Android 13 (the image is border.png, and is copied to the ASD for use by the notifier)

1 Like

why have to copy to "App"? can not read from the "Asset"?

This is possible in companion, but I don't believe the extension handles asset paths when compiled.

OK thanks!

In the demonstration, it does not mention the image file types supported for the base64String.

The extension uses BitmapFactory, so should work for jpg, png and webp.

1 Like

Suggestions for v5:

Set Background and Text Colour
Set Font Size

This comes from the theme, not going there :wink:

You could try html, this is based on the standard notifier....

Font sizes come from standard notifier (android dialog), they are sufficient as they are , imho.

I provide the java source code, you are welcome to fork / develop :wink:

1 Like

@TIMAI2 Could you share a working sample in the AIA file?

Sure.

altNotifierDemo.aia (67.8 KB)
(path defined in blocks will only work in companion app)

1 Like

Thank you working like a charm