Categories
discuss

Using LiveData as state inside Jetpack @Compose functions

I want to use a LiveData<List<DataClass>> to be the source of my state in a @Composable function.

I cannot use the new @Model annotation, I have seen in this talk Link(at 32:06) it is possible to use LiveData, Flow, etc. by invoking the function +observe(/* Data */).

To the problem: I cannot find the function used in the video (+observe()) or any other way to use LiveData as an origin. How can I use LiveData inside my @Compose function?

Project Gradle:

buildscript {
    ext.kotlin_version = '1.3.60-eap-76'
    repositories {
        google()
        jcenter()
        maven { url 'https://dl.bintray.com/kotlin/kotlin-eap' }
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:4.0.0-alpha04'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
}

App gradle: Dependencies:

   def lifecycle_version = "2.1.0"
   def compose_version = "0.1.0-dev02"

    // ViewModel and LiveData
    implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
    kapt "androidx.lifecycle:lifecycle-compiler:$lifecycle_version"
    androidTestImplementation "androidx.arch.core:core-testing:$lifecycle_version"

    implementation "androidx.compose:compose-runtime:$compose_version"
    kapt "androidx.compose:compose-compiler:$compose_version"

    // Android Compose
    implementation "androidx.ui:ui-layout:$compose_version"
    implementation "androidx.ui:ui-foundation:$compose_version"
    implementation "androidx.ui:ui-framework:$compose_version"
    implementation "androidx.ui:ui-tooling:$compose_version"
    implementation "androidx.ui:ui-android-text:$compose_version"
    implementation "androidx.ui:ui-text:$compose_version"
    implementation "androidx.ui:ui-material:$compose_version"


Answer

0.1.0-dev09 now includes ui-livedata. Example use here.

Categories
discuss

How do developers who customise AOSP keep their changes under version control?

Fetching the AOSP source, is 134GB.

A checkout of a particular version of Android is likely to be many GBs.

How do developers who customise AOSP keep their changes under (their own) version control? (Given that checking-in a snapshot of an Android version’s source will be many GBs.)

Answer

This is my flow, maybe not the best….

I don’t like dealing with repo tool and multiple remotes, so I get rid of all the .git subfolders and create just one tremendously huge repository. This has the bad effect of essentially removing all the “history”. So we have a server with the original sync for git blame if we need to.

First check-out for a developer will be time-consuming either way. To make it faster, we have a local bare git repo cloned. So people run git clone on the local server, and the switch the origin to the actual remote.

After all is set-up, the day-to-day dealings are not time consuming. Commits and pushes are quite fast ( maybe 5-10s ) even for a large repo like this. Thanks GIT!

Categories
discuss

javax.imageio.ImageIO file format constants

In javax.imageio.ImageIO there is a method #write(RenderedImage im, String formatName, OutputStream output) that accepts a “stringly-typed” format developer wants image to be written to.

There is an inner class called CanEncodeImageAndFormatFilter deep inside that file that checks if there is an SPI (whatever it is) that supports the aforementioned format. For example, BMPImageWriterSpi declares

    private static String[] formatNames = {"bmp", "BMP"};

But in all these SPI-classes these format names are declared either private or package-default, so I cannot access them in my application. But I’d like to expose that format parameter in API I’m working on right now, but I don’t want to reinvent the wheel.

โžฅ Is there an enum or something I can safely use as a format name parameter for the #write method?

Yes, this is more like an opinion based question with coding-style tag. ๐Ÿ˜€


UPD: What I have:
ImageIO.write(image, "jpg", outStream);

What I want:

ImageIO.write(image, ImageTypes.JPEG, outStream);

Answer

There is no such Enum you are looking for in the default Java API.

The reason is that the Java Image I/O API uses the Service provider interface (SPI). Which allows to create extensible applications. In the scope of your question additional image reader/writer classes (which implements the respective interface) can be added to the classpath and will be discovered automatically during runtime. The application can use them without even knowing at compile time they exist. Hence such Enum not exist.

You can discover all currently known ImageWriter implementations with following snippet.

import javax.imageio.spi.IIORegistry;
import javax.imageio.spi.ImageWriterSpi;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        IIORegistry registry = IIORegistry.getDefaultInstance();
        Iterator<ImageWriterSpi> serviceProviders = registry.getServiceProviders(ImageWriterSpi.class, false);
        while(serviceProviders.hasNext()) {
            ImageWriterSpi next = serviceProviders.next();
            System.out.printf("description: %-27s   format names: %s%n",
                    next.getDescription(Locale.ENGLISH),
                    Arrays.toString(next.getFormatNames())
            );
        }
    }
}

output for Java 13

description: Standard BMP Image Writer     format names: [bmp, BMP]
description: Standard JPEG Image Writer    format names: [JPEG, jpeg, JPG, jpg]
description: Standard WBMP Image Writer    format names: [wbmp, WBMP]
description: Standard PNG image writer     format names: [png, PNG]
description: Standard GIF image writer     format names: [gif, GIF]
description: Standard TIFF image writer    format names: [tif, TIF, tiff, TIFF]

Below is a simplified example how the SPI could be used.

assume following files in the current directory

Main.class                  - the one from above source
ExampleImageWriterSpi.java  - an example implementation of the ImageWriterSpi

ExampleImageWriterSpi.java

package sub.optimal;

import javax.imageio.ImageTypeSpecifier;
import javax.imageio.ImageWriter;
import javax.imageio.spi.ImageWriterSpi;
import java.io.IOException;
import java.util.Locale;

public class ExampleImageWriterSpi extends ImageWriterSpi {

    private static final String[] formatNames = { "xyz", "XYZ"};

    public String getDescription(Locale locale) {
        return "Example XYZ image writer";
    }

    @Override
    public String[] getFormatNames() {
        return formatNames;
    }

    // following is without implementation in this example
    public boolean canEncodeImage(ImageTypeSpecifier type) {
        return false;
    }

    public ImageWriter createWriterInstance(Object extension) throws IOException {
        return null;
    }
}

compile the class

javac ExampleImageWriterSpi.java

create the provider configuration file
(the filename specifies the implemented interface, the line specifies the implementing class)

mkdir -p META-INF/services/
echo sub.optimal.ExampleImageWriterSpi > META-INF/services/javax.imageio.spi.ImageWriterSpi

create an archive for the service provider

jar cf example-image-writer.jar META-INF/ sub/

run the plain example code

java Main

output (all service providers which are part of the Java runtime)

description: Standard BMP Image Writer     format names: [bmp, BMP]
description: Standard JPEG Image Writer    format names: [JPEG, jpeg, JPG, jpg]
description: Standard WBMP Image Writer    format names: [wbmp, WBMP]
description: Standard PNG image writer     format names: [png, PNG]
description: Standard GIF image writer     format names: [gif, GIF]
description: Standard TIFF image writer    format names: [tif, TIF, tiff, TIFF]

run the example with the additional service provider

java -cp example-image-writer.jar:. Main

output

description: Example XYZ image writer      format names: [xyz, XYZ]
description: Standard JPEG Image Writer    format names: [JPEG, jpeg, JPG, jpg]
description: Standard WBMP Image Writer    format names: [wbmp, WBMP]
description: Standard PNG image writer     format names: [png, PNG]
description: Standard GIF image writer     format names: [gif, GIF]
description: Standard BMP Image Writer     format names: [bmp, BMP]
description: Standard TIFF image writer    format names: [tif, TIF, tiff, TIFF]

You might create the enum yourself. But you should check at runtime if there is a provider available for this image type. e.g. TIFF was not available in the Java runtime before Java 9.

Categories
discuss

CameraX – crash app on onPause() while recording video

if minimize app while recording video – everything all right, but once I deploy the application, ะตั€ัƒั‚ getting this error:

E/AndroidRuntime: FATAL EXCEPTION: CameraX-video encoding thread
Process: <pkgname>, PID: 12340
java.lang.IllegalStateException
    at android.media.MediaCodec.native_dequeueOutputBuffer(Native Method)
    at android.media.MediaCodec.dequeueOutputBuffer(MediaCodec.java:2698)
    at androidx.camera.core.VideoCapture.videoEncode(VideoCapture.java:604)
    at androidx.camera.core.VideoCapture$2.run(VideoCapture.java:348)
    at android.os.Handler.handleCallback(Handler.java:873)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:214)
    at android.os.HandlerThread.run(HandlerThread.java:65)

Or if I stopped recording on onPause videoCapture?.stopRecording(), then getting this error:

E/AndroidRuntime: FATAL EXCEPTION: CameraX-
Process: <pkgname>, PID: 9489
java.lang.IllegalStateException
    at androidx.core.util.Preconditions.checkState(Preconditions.java:96)
    at androidx.core.util.Preconditions.checkState(Preconditions.java:108)
    at androidx.camera.camera2.impl.Camera.openCaptureSession(Camera.java:874)
    at androidx.camera.camera2.impl.Camera.onUseCaseReset(Camera.java:625)
    at androidx.camera.camera2.impl.Camera$11.run(Camera.java:611)
    at android.os.Handler.handleCallback(Handler.java:873)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:214)
    at android.os.HandlerThread.run(HandlerThread.java:65)

How right stop record video while minimize app???

here’s my code: I collect configurations:

CameraX.unbindAll()
    getDisplayMetrics()
    setPreviewConfig()

    when (typeCapture) {
        TYPE_IMAGE -> {
            setImageCapture()
            CameraX.bindToLifecycle(this, preview, imageCapture)
        }
        TYPE_VIDEO -> {
            setVideoCapture()
            CameraX.bindToLifecycle(this, preview, videoCapture)
        }
    }

set videoConfig and videoCapture:

val videoCaptureConfig = VideoCaptureConfig.Builder().apply {
        setLensFacing(lensFacing)
        setTargetAspectRatioCustom(screenAspectRatio)
        setTargetRotation(rotation)
    }.build()

    videoCapture = VideoCapture(videoCaptureConfig)

then I start recording video:

videoCapture?.startRecording(videoFile, 
CameraXExecutors.mainThreadExecutor(), recordListener)

on onPause() the errors I get are described above

Thanks

Answer

I had the same error when stoping the video on onPause. To solve it I added a delay before to call super.onPause() ( see : android: camera onPause/onResume issue).

  1. Declare videoSavedListener
private VideoCapture.OnVideoSavedListener videoSavedListener= new VideoCapture.OnVideoSavedListener() {
    @Override
    public void onVideoSaved(@NonNull File file) {
        if(isRecording) {
            isRecording = false;
            // Do whatever you want
        }
    }

    @Override
    public void onError(@NonNull VideoCapture.VideoCaptureError videoCaptureError, @NonNull String message, @Nullable Throwable cause) {

    }
};
  1. Add onClickListener
button.setOnClickListener(v -> {
    if(!isRecording){
        videoCapture.startRecording(videoFile, CameraXExecutors.mainThreadExecutor(), videoSavedListener);
        isRecording = true;
     }else{
        videoCapture.stopRecording();
     }
});
  1. Override onPause()
    @SuppressLint("RestrictedApi")
    @Override
    public void onPause() {
        if(isRecording){
            isRecording = false;
            videoCapture.stopRecording();

            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            super.onPause();
        }else
            super.onPause();
    }

Please note that video recording use case is currently marked as hidden in the API and is in a very preliminary state and subject to change.

EDIT: With some devices the app still crash when calling onPause() with the videoCapture use case set. I added CameraX.unbindAll() to remove all the use cases before calling super.onPause(). Then, in the onResume() method I bind them again.

Categories
discuss

Reading request headers inside a service worker

I’ve created a very basic service worker, that logs the request headers on fetch event:

self.addEventListener('fetch', event => {
  console.log("- Fetch -");
  for (const pair of event.request.headers.entries()) {
    console.log(pair[0]+ ': '+ pair[1]);
  }
});

On the main page, I’m fetching the same page like so:

function fetchPage() {
   fetch(location.href);
}

When logging the headers I’m getting just the following 2 headers:

- Fetch -
service-worker.js:12 accept: */*
service-worker.js:12 user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36

Why can’t I see any other/custom headers?
Is it a security limitation?

Answer

Yes, these headers are intentionally hidden. The general behaviour of header list and request objects is specified in the Fetch standard.

The non-normative section “HTTP header layer division” in that specification explains that requests proceed in three stages, all of which may modify the header list, while client code relying on the Fetch and Service Worker specifications only has access to the first two. So your service worker receives the list of headers at the moment before those other headers are even added.

The Fetch specification also includes a list of forbidden header names that client code can never set under any circumstances; these headers are entirely controlled by the user agent. There are also other mechanisms that limit client code access to header lists, like those related to CORS.

The reason for all this is indeed security: this guarantees that certain headers cannot be read or tampered with by malicious script code attempting to perform request forgery (crafting a malicious header that the server may rely on coming from a trusted source), browser fingerprinting (identifying the user by HTTP headers) or secret extraction (e.g. exfiltrating cookies from request headers).

Source: stackoverflow
Text is available under the Creative Commons Attribution-ShareAlike License; additional terms may apply. By using this site, you agree to the Privacy Policy, and Copyright Policy. Content is available under CC BY-SA 3.0 unless otherwise noted. The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 ยฉ No Copyrights, All Questions are retrived from public domain..