Fileを入出力するためのクラスを作ってみる
無事忌々しいテストも終わったもんだから
テスト期間中に組んだFileの入出力クラスをメモがてら紹介する
成り立ち
Javaから外部資源としてFileを読み書きするには
少々長ったらしい文を書かなくてはいけない
昔、Androidのクイズアプリを作った際に
CSVで問題データを保持させようということで
そのときに初めてファイルの入出力をいじった
非常に書きにくい
特に当時はリファレンスを見るという力も無かったため
色んな情報に左右されながら長ったらしいコードを書いていた
いま計画中のアプリでもCSVを使おうと思っているのでその前準備
何をするクラスか
大体Javaでファイルを扱うときは(ファイル管理ソフトでも作らない限りは)
新規作成・書き込み・読み込みこのぐらいができれば十分であろう
ついでにファイル削除もつけて、計4機能
こいつらを実装させていく
基本的にError処理は利用者任せにするため、全てthrow
使う機能
機能というと語弊があるかもしれないが気にせずに
今回のクラスはnio
のPaths
を使ってファイルを操作する
ファイルの読みはBufferedReader
、書きはPrintWriter
を使う
とりあえずフィールド変数
今回使用する変数の方々
/**
* ファイルの生成、削除、名前変更を担当
* */
private Path path;
/**
* 文字コード設定のための定数
* */
private static final Charset UTF_8 = Charset.forName("UTF-8");
private static final String BR = System.lineSeparator();
private static final Pattern p = Pattern.compile(BR);
/**
* 読み込み用
* */
private BufferedReader reader;
/**
* 書き込み用
* */
private PrintWriter writer;
private BufferedWriter bufferedWriter;
/**
* 読み込みの際に文字列連結高速化
* */
private StringBuilder content;
今回はちょっとJavaDocも書いてみた
ちょっと変わったところがこの二行
private static final String BR = System.lineSeparator();
private static final Pattern p = Pattern.compile(BR);
一行目は改行コードを取っているのだが
その改行コードがOSによって異なっているので
OSから改行コードをもらってきている
そのOS依存の改行コードを使ってパターンを作っているのが二行目
あとでこれを使ってゴニョゴニョする
今気づいたがあまりこれは意味がない・・・
続いてコンストラクタ
/**
* パスが文字列で与えられたときのコンストラクタ
* @param pathName 操作したいファイルのフルパスを渡す
* */
public FileManager(String pathName) throws IOException {
path = Paths.get(pathName);
init(true);
}
/**
* File型が与えられたときのコンストラクタ
* @param file 操作したいファイルのFile型を渡す
* */
public FileManager(File file) throws IOException {
path = file.toPath();
init(true);
}
/**
* Path型が与えられたときのコンストラクタ
* @param path 操作したいファイルのPath型を渡す
* */
public FileManager(Path path) throws IOException {
this.path = path;
init(true);
}
3種類の型に対応できるようにした
今頃File
という感じもするが
古いAPIだと返り値がFile
ということがあるらしい
init()の内容はその名の通り各フィールド変数の初期化
private void init() throws IOException {
bufferedWriter = Files.newBufferedWriter( path, UTF_8, StandardOpenOption.APPEND);
writer = new PrintWriter(bufferedWriter, true);
reader = Files.newBufferedReader( path, UTF_8 );
content = new StringBuilder();
}
ここで注意しておきたいのが
bufferedWriter = Files.newBufferedWriter( path, UTF_8, StandardOpenOption.APPEND);
StandardOpenOption.APPEND
をしっかりつけないと
実行時にファイルがまっさらになる
ほかは特に注意点なし
bufferedWriter = Files.newBufferedWriter( path, UTF_8, StandardOpenOption.APPEND);
reader = Files.newBufferedReader( path, UTF_8 );
こいつらは省エネな書き方
File file = new File(file_name);
BufferedWriter bw = new BufferedWriter(new FileWriter(file));
これが普通の書き方
最初に紹介したほうが個人的には好き
新規作成・削除
難しい処理は書くことなく、ほぼワンライン
無事に作成・削除できたかを知らせるboolean型の返り値を設定してある
/**
* ファイルを新規作成するためのメソッド
* @return 作成に成功すればTrue, 既にファイルが存在する場合はFalse
* @throws IOException 入出力エラーが発生した場合
* */
public boolean create() throws IOException {
return path.toFile().createNewFile();
}
/**
* ファイルを削除するためのメソッド
* @return 削除に成功すればTrue, 失敗すればFalse
* @throws IOException 入出力エラーが発生した場合
* */
public boolean delete() throws IOException {
Files.delete(path);
return !( exists() );
}
説明はDocに書いてある通り
exists()
っていうのは
ファイルが存在しているかどうかを調べるメソッド
以下の通りワンライン
public boolean exists() {
return Files.exists(path);
}
外からでも有無を確認できるようにpublicにしてある
ここからが本番、読み込み
ここからがようやく本番といった感じ
いかにに無駄なく素早く処理するか
素人ながら色々工夫をして書いた
/**
* ファイルの中身を読み込むためのメソッド
* @return ファイルの中身の文字列
* @throws IOException 入出力エラーが発生した場合
* @throws NullPointerException ファイルが空だった場合
* */
public String read() throws IOException, NullPointerException {
if (exists() && Files.isReadable(path)) {
String buffer;
do {
buffer = reader.readLine();
content.append( buffer ).append( BR );
} while (buffer != null);
return content.toString();
} else if ( !exists() ) {
System.err.println("Couldn't find File");
} else if ( !Files.isWritable(path) ) {
System.err.println("Have no authority to read");
}
return null;
}
最初のif文で存在しているか&読み込み権限があるかを見ている
あとは定型文
これを何回も書きたくないからこのクラスを作ったようなもの
if文でboolen型を!をつけてFalseの場合に反転させているが
== false
で書いたほうが読みやすい気はする
仕上げの書き込み
最後の難関
/**
* ファイルに書き込むためのメソッド
* @param text 書き込みたい内容
* @throws IOException 入出力エラーが発生した場合
* */
public void write(String text) throws IOException {
if (exists() && Files.isWritable(path)) {
if (p.matcher(text).find()) {
String[] buffer = text.split(BR, 0);
for (String line : buffer) {
writer.println(line);
}
} else {
writer.write(text);
}
writer.flush();
} else if ( !exists() ) {
System.err.println("Couldn't find File");
} else if ( !Files.isWritable(path) ) {
System.err.println("Have no authority to write");
}
}
ここで出てくるPattern
もし改行がある場合はそれを反映させ、ない場合はそのまま書き込む
この改行を楽にするためにPrintWriter
を使用している
とは言えどもBufferedWriter
にもnewLine()
なんてのがあるので
素直にBufferedWriter
を使えばよかった気もする
忘れられがちなClose
読み書きのメソッドを見て、close()がないことに気づかれただろう
忘れていたわけではなく、あえて書かなかったのだ
別にメソッドとして定義している
public void close_r() throws IOException {
reader.close();
}
public void close_w() throws IOException {
writer.close();
}
案の定のワンライン
なぜ読み書きの処理に埋め込まずに別途定義しているのか
それはそれぞれのメソッドがエラーを利用者に委ねているため
本来close()
をいうのはfinally
の中に書かなくてはいけない
しかし、エラーを投げてしまっているため
finally
もクソもないのである
そのため、苦肉の策として別途定義することで
利用者側にfinally
でしっかり閉めてもらうことができる
私自身、かなり嫌々この方式を取った
もし何か良い策があったら連絡下さい
最後に
作ってから気づく実際に使えるのか感
実践で使ったことがないので何とも言えないが
あまり使える気がしない
今度使った後に感想でも書くこととしよう
このコードはGithubに上げてある
以下のリンクからすべてを見ることができる
Github上では、今回紹介した以外のメソッドも幾つか書いてあるので
気になる方はぜひご一読を
以上
次はCSVのパーサーでも自作したい
JAVAでコマンド版カウントダウンをしてみる
たまに、Youtubeなどで
コマンドプロンプト上で動くゲームを作る実況動画なるものがあるが
全てC系統で組んでいる
何故JAVAがないのかを考えてみると
System("cls")
がないことに気づく
素直にC系統を勉強して作ればいいだけかもしれないが
応用(と言うなの丸パクリ)してコマンドライン上で動く
カウントダウンアプリ(?)を作ってみる
使うもの
特筆して使うものは以下の2つ
Thread.sleep()
Process(ProcessBuilder)
大まかな仕組み
仕組みというほど大げさなものではないが
Whileループの中でSystem.out.print
を使って一秒単位で画面上に秒数を表示する
画面の更新にはSE7から追加されたProcess
を使う
1,2共にエラーをTry-catchしないといけないので
前回同様実装時には適切なエラー処理を
ソースコード
public class Main {
public static void main ( String[] args ) {
int c = 0;
ProcessBuilder pb = new ProcessBuilder( "cmd", "/c", "cls" );
while ( c < 10 ) {
try {
pb.inheritIO().start().waitFor();
System.out.print( c ); //printlnではなくprint
Thread.sleep( 1000 );
} //以下エラー処理(省略)
catch( InterruptedException iue ){}
catch( IOException ioe ){}
c++;
}
}
}
これぞ5分クオリティ
解説(と言うかメモ)
見て一発でわかるプログラムなもんだから書くことなどなにもないのだが
ProcessBuilder pb = new ProcessBuilder( "cmd", "/c", "cls" );
pb.inheritIO().start().waitFor();
参考にしたサイトの方がよくわからないと仰っていたこの部分だけ調べたのでメモ
参考サイトの方では変数を使わず直接繋げてやっていられた
個人的にはこっちのほうが理解しやすかったのと
Whileの中でインスタンスを毎回生成すると言う無駄なことを防ぐためにこうした
一行目は普通のインスタンス作成
どうやら第一引数に起動したいプログラム名(?)
それ以降にそれぞれ分けてそのコマンドの引数
上記だと
コマンドプロンプト上でcls
を実行する
というProcessBuilder
のインスタンスを作ることになる
次の行は1つずつ分解して考えてみる
inheritIO()
返り値はProcess
であることに注意
リファレンスを見てみると
サブプロセスの標準入出力の入力元と出力先を、現在の Java プロセスと同じものに設定します。
とある
簡単に言えば
”結果をいま実行しているコマンドライン上に表示する”といった感じ(あくまでも感じ)
今回はcls
なので動かしているコマンドライン上の画面がクリアされる
start()
これも返り値はProcess
名前の通り登録したプロセスを実行するメソッド
コヤツはいくつかエラーを吐くので
詳しくはこちらを確認
waitFor()
ラスト
返り値はint型、所謂終了コードを返してくれる
これは要求したプロセス(ここではcls
)が終了するまで
JAVAの処理を中断するというもの
以上
これで二行目の文の説明(?)終了
もう少し実用的にするのであれば
最初に数値入力を促すウェザードを実装するか
引数で秒数を取得するなどして
時間の上限を動的にするといいかも
今後
最初に書いたように
そんなこと考えながら
まず第一歩として画面の更新の方法をまとめてみた
そのうちに連載企画としてやってみたい
Win7でレジストリをいじってキー配列を変える
今の時期にWin7の話をするというのも時代遅れなきがするが
メモとして書いておく
最初に
当然の事ながら、レジストリをいじるので自己責任のもとで
バックアップは必須
これからすることによってパソコンがどうにかなったとしても
私は責任を取れない
今回は「Caps Lock」を「Alt」としてみる
参考サイトはこちら
How to Disable Caps Lock Key in Windows 7, 8, 10, or Vista
Windows/TIPS/レジストリを修正してCAPSLOCKの割り当て変更 - yanor.net/wiki
Windows Vista/XP/2000/NT4.0のキー配列の変更方法
主に二つ目を参考に話をすすめる
本題
レジストリ エディタを使って
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout
にScancode Map
という名でバイナリ値を作成
そこに以下の内容を入力
00 00 00 00 00 00 00 00
02 00 00 00 38 00 3A 00
00 00 00 00
勉強タイム
勉強がてら、一つ一つを読み解いていく
まず、一行目の00
8つはヘッダのようなのでそのまま入力
続いて、二行目
これは2つに分けて02 00 00 00
と38 00 3A 00
に分けられる
一つ目の02 00 00 00
は変更するキーが2つですよということ
ここで一つ疑問
1(Caps Lock) + 1(Alt) = 2
確かにその通りであるが
ここで一つ疑問
なぜ02
が一番最初に来ているのか
普通に考えて最後に来るのが普通ちゃうんかい┌(`Д´)ノ)゚∀゚)
って思っていたが、ふと「リトル・エンディアン」を思い出して
あぁ、なるほどね~
なんて思った
「リトル・エンディアン」がわからない方は
Wikipediaに聞くなり、ググっていただくと幸せになれるかもしれない
無事疑問は解決し・・・
では次
38 00
と3A 00
最初の値が変更後(出力)の役割、次に変更前(入力)の役割
リトル・エンディアンだから、38
と3A
38
がAltのキーコードで3A
がCaps Lockのキーコードである
有名どころを抑えておく
名称 | 入力値 |
---|---|
Alt(Right) | 38E0 |
Alt(Left) | 3800 |
Caps Lock | 3A00 |
Ctrl(Right) | 1DE0 |
Ctrl(Left) | 1D00 |
Esc | 0100 |
NumLock | 4500 |
ScrollLock | 4600 |
Win(Right) | 5CE0 |
Win(Left) | 5BE0 |
他のキーのコードは参考サイト二つ目に書かれている
ここではあえて実際に入力する際の値を表しているので
キーコードと言うと語弊がある
そこは適時読み直していただけたらと(;・∀・)
そして最後にNULL埋め
これで完了
複数キーを変更するときの値が
いまいち理解しきれていない(末尾のNULLの数とか)ので
今は書かないでおく
今後わかれば書き足すなり、新たに記事を作るなりしよう
JavaでAPIが叩きたい
今回は素のJAVA(SE8)で組んでみたいと思う
使用するAPIはこちら↓
GitHub API v3 | GitHub Developer Guide
これで自分のGist一覧を取得するためのAPIを叩いてみる
叩くだけであってそれで得られたJSONの処理はしない
何故ならできないからだ(`・∀・´)エッヘン!!
まずはコード
import java.io.*;
import java.net.URL;
public class GithubApi {
private static final String API_URL = "https://api.github.com/users/[UserID]/gists"; //叩くAPI
private static URL url = null;
private static BufferedReader br = null;
private static InputStreamReader isr = null;
public static void main ( String[] args ) {
try {
System.out.println( conectGetJson() );
} catch ( Exception e ) {
e.printStackTrace();
}
}
/* 実際にAPIを叩いて得たJSONを文字列として返す
適当に組んでいるのでエラーは投げてます
当然のことながら実際に実装する際は各自で適切な処理を*/
public static String conectGetJson() throws Exception {
url = new URL( API_URL );
String readLine = "";
String writeContent = "";
/* ここから読み込むための定型文 */
isr = new InputStreamReader( url.openStream() );
br = new BufferedReader( isr );
while ( ( readLine = br.readLine() ) != null ) writeContent = writeContent + readLine;//ここで読み込んだ内容を変数に保存している
return writeContent;
}
}
こんな感じですね
相も変わらず読みにくいコード(汗)
コメントの通り、実装の際は適切なエラー処理をお願いしますm(__)m
組んでから気付いたのですが
普通にJavaでHTMLやら読み込むときとまったく同じですね
結局やってることは同じということでしょうか
あえて今回は「APIを叩く」ということに焦点を置きました
本当はJSONのパースまでできたらいいんですけどね
面倒くさそうなので現段階では手を付けていません
楽そうなパースの方法がありましたらコメントしてもらえば嬉しいです
CardViewをListViewを使って表示させる
前々からCardViewをいじってみたくて調べていると
入れ子にしたりFor文回したりと意味がわからんことをやっていたので
ListViewで実装してみる
RecyclerViewに実装する方法は日本語であったが
ListViewに実装する方法はすぐに見つからなかったので
書き記しておく
目標
こんな感じになればOK
今回は素材を用意するのが面倒くさかったので
ImageViewを単色で塗りつぶした
下準備
CardViewはサポートライブラリなので
build.gradeに例のあれを書き足してあげないといけない
compile "com.android.support:cardview-v7:+"
必要なクラスやレイアウト
必要なクラスやレイアウトを最初に書き出しておく
- MainActivity
- CardViewのレイアウト
- CardViewに表示させる情報
- CustomAdapter
このぐらいかな
3には色の情報(色名と色コード)を保存する
1.MainActivity
とりあえず中身は最後にちょちょっと実装するとして
Layoutを組む
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android">
<ListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
私はActivityのLayoutを一から書く派なので、
手元のコードと少し違うかもしれないが、問題はない
2.CardViewのLayout
"layout"フォルダを右クリックし、
[New]→[Layout resource file]を選択
名前は"card.xml"にしておいた
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.CardView
android:id="@+id/cardView"
android:layout_width="match_parent"
android:layout_height="140dp"
card_view:cardCornerRadius="4dp"
android:layout_margin="16px">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#f0f0f0">
<ImageView
android:id="@+id/image"
android:layout_width="120dp"
android:layout_height="120dp"
android:layout_margin="8dp"/>
<TextView
android:id="@+id/text"
android:text="CardView"
android:textSize="30dp"
android:gravity="center"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1" />
</LinearLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
CardViewの中にLinearLayoutを突っ込んで
「ImageView・TextView」の順に書いただけ
高さや横幅はお好みで
3.CardViewに載せる情報
CardViewに載せたい情報は
- 色の名前
- 色コード
の2つだけ
private String colorName = "";
private String colorCode = "";
両方フィールドとしてprivateで宣言して
インスタンス化のときに代入してやる
あとで取り出すのでgetterを忘れずに
public class Card {
private String colorCode = "";
private String colorName = "";
public Card(String colorName, String colorCode) {
this.colorCode = colorCode;
this.colorName = colorName;
}
//↓getter
public String getColorName() {
return this.colorName;
}
public String getColorCode() {
return this.colorCode;
}
}
publicでもいいのかもしれないが
まぁ、無難にprivate
アクセス修飾子の勉強もせんとなぁ
4.CustomAdapter
これが一番面倒くさい
が、一番楽しい
public class ColorInfoAdapter extends ArrayAdapter<Card> {
private List<Card> cardList = null;
public ColorInfoAdapter(Context context, int resourceId, List<Card> cardList) {
super(context, resourceId, cardList);
this.cardList = cardList;
}
@Override
public int getCount() {
return cardList.size();
}
@Override
public Card getItem(int position) {
return cardList.get(position);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder viewHolder;
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.card, null);
viewHolder = new ViewHolder(convertView);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder)convertView.getTag();
}
final Card CARDINFO = getItem(position);
if (CARDINFO != null) {
viewHolder.getColorName().setText(CARDINFO.getColorName());
viewHolder.getColorImage().setBackgroundColor(Color.parseColor(CARDINFO.getColorCode()));
convertView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(getContext(), CARDINFO.getColorName(), Toast.LENGTH_SHORT).show();
}
});
}
return convertView;
}
private class ViewHolder {
private ImageView colorImage = null;
private TextView colorName = null;
public ViewHolder(View view) {
colorImage = (ImageView)view.findViewById(R.id.image);
colorName = (TextView) view.findViewById(R.id.text);
}
public ImageView getColorImage() {
return this.colorImage;
}
public TextView getColorName() {
return this.colorName;
}
}
}
ArrayAdapterを継承してやる
もちろんジェネリクスは先程作ったCard
フィールドで
private List cardList = null;
としてやる
インスタンスはそのまんま
次にgetCount・,getItenを記述
何回もView#findViewById
をすると処理が重いので
維持するためのViewHolderを作成
フィールドでTextViewとImageViewを宣言してやる
あとはインスタンスで代入
書けたらgetViewをOverride
さっき作ったクラスをfinalで宣言
後はいつも通りのnullチェックですな
最後にTagをセットしてやる
そうすることで、あとでもっかい何かするときに
getTagだけで取り戻せる
さぁ、ラスト
さっきのクラスを使っていつも通り
setTextなりsetBackgroundColorなりをする
Cardに保存されているColorCodeはString型なんで
Color#parseColorで求めているint型に直してやる
おまけ
convertViewはCardViewなので
CardViewに対してOnClickなどが書きたい場合は
convertView.setOnClickListenear(...);
と書いてやる
今回は押したCardViewの色名をTost表示するようにした
5.MainActivity(再び)
一周回ってMainActivity
今回こそはコードを書く
public class ColorCardListActivity extends AppCompatActivity {
//変数宣言
private List<Card> cardList = null;
private ColorInfoAdapter adapter = null;
private ListView listView = null;
private final String[] COLORCODES = {"black", "red", "blue", "green", "yellow","white" };
private final String[] COLORNAMES = {"黒", "赤", "青", "緑", "黄", "白"};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_color_card_list);
listView = (ListView)findViewById(R.id.listView);
cardList = new ArrayList<>();
for (int i = 0; i < COLORNAMES.length; i++) {
cardList.add(new Card(COLORNAMES[i], COLORCODES[i]));
}
adapter = new ColorInfoAdapter(this, R.layout.card, cardList);
listView.setAdapter(adapter);
}
}
String配列2つは、色の名前とコードを対応させて保存している
Mapでも良かったがなんだかんだ言って面倒くさいので
配列2つにしておく
あとはListにfor文で情報を入れて
そいつをadapterに渡してListViewにセット
以上
無事表示された
Tostもしっかり表示されている
MinecraftのMODを自作してみる on Ubuntu
友達がModdingをしたいと言っており
教えるがために自分も勉強するために自機の
Ubuntu上でModding環境を構築した際の覚書
WinやMacは調べればわんさかでてくるが
Linuxはあまりなかったので書いておく
結論を言ってしまえば
と言うか違いはない気がする
Editorが何かだけである
今回はIntellij IDEAを使う
バージョンは1.9
参考リンクはこちら
1,ダウンロード
Minecraft ForgeからMDKなるものをダウンロードする
ModDevelopmentKitだろうか
最近の名称らしい
DLしてきたZipを解凍しておく
2,構築(?)
この行為が構築であるとは断言できないが
恐らく構築であろう
Linux系統でModdingをしようと思ってらっしゃる方で
ここで止まる方もいたかもしれない
まずcd "DLしてきたMDKのディレクトリ"
で移動
続いてこちらのコマンドを実行
&&でつなぐのはオススメしない
#これでMinecraftとForgeをデコンパイルとビルドをしているらしい
./gradlew setupDecompWorkspace
#Intellij用の環境ファイルを作成
./gradlew genIntellijRuns
無事終了したらIDEAを起動
Import Projectで先程のディレクトリ内の
build.gradleを選択
しばしすると、無事ロードされる
あとは参考リンクの2つめの記事に
書いてあるコードを写経する
3,実行
注:コードは書き終えているものとする
やはり自作したら試したくなるものである
IDEAでの実行は
[View → ToolWindow → Gradle ]
[Tasks → forgegradle → runClient]
で無事実行できる(はず)
以上
ChromiumでFlashPlayerを使えるようにする
注意
現在この方法ではFlashが入れられません
そもそもFlash自体が2020年に廃止となるので
Flashを諦めることをおすすめします
Flashが使えずに悩んでいた
Flash自体は危ないものだがないと困る時がある
と、言うことでPepperFlashPlayerを入れてみる
こちらのサイトを参考にした
とりあえずパッケージを検索
apt-cache search pepperflashplugin-nonfree
そうすると以下が引っかかる
pepperflashplugin-nonfree - Pepper Flash Player - browser plugin
見つけたら早速インストール
sudo apt install pepperflashplugin-nonfree
無事インストールできたら、続いてChromiumにインストール
sudo update-pepperflashplugin-nonfree --install
最後にChromiumを起動して以下のリンクへ
無事適用されているかを確認
chrome://flash/
↓Radikoのプレイヤー(Flashがないと表示されない)↓