Saturday, February 10, 2024

Privacy Policy for Radio Walkman (com.dedetok.RadioWalkman)

Privacy Statement

Your privacy is important to us. This privacy statement explains what Radio Walkman (com.dedetok.RadioWalkman) application does, regarding your personal data.

Personal data we collect

Radio Walkman (com.dedetok.RadioWalkman) application does not requesting any information about your personal data.

Network & Internet Connection:

Radio Walkman (com.dedetok.RadioWalkman) application required internet connection for

  1. Get list of radio from my blogger https://dedetoknotes.blogspot.com/.
  2. Get radio stream from Radio Station Streaming server.
  3. Use to serve Google AdMob.

We do not provide any streaming services. Those streaming services are Radio Station's own and their services may change without any notice that cause this application can not get any radio streaming.

Contact Us:

If You need to contact Us, here is My email address:

dedetoke2021@gmail.com

Wednesday, February 7, 2024

Android java: Tutorial MediaPlayer and Media3 ExoPlayer

Android Studio Hedgehog | 2023.1.2

Note: For personal reference using MediaPlayer and Media3 ExoPlayer in java

build.gradle.kts (Module: app)

dependencies {
    ....
    implementation("androidx.media3:media3-exoplayer:1.2.1") // ExoPlayer
    implementation("androidx.media3:media3-common:1.2.1") // setAudioAttributes; MediaItem
}

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">
    <uses-permission android:name="android.permission.INTERNET" />
...

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.LinearLayoutCompat
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    android:orientation="vertical">
    <androidx.appcompat.widget.AppCompatButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="MediaPlayer"
        android:id="@+id/b_mediaplayer"
        />
    <androidx.appcompat.widget.AppCompatButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="ExoPlayer"
        android:id="@+id/b_exoplayer"
        />
</androidx.appcompat.widget.LinearLayoutCompat>

MyExoPlayer.java

package com.dedetok.tutorialexoplayer;

import android.content.Context;
import android.util.Log;
import androidx.media3.common.MediaItem;
import androidx.media3.exoplayer.ExoPlaypackage com.dedetok.tutorialexoplayer;

import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.AppCompatButton;
import android.os.Bundle;
import android.view.View;

public class MainActivity extends AppCompatActivity {

    MyMediaPlayer myMediaPlayer;
    MyExoPlayer myExoPlayer;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        myMediaPlayer = new MyMediaPlayer();
        myExoPlayer = new MyExoPlayer(this);

        String myRadioUrl = "https://stream-node1.rri.co.id/streaming/25/9025/rrijakartapro1.mp3";
        //String myRadioUrl = "http://cast1.my-control-panel.com/proxy/radioso1/stream";

        AppCompatButton bMediaPlayer = findViewById(R.id.b_mediaplayer);
        bMediaPlayer.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                myExoPlayer.stop();
                myMediaPlayer.play(myRadioUrl);
            }
        });

        AppCompatButton bExoPlayer = findViewById(R.id.b_exoplayer);
        bExoPlayer.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                myMediaPlayer.stop();
                myExoPlayer.play(myRadioUrl);
            }
        });
    }
}er;

public class MyExoPlayer {
    // API level 23 / Android N / Android 6.0
    ExoPlayer myPlayer;

    public MyExoPlayer(Context appContext) {
        myPlayer = new ExoPlayer.Builder(appContext).build();
    }

    public void play(String myRadioUrl) {
        if (myPlayer.isPlaying()) {
            myPlayer.stop();
            Log.e("dedetok", "ExoPlaayer playing Stop"); // debug
        } else {
            try {
                Log.e("dedetok", "ExoPlaayer playing " + myRadioUrl); // debug
                MediaItem myRadio = MediaItem.fromUri(myRadioUrl);
                myPlayer.setMediaItem(myRadio);
                myPlayer.prepare();
                myPlayer.play();
            } catch (IllegalArgumentException e) {
                Log.e("dedetok", "ExoPlayer IllegalArgumentException " + e.getMessage()); // debug
            }
        }
    }

    public void stop() {
        myPlayer.stop();
    }

    public void release() {
        myPlayer.release();
        myPlayer=null;
    }
}

MyMediaPlayer.java

package com.dedetok.tutorialexoplayer;

import android.media.AudioAttributes;
import android.media.MediaPlayer;
import android.util.Log;
import java.io.IOException;

public class MyMediaPlayer implements MediaPlayer.OnPreparedListener, MediaPlayer.OnErrorListener {
    MediaPlayer myPlayer;

    boolean isPrepared= false;

    public MyMediaPlayer() {
        myPlayer = new MediaPlayer();
    }

    public void play(String myRadioUrl) {
        if (myPlayer.isPlaying()) {
            myPlayer.stop();
            myPlayer.reset();
            Log.e("dedetok", "MediaPlayer Stop"); // debug
        } else {
            Log.e("dedetok", "MediaPlayer playing " + myRadioUrl); // debug
            myPlayer.setOnPreparedListener(this);
            myPlayer.setAudioAttributes(
                    new AudioAttributes.Builder()
                            .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
                            .setUsage(AudioAttributes.USAGE_MEDIA)
                            .setLegacyStreamType(AudioAttributes.USAGE_MEDIA)
                            .build()
            );
            myPlayer.setOnErrorListener(this);
            try {
                myPlayer.setDataSource(myRadioUrl);
                isPrepared=true;
                myPlayer.prepareAsync();
            } catch (IOException e) {
                Log.e("dedetok", "IOException " + e.getMessage()); // debug
            } catch (IllegalArgumentException e) {
                Log.e("dedetok", "IllegalArgumentException " + e.getMessage()); // debug
            }
        }
    }

    @Override
    public void onPrepared(MediaPlayer mediaPlayer) {
        /*
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            if (mediaPlayer.getDrmInfo() != null) {
                myPlayer.prepareDrm();
                //myPlayer.getKeyRequest();
                //myPlayer.provideKeyResponse();
            }
        }

         */
        myPlayer.start();
        isPrepared=false;
    }

    public void stop() {
        if (!isPrepared) {
            myPlayer.stop();
            myPlayer.reset();
            isPrepared = false;
        } else {
            myPlayer.reset();
            isPrepared = false;
        }
    }

    @Override
    public boolean onError(MediaPlayer mediaPlayer, int what, int extra) {
        String tmp="";
        if (what == MediaPlayer.MEDIA_ERROR_UNKNOWN)
            tmp = "MediaPlayer.MEDIA_ERROR_UNKNOWN";
        if (what == MediaPlayer.MEDIA_ERROR_SERVER_DIED)
            tmp = "MediaPlayer.MEDIA_ERROR_SERVER_DIED";
        if (extra == MediaPlayer.MEDIA_ERROR_IO)
            tmp+=" MediaPlayer.MEDIA_ERROR_IO";
        if (extra == MediaPlayer.MEDIA_ERROR_MALFORMED)
            tmp+=" MediaPlayer.MEDIA_ERROR_MALFORMED";
        if (extra == MediaPlayer.MEDIA_ERROR_UNSUPPORTED)
            tmp+=" MediaPlayer.MEDIA_ERROR_UNSUPPORTED";
        if (extra == MediaPlayer.MEDIA_ERROR_TIMED_OUT)
            tmp+=" MediaPlayer.MEDIA_ERROR_TIMED_OUT";

        Log.e("dedetok", "OnErrorListener " + tmp); // debug
        myPlayer.reset();
        isPrepared=false;
        return true;
    }

    public void release() {
        myPlayer.release();
        myPlayer=null;
    }
}

MainActivity.java

package com.dedetok.tutorialexoplayer;

import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.AppCompatButton;
import android.os.Build;
import android.os.Bundle;
import android.view.View;

public class MainActivity extends AppCompatActivity {

    MyMediaPlayer myMediaPlayer;
    MyExoPlayer myExoPlayer;
    int buildVersion=0;
    /*
     * ## activity life cycle 1 ##
     */
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        buildVersion = Build.VERSION.SDK_INT; // get android version from device

        String myRadioUrl = "https://stream-node1.rri.co.id/streaming/25/9025/rrijakartapro1.mp3";
        //String myRadioUrl = "http://cast1.my-control-panel.com/proxy/radioso1/stream";

        AppCompatButton bMediaPlayer = findViewById(R.id.b_mediaplayer);
        bMediaPlayer.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                myExoPlayer.stop();
                myMediaPlayer.play(myRadioUrl);
            }
        });

        AppCompatButton bExoPlayer = findViewById(R.id.b_exoplayer);
        bExoPlayer.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                myMediaPlayer.stop();
                myExoPlayer.play(myRadioUrl);
            }
        });
    }

    /*
     * ## activity life cycle 2 ##
     */
    @Override
    protected void onStart() {
        super.onStart();
        // Android N Android 7
        if (buildVersion>= Build.VERSION_CODES.N) {
            myMediaPlayer = new MyMediaPlayer();
            myExoPlayer = new MyExoPlayer(this);
        }
    }

    /*
     * ## activity life cycle 3 ##
     */
    @Override
    protected void onResume() {
        super.onResume();
        // Android N Android 7
        if (buildVersion< Build.VERSION_CODES.N) {
            myMediaPlayer = new MyMediaPlayer();
            myExoPlayer = new MyExoPlayer(this);
        }
    }

    /*
     * ## activity life cycle 4 ##
     */
    @Override
    protected void onPause() {
        if (buildVersion<Build.VERSION_CODES.N) {
            myMediaPlayer.release();
            myMediaPlayer=null;
            myExoPlayer.release();
            myExoPlayer=null;
        }
        super.onPause();
    }

    /*
     * ## activity life cycle 5 ##
     */
    @Override
    protected void onStop() {
        if (buildVersion>=Build.VERSION_CODES.N) {
            myMediaPlayer.release();
            myMediaPlayer=null;
            myExoPlayer.release();
            myExoPlayer=null;
        }
        super.onStop();
    }

    /*
     * ## activity life cycle 6 ##
     */

    @Override
    protected void onDestroy() {
        super.onDestroy();
    }
}

Pron using ExoPlayer:

  1. ExoPlayer can handle https media streaming for self signing sertificate but MediaPlayer can not.
  2. Handing media streaming in ExoPlayer uses less code then MediaPlayer.

Cons using ExoPlayer

  • ExoPlayer required minimum API level 23 / Android N / Android 6.0


Monday, January 29, 2024

Jsoup extracting table element

Eclipse 2023-09

Note: For personal reference using Jsoup in java

  1. create a new project
  2. under project root create folder "lib"
  3. download Jsoup binary (jar file) from https://jsoup.org/download and put in folder "lib". Use the latest one, this example use jsoup-1.17.2.jar
  4. in project properties -> Java Build Path -> Libraries -> Modulepath -> Add external JARs and add your Jsoup binary, Apply and Close

Java code to extract element in table from my blog https://dedetoknotes.blogspot.com/2024/01/my-radio-list.html

package com.dedetok;

import java.io.IOException;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

public class Main {

    public static void main(String[] args) {
        try {
            Document doc = Jsoup.connect("https://dedetoknotes.blogspot.com/2024/01/my-radio-list.html").get();
            if (doc!=null) {
                System.out.println("Ok: "+doc.title()); //debug
                //Elements myTable = doc.getElementsByTag("table");
                Element myTable = doc.getElementById("com.dedetok.myradiolist");
                //System.out.println("size children: "+myTable.childrenSize()); //debug
                Elements myTr = myTable.select("tr");
                System.out.println("number of tr: "+myTr.size());
                //System.out.println(myTr.toString()); //debug

                // iterate row tr
                for (Element e : myTr) {
                    Elements myTd = e.select("td");
                    //System.out.println("number of td: "+myTd.size()); //debug

                    // iterate column td
                    for (Element eTd: myTd) {
                        //get icon url in image or text
                        Element myImg = eTd.select("img").first();
                        if (myImg!=null) {
                            String myIconUrl = myImg.absUrl("src");
                            System.out.print(myIconUrl+"|"+eTd.text()+" ");
                        } else {
                            System.out.print(eTd.text()+";");                           
                        }
                    }
                    System.out.println(); // add a new line
                }
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

For Android Studio 2023.1.1 Patch 1

add build.gradle.kts (Module :app) 

dependencies {
    ...
    implementation("org.jsoup:jsoup:1.17.2") // jsoup
}

 


 

huawei echolife default user for EG & HG series

There are 3 default type/user group available in echolife EG, HG and DSL Home Gateway series, these user name and password are:

type/user group
EG Series HG V300R016C10 and earlier HG V300R017C00 and later DSL Home Gateway
user Epuser/userEp root/admin root/adminHW user/HuaweiUser
admin Epadmin/adminEp root/admin * root/adminHW * user/HuaweiUser *
telnet Eproot/adminEp root/admin * root/adminHW * user/HuaweiUser *

* not tested

if those fail try telecomadmin/admintelecom or admin/@HuaweiHgw or maybe your firmware has been customized by your privder

  1. user: for general use
  2. admin: for more setting then user e.q to change default ntp and time zone; change services
  3. telnet: for connect to router via telnet or SSH

In EG8145V5 default service to access your router are:

  1. Enable the LAN-side PC to access the device using HTTP
  2. Enable devices on the Wi-Fi side to access web pages

Important: 

  1. Change default password immediately and put in a note
  2. DO NOT OPEN ANY SERVICES for WAN

References: https://forum.huawei.com/enterprise/en/huawei-ont-login-account-and-password/thread/667238610795118592-667213871523442688

Friday, January 26, 2024

Personal mysql/mariadb sql command references

Using mysqladmin 

Set password root using mysqladmin

# mysqladmin -u root password

Using mysql client

$ mysql -u [user_name] -p

Show users:

> select User from mysql.user;

Add user:

> create user `test`@`localhost`;
> SELECT User FROM mysql.user;

Set user password

> alter user [user_name] identified by [new_password];

Show database:

> show databases;

Add database:

> create database `test`;
> SHOW DATABASES;
> grant all privileges on test.* to 'test'@'localhost` ;
> flush privileges;

Show table:

> use test;
> show tables;

create table:

> use test;
> create table product(id mediumint, name varchar(100));

Note: Do not use root account to create user table, use particular user to create table.