Categories
discuss

Gradle sync failed after restarting android studio, Cannot convert string value ‘ML_MODEL_BINDING’

I did ‘Invalidate Caches/Restart’ in Android studio and then I got this error while syncing gradle.

Cannot convert string value ‘ML_MODEL_BINDING’ to an enum value of type ‘com.android.builder.model.AndroidGradlePluginProjectFlags$BooleanFlag’ (valid case insensitive values: APPLICATION_R_CLASS_CONSTANT_IDS, TEST_R_CLASS_CONSTANT_IDS, TRANSITIVE_R_CLASS, JETPACK_COMPOSE)

I am using gradle 4.1.0-alpha05

classpath 'com.android.tools.build:gradle:4.1.0-alpha05'

I have tried clean project, rebuild project, deleted the build files and restarted Android Studio. Nothing worked

Thanks in advance

Answer

Had the same problem on IntelliJ 2020.1.3 .

What worked for me was updating gradle versions to the highest available:

in file build.gradle (project)

dependencies {
        classpath 'com.android.tools.build:gradle:4.1.0-beta03'

in file gradle-wrapper.properties

distributionUrl=https://services.gradle.org/distributions/gradle-6.5-all.zip
Categories
discuss

How to create such shape using javaFx TriangleMesh?

I need to create this shape. I understand how to create simple shapes such as a cube, but I don’t understand at all how to create such a shape. How to get the right points for these arrays? Please, help

    TriangleMesh mesh = new TriangleMesh();

    mesh.getPoints().addAll(
            0, 0, 0,//P1
            0,0,100,//P2
            0,20,100,//P3
            60,20,100,//P4
            60,0,100,//P5
            60,20,60,//P6
            60,0,60,//P7
            40,0,60,//P8
            40,20,60,//P9
            40,20,0,//P10
            40,0,0,//P11
            0,20,0//P12
    );

    mesh.getTexCoords().addAll(
     //which points should be here?
    );

    mesh.getFaces().addAll(
   // which points should be here?
               );
    return mesh;

`

I need to create this shape

Answer

There are several ways you can construct a 3D shape like the one you have posted.

3D Modeling

Probably the easiest way is by using a 3D editor, like Blender (open source), and then exporting the model to an .OBJ file. In this OBJ file you will get a list of vertices, textures and faces. However, the format is not readable directly, so you can’t just feed it into a JavaFX MeshView. However, there are importers of this format, that will create a TriangleMesh, like this one.

JCSG

Without dealing with point, vertices and faces, but from a Java approach, another option is to use JCSG: you can just create two cubes, and do a boolean operation to get the desired shape (subtract a 20x20x60 cube from a 60x20x100 cube). There is also a way to convert the CSG object into a TriangleMesh.

FXyz3D

From a pure JavaFX perspective, you can also use the FXyz3D library and its TriangulatedMesh. Is is based on a flat surface with a list of 3D points ({x, y, 0}) that define its perimeter, that is triangulated and extruded to a given height. Internally it uses Poly2Tri, which precisely is a 2D constrained Delaunay triangulation library.

Since you need a flat surface on XY, I’ll rewrite your list of points into:

private final List<Point3D> points = new ArrayList<>(Arrays.asList(
            new Point3D(0,   0, 0),
            new Point3D(0, 100, 0), new Point3D(60, 100, 0),
            new Point3D(60, 60, 0), new Point3D(40, 60,  0),
            new Point3D(40,  0, 0), new Point3D( 0,  0,  0)));

and then the shape can be generated with:

TriangulatedMesh customShape = new TriangulatedMesh(points, 20);
customShape.setLevel(0);
customShape.setCullFace(CullFace.NONE);
customShape.getTransforms().addAll(new Rotate(-90, Rotate.X_AXIS));

(note the rotation will put the flat surface from plane XY into plane XZ as in your drawing)

TriangulatedMesh

You can now inspect the generated mesh, and you will see all the triangles generated:

Line and Fill Meshes

so you can use this information to “fill” your points, texture and faces arrays, and find out how it works.

TriangleMesh

Finally, starting from the scratch, but based on the above triangulation, these are the required arrays:

Vertices

float[] vertices = {
         0.0,  0.0,   0.0,  // 0
         0.0,  0.0, 100.0,  // 1
        60.0,  0.0, 100.0,
        60.0,  0.0,  60.0,
        40.0,  0.0,  60.0,
        40.0,  0.0,   0.0,
         0.0, 20.0,   0.0,
         0.0, 20.0, 100.0,
        60.0, 20.0, 100.0,
        60.0, 20.0,  60.0,
        40.0, 20.0,  60.0,
        40.0, 20.0,   0.0};   // 11

vertices

Texture coordinates

These can be generated, for instance, based on a 2D surface with dimension 1×1, so vertices coordinates can be mapped easily with this expression: {x / (MaxX-MinX), y /(MaxY-MinY)}.

float[] texture = {
        0.00, 0.00,        // 0
        0.00, 1.00,        // 1
        1.00, 1.00,
        1.00, 0.60,
        0.67, 0.60,
        0.67, 0.00,
        0.00, 0.00,
        0.00, 1.00,
        1.00, 1.00,
        1.00, 0.60,
        0.67, 0.60,
        0.67, 0.00};        // 11

Faces

We’ll add the indices of 3 vertices and 3 texture coordinate for each triangular face.

int[] faces = {
         1,  1,  2,  2,  4,  4,      // 0
         4,  4,  2,  2,  3,  3,      // 1
         1,  1,  4,  4,  0,  0,      // 2
         0,  0,  4,  4,  5,  5,
         7,  7, 10, 10,  8,  8,
        10, 10,  9,  9,  8,  8,
         7,  7,  6,  6, 10, 10,
         6,  6, 11, 11, 10, 10,
         0,  0,  1,  1,  7,  7,
         0,  0,  7,  7,  6,  6,
         1,  1,  2,  2,  8,  8,
         1,  1,  8,  8,  7,  7,
         2,  2,  3,  3,  9,  9,
         2,  2,  9,  9,  8,  8,
         3,  3,  4,  4, 10, 10,
         3,  3, 10, 10,  9,  9,
         4,  4,  5,  5, 11, 11,
         4,  4, 11, 11, 10, 10,
         5,  5,  0,  0,  6,  6,
         5,  5,  6,  6, 11, 11};     // 19

For instance, for the top surface, there are four triangles defined, and the first one (0) has vertices (1, 2, 4), the second one (1) has vertices (4, 2, 3), and so on:

Faces

In this case, the coordinate textures have the same indices as the vertices (but this could be different). Note the vertex winding or anti-clockwise rotation.

EDIT

If you don’t use normals, it is convenient to add face smoothing groups: each group contains the faces indices that belong to a same flat surface. For instance, the first four indices belong to the top surface.

int[] smooth = {0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7};

And this is the whole code to create your custom MeshView node:

private final float[] vertices = {
             0.0f,  0.0f,   0.0f,  // 0
             0.0f,  0.0f, 100.0f,  // 1
            60.0f,  0.0f, 100.0f,
            60.0f,  0.0f,  60.0f,
            40.0f,  0.0f,  60.0f,
            40.0f,  0.0f,   0.0f,
             0.0f, 20.0f,   0.0f,
             0.0f, 20.0f, 100.0f,
            60.0f, 20.0f, 100.0f,
            60.0f, 20.0f,  60.0f,
            40.0f, 20.0f,  60.0f,
            40.0f, 20.0f,   0.0f};   // 11

    private final float[] texture = {
            0.00f, 0.00f,        // 0
            0.00f, 1.00f,        // 1
            1.00f, 1.00f,
            1.00f, 0.60f,
            0.67f, 0.60f,
            0.67f, 0.00f,
            0.00f, 0.00f,
            0.00f, 1.00f,
            1.00f, 1.00f,
            1.00f, 0.60f,
            0.67f, 0.60f,
            0.67f, 0.00f};        // 11

    private final int[] faces = {
            1,  1,  2,  2,  4,  4,      // 0
            4,  4,  2,  2,  3,  3,      // 1
            1,  1,  4,  4,  0,  0,      // 2
            0,  0,  4,  4,  5,  5,
            7,  7, 10, 10,  8,  8,
            10, 10,  9,  9,  8,  8,
            7,  7,  6,  6, 10, 10,
            6,  6, 11, 11, 10, 10,
            0,  0,  1,  1,  7,  7,
            0,  0,  7,  7,  6,  6,
            1,  1,  2,  2,  8,  8,
            1,  1,  8,  8,  7,  7,
            2,  2,  3,  3,  9,  9,
            2,  2,  9,  9,  8,  8,
            3,  3,  4,  4, 10, 10,
            3,  3, 10, 10,  9,  9,
            4,  4,  5,  5, 11, 11,
            4,  4, 11, 11, 10, 10,
            5,  5,  0,  0,  6,  6,
            5,  5,  6,  6, 11, 11};     // 19

    private final int[] smooth = {
            0, 0, 0, 0,   // top surface
            1, 1, 1, 1,   // bottom surface
            2, 2,
            3, 3,
            4, 4,
            5, 5,
            6, 6,
            7, 7};

    public MeshView getMeshView() {
        TriangleMesh mesh = new TriangleMesh();
        mesh.getPoints().addAll(vertices);
        mesh.getTexCoords().addAll(texture);
        mesh.getFaces().addAll(faces);
        mesh.getFaceSmoothingGroups().addAll(smooth);

        MeshView meshView = new MeshView(mesh);
        meshView.setMaterial(new PhongMaterial(Color.FIREBRICK));
        meshView.setCullFace(CullFace.NONE);
        return meshView;
    }
Categories
discuss

Filter nested object

I receive an object that looks like this:

 this.tokensData = {
    O: {
        id: 0,
        name: value1,
        organization: organization1,
        ...,
       },
    1: {
        id: 1,
        name: value1,
        organization: organization1,
        ...,
        },
    2: {
        id: 2,
        name: value2,
        organization: organization2,
        ...,
        },
    ...
   }

I want to filter by id and remove the Object which id matches the id I receive from the store. What I tried so far:

const filteredObject = Object.keys(this.tokensData).map((token) => {
  if (this.$store.state.id !== this.tokensData[token].id) {
    return this.tokensData[token];
  }
});

This replaces the Object with undefined – which would work for my purposes but is obviously not ideal. Any help is much appreciated!

Answer

Try to use Object.entries and then Object.fromEntries() to create an object from a list of key-value pairs:

let store = [0 , 1];

const result = Object.entries(tokensData).filter(([k, v]) => !store.some(s => s == v.id));

console.log(Object.fromEntries(result));

An example:

let tokensData = {
   O: {
       id: 0,
       name: '',
       organization: '',
      },
   1: {
       id: 1,
       name: '',
       organization: '',
       },
   2: {
       id: 2,
       name: '',
       organization: '',
       }
  }

let store = [0 , 1];

const result = Object.entries(tokensData).filter(([k, v]) => !store.some(s => s == v.id));

console.log(Object.fromEntries(result));
Categories
discuss

How to check whether Android phone supports TEE?

I have read this two posts: One and Two, but I still have question.

I use KeyStore (Android 9) to generate an AES key, and use isInsideSecureHardware() method to check whether the key isInsideSecureHardware. I got return False. Sample code can be found here, and here.

public boolean isInsideSecureHardware ()

Returns true if the key resides inside secure hardware (e.g., Trusted Execution Environment (TEE) or Secure Element (SE)). Key material of such keys is available in plaintext only inside the secure hardware and is not exposed outside of it.

Thus, I want to further confirm whether my phone device (Huawei P20) supports TEE.

Question:

  1. If the phone supports TEE, the key generated by KeyStore will be store into TEE automatically? Do I Need any manually configuration in Java? I heard that keys will be automatically stored in TEE, as long as you use KeyStore.getInstance(), KeyGenerator
    .getInstance(algorithm, KeyStore Name)
    . But I am not sure this is True or Not?

  2. If the answer of Q1 is “Need manually configuration”, it becomes the reason of isInsideSecureHardware() returns False, right? If the answer of Q1 is “automatically”, ignore Q2.

  3. Any method to directly check whether the phone supports TEE, in Java?

Answer

From the Android keystore system docs:

Supported devices running Android 9 (API level 28) or higher installed can have a StrongBox Keymaster, an implementation of the Keymaster HAL that resides in a hardware security module. The module contains the following:
[…]
* Secure storage.
[…]
When checking keys stored in the StrongBox Keymaster, the system corroborates a key’s integrity with the Trusted Execution Environment (TEE).
[…]
When generating or importing keys using the KeyStore class, you indicate a preference for storing the key in the StrongBox Keymaster by passing true to the setIsStrongBoxBacked() method.

In my understanding that means when you generate a Key and call keyGenParameterSpecBuilder.setIsStrongBoxBacked(true) for the key configuration you can ensure that it’s backed by a TEE. If there is no TEE available, it’ll throw a StrongBoxUnavailableException.

So to check if there’s a TEE available you could just attempt to generate a key this way and see if it works.

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..