Thursday, June 25, 2026

Menelpon keluar negeri berdasarkan operator dan NATO phonetic alphabet

Menelpon keluar negeri berdasarkan operator 

  1.  telkomsel/by.u
    1. 01017+[nomor_lengkap] tarif Rp. 350 per menit terbatas negara: Australia, Bangladesh, Brunei Darussalam, China, Hong Kong, India, Malaysia, Singapura, Korea Selatan, Thailand, dan Amerika Serikat/Kanada (tidak termasuk destinasi Hawaii)
    2. 007+[nomor_lengkap] tarif Rp. 4.550 per menit
  2. indosat im3
    1. 001+[nomor_lengkap] atau 008+[nomor_lengkap] tarif cek https://im3.id/portal/id/psinternationalcallandsms contoh australia Rp. 5.000 per menit.
    2. 01016+[nomor_lengkap] tarif cek https://im3.id/portal/id/psinternationalcallandsms contoh australia Rp. 1.500 per menit.
  3. xl (tidak diinformasikan secara resmi di xl.co.id
    • 01000+[nomor_lengkap] atau 01017 +[nomor_lengkap], memerlukan paket Nelpon Internasional XL
  4. three/3
    1. 001+[nomor_lengkap] atau 008+[nomor_lengkap], memerlukan paket Paket Nelpon Luar Negeri, contoh australia Rp. 7.350 per menit 
    2. 01016+[nomor_lengkap], memerlukan paket Paket Nelpon Luar Negeri, contoh australia Rp. 1.500 per menit.  
    3. paket yang tersedia https://tri.co.id/nelpon-luar-negeri
      1. Nelpon Luar Negeri     30     1 Hari     30 Menit
      2. Nelpon Luar Negeri     100     30 Hari     100 Menit 

 

NATO phonetic alphabet:

  1. A – Alfa
  2. B – Bravo
  3. C – Charlie
  4. D – Delta
  5. E – Echo
  6. F – Foxtrot
  7. G – Golf
  8. H – Hotel
  9. I – India
  10. J – Juliett
  11. K – Kilo
  12. L – Lima
  13. M – Mike
  14. N – November
  15. O – Oscar
  16. P – Papa
  17. Q – Quebec
  18. R – Romeo
  19. S – Sierra
  20. T – Tango
  21. U – Uniform
  22. V – Victor
  23. W – Whiskey
  24. X – X-ray
  25. Y – Yankee
  26. Z – Zulu  

 

ETLE dan stnk terblokir saat perpanjangan

Sebelum perpanjangan stnk coba cek dulu, apakah kendaraan di blok terkait etle (Electronic Traffic Law Enforcement). jangan sampai di samsat baru buka blokiran ya, lama banget. 

Siapkan 

  1. Nomor kendaraan
  2. Nomor kerangka kendaraan
  3. Nomor mesin kendaraan

Buka internet melalui browser lalu cari "ETLE PMJ" melalui mesin pencari. ini link-nya https://etle-pmj.id/ , namun bisa berubah tergantung kondisi.

Masuk menu cek data, dan masukan data yang telah disiapkan. bila kendaraan kamu terkena etle, pastikan itu memang kendaraan milik anda. bila benar anda bisa melakukan konfirmasi. bila tidak benar anda bisa menyanggahnya.

Bila kendaraan terkena etle saat konfirmasi anda akan diminta melengkapi data pribadi untuk dapat dihubungi. berikan data yang benar. Setelah itu anda akan menerima surat perintah bayar dengan nomor "BRIVA" yang berupa 15 angka. Lakukan deposit denda melalui bank bri atau aplikasi bri. Dari bank lain, jumlah tidak muncul. setelah pembayaran, blokir stnk terbuka. 

Note: pastikan anda telah membayar semua pelanggaran yang tertangkap etle.

Setelah dibayar, akan muncul konfirmasi dan anda akan menerima pesan tanggal sidang dan "No Blanko Tilang". 

melalui browser cari "ETLE kejaksaan" atau https://tilang.kejaksaan.go.id/be/ untuk mengecek sidang anda.

setelah tanggal sidang anda bisa melihat besaran denda tilang yang dibebankan ke anda. bisa kurang atau lebih bayar tergantung putusan sidang. 

Wednesday, June 17, 2026

Android java: migrate build to gradle version catalog

create a new gradle catalog, project -> gradle -> new -> Version Catalog, it will prompt "lib" and press enter.

fill libs.version.toml with agp version


[versions]
agp = "9.2.1"
appcompat = "1.7.1"
material = "1.14.0"
constraintlayout = "2.2.1"
junit = "4.13.2"
androidx-junit = "1.3.0"
espresso-core = "3.7.0"
play-services-ads-lite = "25.0.0"

[libraries]
appcompat = { module = "androidx.appcompat:appcompat", version.ref = "appcompat" }
material = { module = "com.google.android.material:material", version.ref = "material" }
constraintlayout = { module = "androidx.constraintlayout:constraintlayout", version.ref = "constraintlayout" }

junit4 = { module = "junit:junit", version.ref = "junit" }
androidx-junit = { module = "androidx.test.ext:junit", version.ref = "androidx-junit" }
espresso-core = { module = "androidx.test.espresso:espresso-core", version.ref = "espresso-core" }

play-services-ads-lite = { module = "com.google.android.gms:play-services-ads-lite", version.ref = "play-services-ads-lite" }

[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }

agp in [version] and [plugin] must exist.

edit build.gradle.kts

change


dependencies {

    implementation("androidx.appcompat:appcompat:1.7.0")
    implementation("com.google.android.material:material:1.12.0")
    implementation("androidx.constraintlayout:constraintlayout:2.1.4")
    testImplementation("junit:junit:4.13.2")
    androidTestImplementation("androidx.test.ext:junit:1.2.1")
    androidTestImplementation("androidx.test.espresso:espresso-core:3.6.1")
    implementation("com.google.android.gms:play-services-ads-lite:23.3.0")
}

 to


dependencies {

    implementation(libs.appcompat)
    implementation(libs.material)
    implementation(libs.constraintlayout)

    implementation(libs.play.services.ads.lite)

    testImplementation(libs.junit4)
    androidTestImplementation(libs.androidx.junit)
    androidTestImplementation(libs.espresso.core)
}

Synchronize project and change


plugins {
    id("com.android.application")
}

to


plugins {
    alias(libs.plugins.android.application)
} 



Wednesday, June 10, 2026

Java: reading config.conf file

example config.conf


# http and https ports configuration
http_port = 48001
https_port = 48001

# printer port
printer_port=/dev/rfcomm0
# printer size
printer_size=80mm

java code


    // configuration file config.conf
    static final String linux_file_path = "/etc/dddtescpos/config.conf";
    static final String file_path = "./config.conf";

    public static String printer_port = null;
    public static String printer_size = null;
    
    public static int http_port = -1;
    public static int https_port = -1;
    
    public static void readConfig() {
        Path configFile = Paths.get(linux_file_path);
        
        if (Files.notExists(configFile)) {
            configFile = Paths.get(file_path);
        }
        
        // comment in config file will # or !
        Properties props = new Properties();

        try (InputStream input = Files.newInputStream(configFile)) {
            props.load(input);
        
            printer_port = props.getProperty("printer_port");
            printer_size = props.getProperty("printer_size");
            if (printer_size == null || printer_size.isBlank()) {
                printer_size = "80mm";   // default
            } else {
                printer_size = printer_size.trim().toLowerCase();

                if (!printer_size.equals("58mm")
                        && !printer_size.equals("80mm")) {
                    printer_size = "80mm";   // default for invalid value
                }
            }


            String tmpPort = props.getProperty("http_port","48001");
            try {
                int intTmpPort = Integer.parseInt(tmpPort); 
                if (intTmpPort<48000 || intTmpPort>65535)
                    intTmpPort = 48001;
                    http_port = intTmpPort;
            } catch (NumberFormatException ex) {
                http_port = 48001;
            }
            tmpPort = props.getProperty("https_port","48002");
            try {
                int intTmpPort = Integer.parseInt(tmpPort); 
                if (intTmpPort<48000 || intTmpPort>65535)
                    intTmpPort = 48002;
                https_port = intTmpPort;
            } catch (NumberFormatException ex) {
                https_port = 48002;
            }
            // if ports hava equal value, set default
            if (http_port == https_port) {
                http_port = 48001;
                https_port = 48002;
            }
        } catch (IOException ex) {
            System.out.println("No Configuration file found");
            http_port = 48001;
            https_port = 48002;            
        }
        
    }

 

Monday, June 8, 2026

Java: http and https (self sign certificate)

install mkcert


# apt install mkcert

go to root of netbeans project and create self sign certificate


$ mkcert localhost
Created a new local CA 💥
Note: the local CA is not installed in the system trust store.
Note: the local CA is not installed in the Firefox and/or Chrome/Chromium trust store.
Run "mkcert -install" for certificates to be trusted automatically ⚠️

Created a new certificate valid for the following names 📜
 - "localhost"

The certificate is at "./localhost.pem" and the key at "./localhost-key.pem" ✅

It will expire on 8 September 2028 🗓

Convert to PKCS 12


$ openssl pkcs12 -export \
  -in localhost.pem \
  -inkey localhost-key.pem \
  -out localhost.p12 \
  -name localhost
Enter Export Password:
Verifying - Enter Export Password:

main java code


/*
 * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
 */

package com.dedetok.ddtescpos;

import com.alibaba.fastjson2.JSONObject;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpServer;
import com.sun.net.httpserver.HttpsConfigurator;
import com.sun.net.httpserver.HttpsExchange;
import com.sun.net.httpserver.HttpsServer;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.nio.charset.StandardCharsets;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;


/**
 *
 * @author dedetok
 */
public class DdtEscPos {

    final static String serviceString = "DdtEscPos";
    final static String serviceVersion = "1.0";
    
    public static void main(String[] args) {
        System.out.println("DdtEscPos reading configuration file");
        MyController.readConfig(); // if configuration not available, use hard code config
        
        System.out.println(serviceString+" "+serviceVersion);
        
        // ================= 
        try {
            HttpServer httpServer = createHttpService(MyController.http_port);
            HttpsServer httpsServer = createHttpsService(MyController.https_port);
            
            Runtime.getRuntime().addShutdownHook(new Thread(() -> {
                System.out.println("Stopping HTTP & HTTPS server...");
                httpServer.stop(5); // stop 5 second
                System.out.println("HTTP server stopped");
                httpsServer.stop(5); // stop 5 second
                System.out.println("HTTPS server stopped");

            }));
            httpServer.start();
            System.out.println("HTTP server running on http://localhost:" + MyController.http_port);
            httpsServer.start();
            System.out.println("HTTPS server running on http://localhost:" + MyController.https_port);

        } catch (IOException | KeyStoreException | NoSuchAlgorithmException | CertificateException | UnrecoverableKeyException | KeyManagementException ex) {
            System.getLogger(DdtEscPos.class.getName()).log(System.Logger.Level.ERROR, (String) null, ex);
        }
    }

    /*
     * create http service in httpPort
     */
    static HttpsServer createHttpsService(int httpsPort) throws IOException, KeyStoreException, NoSuchAlgorithmException, CertificateException, UnrecoverableKeyException, KeyManagementException {
        // Load PKCS12 keystore
        char[] password = "escpos".toCharArray();
        KeyStore ks = KeyStore.getInstance("PKCS12");
        try (FileInputStream fis = new FileInputStream("localhost.p12")) {
            ks.load(fis, password);
        }

        KeyManagerFactory kmf = KeyManagerFactory.getInstance(
                KeyManagerFactory.getDefaultAlgorithm());
        
        kmf.init(ks, password);

        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(kmf.getKeyManagers(), null, null);

        // Create HTTPS server
        HttpsServer httpsServer =
                HttpsServer.create(
                        new InetSocketAddress("localhost", httpsPort),
                        0);        
    
        httpsServer.setHttpsConfigurator(new HttpsConfigurator(sslContext));
        
        // Register endpoints
        httpsServer.createContext("/", DdtEscPos::handleHttpRequest);
        httpsServer.createContext("/printjson", DdtEscPos::handlePrintJson);        
        
        return httpsServer;
    }
    
    /*
     * create http service in httpPort
     */
    static HttpServer createHttpService(int httpPort) throws IOException {
        HttpServer httpServer =
                HttpServer.create(new InetSocketAddress("localhost", httpPort), 0);
        
        httpServer.createContext("/", DdtEscPos::handleHttpRequest);
        httpServer.createContext("/printjson", DdtEscPos::handlePrintJson);
        return httpServer;
    }

    /*
     * handling /
     */
    static void handleHttpRequest(HttpExchange exchange) throws IOException {
        // CORS
        exchange.getResponseHeaders().add(
                "Access-Control-Allow-Origin", "*");

        exchange.getResponseHeaders().add(
                "Access-Control-Allow-Headers",
                "Content-Type, Authorization");

        exchange.getResponseHeaders().add(
        "Access-Control-Allow-Methods",
        "GET, POST, OPTIONS");

        if ("OPTIONS".equalsIgnoreCase(exchange.getRequestMethod())) {
            exchange.sendResponseHeaders(204, -1);
            return;
        }
        
        // UTF-8 text response
        exchange.getResponseHeaders().add(
                "Content-Type",
                "text/plain; charset=UTF-8");
        
        String response = infoService(exchange).toString();

        byte[] responseBytes = response.getBytes(StandardCharsets.UTF_8);

        exchange.sendResponseHeaders(200, responseBytes.length);

        
        try (OutputStream os = exchange.getResponseBody()) {
            os.write(responseBytes);
        }
        System.out.println("Servicing client done"); // debug
    }

    /*
     * handling /printjson
     */
    static void handlePrintJson(HttpExchange exchange) throws IOException {
        // CORS
        exchange.getResponseHeaders().add(
                "Access-Control-Allow-Origin", "*");

        exchange.getResponseHeaders().add(
                "Access-Control-Allow-Headers",
                "Content-Type, Authorization");

        exchange.getResponseHeaders().add(
        "Access-Control-Allow-Methods",
        "GET, POST, OPTIONS");

        if ("OPTIONS".equalsIgnoreCase(exchange.getRequestMethod())) {
            exchange.sendResponseHeaders(204, -1);
            return;
        }
        
        // UTF-8 text response
        exchange.getResponseHeaders().add(
                "Content-Type",
                "text/plain; charset=UTF-8");
        // get json from request
        // Read request body
        String requestBody;
        try (InputStream is = exchange.getRequestBody()) {
            requestBody = new String(is.readAllBytes(), StandardCharsets.UTF_8);
            // Parse JSON
            // Parse JSON and process
            JSONObject json = JSONObject.parseObject(requestBody);

            JSONObject responseJson = infoService(exchange);
            
            try {
                MyController.printJson(json.toString());


                responseJson.put("status", "printing done");
            } catch (IOException ex) {
                responseJson.put("status", "printing fail");
                responseJson.put("error", ex.getMessage());
                
            }
            
            byte[] bytes =
                responseJson.toString().getBytes(StandardCharsets.UTF_8);

            exchange.sendResponseHeaders(200, bytes.length);
            OutputStream os = exchange.getResponseBody();
            os.write(bytes);
            os.flush();

        }
    }
    
    /* 
     * standard info response 
     */
    static JSONObject infoService(HttpExchange exchange) {
        JSONObject jsonObj = new JSONObject();
        
        jsonObj.put("version", serviceVersion);
        jsonObj.put("service", serviceString);
        jsonObj.put("status", "running");
        String host = exchange.getLocalAddress().getHostString();
        int port = exchange.getLocalAddress().getPort();

        String scheme = (exchange instanceof HttpsExchange)
        ? "https://"
        : "http://";
        
        String baseUrl = scheme + host + ":" + port;
        jsonObj.put("endpoint",baseUrl+"/printjson");
        
        return jsonObj;
    }
}

to run service


$ java -jar target/DdtEscPos-1.0.jar 
Hello World!
HTTP server running on http://localhost:50001
HTTPS server running on https://localhost:50002
Serviing client done
Serviing client done

using curl to send json to print http


$ curl -H "Content-Type: application/json" \
     -d @exampleescpos.json \
     http://localhost:50001/printjson

https


$ curl -k \
  -H "Content-Type: application/json" \
  -d @exampleescpos.json \
  https://localhost:50002/printjson

or 


$ curl --insecure \
  -H "Content-Type: application/json" \
  -d @exampleescpos.json \
  https://localhost:50002/printjson

Credit: esc html using https://www.freeformatter.com/html-escape.html