There were many problems with the code you posted, probably transpiling errors. I rewrote the code manually and it works.
private long lastPushTime = 0;
private static final char[] CHARS = "-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz".toCharArray();
private final char[] lastRandChars = new char[12];
@SimpleFunction(description = "generates a unique alphanumeric 'timestamped' UID")
public String UID() {
long now = System.currentTimeMillis();
boolean duplicateTime = now == lastPushTime;
lastPushTime = now;
// first part
StringBuilder id = new StringBuilder();
for (int i = 7; i >= 0; i--) {
id.append(CHARS[(int) (now % 64)]);
now = (long) Math.floor((double) now / 64);
}
// second part
if (!duplicateTime) {
for (int i = 0; i < 12; i++) {
lastRandChars[i] = (char) Math.floor(Math.random() * 64);
}
} else {
for (int i = 11; i >= 0 && lastRandChars[i] == 63 ; i--) {
lastRandChars[i] = 0;
}
}
for (int i = 0; i < 12; i++) {
id.append(CHARS[Math.min(lastRandChars[i], 61)]);
}
return id.toString();
}
Also as a note, if you are planning to use the UUID generated from this as unique identifier, I would recommend not, there are well advanced and tested algorithms implemented such as UUID.randomUUID()
The list generated from your code will not sort alpha-numerically by time though (time is represented by characters...), whereas even without sorting, you can see that the list from the original code is in order.
I revisited your code for the extension you kindly created, to see if I could understand why the output did not "look like" the output from the javascript version.
Running the two side by side I eventually saw that the first eight characters were in reverse!
I added some code to fix this, and now they do look similar. I am not sure though if the remaining 12 characters are also in reverse (although I am not sure if it matters)?
Revised example output: -NpRDVMcurjmxlt5NC4O //extension -NpRDVMOBDKzr_7Fwk-a //javascript
Revised extension code:
package uk.co.metricrat.generateuid;
import com.google.appinventor.components.annotations.SimpleFunction;
import com.google.appinventor.components.runtime.AndroidNonvisibleComponent;
import com.google.appinventor.components.runtime.ComponentContainer;
import java.util.*;
public class GenerateUID extends AndroidNonvisibleComponent {
public GenerateUID(ComponentContainer container) {
super(container.$form());
}
// Timestamp of last push, used to prevent local collisions if you push twice in one ms.
private long lastPushTime = 0;
// Modeled after base64 web-safe chars, but ordered by ASCII.
private static final char[] PUSH_CHARS = "-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz".toCharArray();
// Generate 72-bits of randomness which get turned into 12 characters and
// appended to the timestamp to prevent collisions with other clients.
// Store the last characters generated because in the event of a collision,
// Use those same characters except "incremented" by one.
private final char[] lastRandChars = new char[12];
@SimpleFunction(description = "generates a unique alphanumeric 'timestamped' UID")
public String UID() {
long now = System.currentTimeMillis();
boolean duplicateTime = now == lastPushTime;
lastPushTime = now;
// part one
StringBuilder id = new StringBuilder();
for (int i = 7; i >= 0; i--) {
id.append(PUSH_CHARS[(int) (now % 64)]);
now = (long) Math.floor((double) now / 64);
}
// part two
if (!duplicateTime) {
for (int i = 0; i < 12; i++) {
lastRandChars[i] = (char) Math.floor(Math.random() * 64);
}
} else {
// If the timestamp hasn't changed since last push, use the same random number, except incremented by 1.
int j;
for ( j = 11; j >= 0 && lastRandChars[j] == 63 ; j--) {
lastRandChars[j] = 0;
}
lastRandChars[j]++;
}
// reverse part one of the uid string to ensure alphanumeracy
StringBuilder idrev = id.reverse();
for (int i = 0; i < 12; i++) {
idrev.append(PUSH_CHARS[lastRandChars[i]]);
}
return idrev.toString();
}
}