2010-12-29

mediaplayerを作ってみる(14)

ファイルを忍者に置いておきます。

http://sattva.asasvata.net/Entry/28/

前回の遺産がなくなったので、なかなか進みません。
まあ、それだけでもないんですが。

プリファレンスを追加しました。思ったより簡単でした。
というか、簡単なのにしました。

onStop()で、書き込み。


@Override
public void onStop() {
super.onStop();
musicPlayer.stop();

SharedPreferences pref = getSharedPreferences("SDMP", MODE_PRIVATE);
SharedPreferences.Editor editor = pref.edit();

editor.putString("directory_name", musicDirList.get(musicPlayer.getDirNum()));

editor.putString("file_name",
musicFileList.get(musicPlayer.getMusicNum()));

editor.commit();
}

onStart()で、読み込み。

@Override
public void onStart() {
super.onStart();
SharedPreferences pref = getSharedPreferences("SDMP", MODE_PRIVATE);
String dirName = pref.getString("directory_name", "");
String fileName = pref.getString("file_name", "");
int dirNum = 0;
int fileNum = 0;
if (musicDirList.contains(dirName)) {
mflm.musicFileListMaker(dirName, musicFileList);    
addNumList();
if (musicFileList.contains(fileName)) {
dirNum = musicDirList.indexOf(dirName);
fileNum = musicFileList.indexOf(fileName);
}
}
spinner.setSelection(dirNum);
mflm.musicFileListMaker(musicDirList.get(dirNum), fileListForListView);
mflm.musicFileListMaker(musicDirList.get(dirNum), musicFileList);
addNumList();

musicPlayer.setDirNum(dirNum);
musicPlayer.setCount(fileNum);
//listViewの変更と通知
listView.setAdapter(listAdapter);
musicPlayer.setListView(listView);
listView.clearChoices();
listView.setItemChecked(fileNum, true);
if (fileNum == 0) listView.setSelection(fileNum);
else listView.setSelection(fileNum - 1);
}

流れでonItemSelectedとかも変わってますが、
実行するタイミングが変わっただけで、やってることは同じ。

intではなくStringで書き込んだのは、その方がいいかなーと。
ディレクトリやファイルの場所は、追加、削除で変わるので。

まあ、場所が変わると読み込まないので、無かったことになります。
その辺が、簡単の限界。おまけ程度です。

次は、まあ、そのうち。

2010-12-24

mediaplayerを作ってみる(13)-2

とりあえず置いときます。あまり変わってませんが。

http://sattva.asasvata.net/Entry/25/

本当は、allMusicListに全曲の情報を詰めて
それを使って、randomをしようと思ったんですが、
なんか、色々考えると面倒くさいのでもういいかと。

変更は、menuで演奏履歴をクリアするようにしただけ。


    //オプションメニューの生成
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
     MenuInflater inflater = getMenuInflater();
     inflater.inflate(R.menu.options_menu, menu);
     return true;
    }
  
    //menuが選択されたときの処理
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
     switch (item.getItemId()) {
     case R.id.randomReset:
         allMusicList.clear();//clearしときます
         Toast.makeText(this, "reset", Toast.LENGTH_SHORT).show();
         break;
     }
    
     return super.onOptionsItemSelected(item);
    }


メニューを使いたかっただけです。
本当はvolume調整をメニューでしようと思ったんですが、
本体の横についてるんでいらないかと。

一応前に作ったのを利用して、main.xmlに


<TextView
    android:id="@+id/volText"
    android:layout_width="fill_parent"
    android:layout_height="30dp"
    android:textSize="16sp"
    android:background="@color/violet"
android:textColor="@color/green"
android:gravity="center">
</TextView>
<SeekBar
android:id="@+id/seekBar"
android:layout_width="fill_parent"
android:layout_height="30dp"
android:max="15"
android:progressDrawable="@color/green">
</SeekBar>


を追加して、onCreateの中に、

//seekBarの取得と初期値の設定
SeekBar seekBar = (SeekBar)findViewById(R.id.seekBar);
seekBar.setProgress(5);//とりあえず、5。

//volTextの取得と表示する文字列のセット
final TextView volText = (TextView)findViewById(R.id.volText);
volText.setText("Vol:" + seekBar.getProgress());

//volume調整のための準備
final AudioManager am = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
//int maxVolume = am.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
am.setStreamVolume(AudioManager.STREAM_MUSIC, 5, 0);

//seekBarが動かされたときの処理
seekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
//volumeのセット
am.setStreamVolume(AudioManager.STREAM_MUSIC, progress, 0);
//volTextに文字列をセット
volText.setText("Vol:" + progress);
}
//@Override
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO 自動生成されたメソッド・スタブ
}

//@Override
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO 自動生成されたメソッド・スタブ
}
});


んな感じのを書いとくと、
こんな感じ↓に

















なったりして。

これも置いときます。
忍者に。



2010-12-18

ubuntuとis01とgalaxy

結構簡単につながります。ubuntuには。

参考サイト


Ubuntu 上に IS01 の開発環境構築



そのままです。一個目のを先にやってたので、
そのファイルに追記するだけ。

一個目のは、とりあえずファイルを作ってから
mvで移動させました。

今回は、クリックしたらファイルが開いて
そのまま追記できました。

SUBSYSTEM=="usb", SYSFS{idVendor}=="04dd", MODE="0666"
SUBSYSTEM=="usb", SYSFS{idVendor}=="04e8", MODE="0666"

↑の2行です。
ということは、番号さえ分かればいくらでもいける。かも。
やってないので分かりませんが。

ちなみに、usbマウントをしてsdに書き込もうとすると、
is01の方は、普通に記憶デバイスとして認識されますが、

galaxyは、mediaplayerとして認識されます。
しかも、sdだけじゃなく、本体の方も同じように認識されます。

まあ、それだけで普通に書き込めますが。

2010-12-17

mediaplayerを作ってみる(13)

また忍者ブログに置いときます。

random。ディレクトリを越えて。

SDMP13_1 http://sattva.asasvata.net/Entry/20/

SDMP13_2 http://sattva.asasvata.net/Entry/21/

SDMP13_3 http://sattva.asasvata.net/Entry/22/

12/18追加 SDMP13_4 http://sattva.asasvata.net/Entry/23/

色々さまよった結果、3つ目のに落ち着きました。

12/18 ↑はずでしたが、たぶんもうちょっと変更します。

主な変更点

MusicDirListMakerの引数にArrayListを追加。合計3つ。
で、追加したやつに音楽ファイルをとりあえず詰め込む。
あと、地味にsortもしてます。

ほいで、Activityで、音楽ファイルの総数を確保してから
とりあえず、clear。

で、randomボタンと言うかCheckBox。


public void onClickRandom(View view) {

allMusicList.clear();//clearしときます
addNumList();//sortしときます。

Resources res = getResources();//なんとなく、使ってみる。

if (randomFlag) {

repeatButton.setClickable(true);
shuffleButton.setClickable(true);

     repeatButton.setTextColor(res.getColor(R.color.red));
     shuffleButton.setTextColor(res.getColor(R.color.red));
    
randomFlag = !randomFlag;
} else {

     repeatButton.setChecked(false);
     shuffleButton.setChecked(false);
    
     repeatButton.setClickable(false);
     shuffleButton.setClickable(false);
    
     repeatButton.setTextColor(res.getColor(R.color.dark_red));
     shuffleButton.setTextColor(res.getColor(R.color.dark_red));
    
     randomFlag = !randomFlag;
}
}

repeatButtonとshuffleButtonを、無効にしてテキストの色を暗く。
押す度に、allMusicList.clear();をしてますが、まあ、お好みで。

で、MusicPlayer。

plauMusic内

//Stringに変換
str = "" + dirNum + musicNum;
//全体の80%を越えたらクリアー。なんとなく。
if (allMusicList.size() > (totalMusicCount * 8 / 10)) allMusicList.clear();
//allMusicListに含まれてなければ
if (!allMusicList.contains(str)) allMusicList.add(str);

randomButton.isChecked()が、無いのはなんとなく。
というか、randomButtonを押す度にclearしてなかった時の名残りです。
まあ、いいかと。

で、onCompletion内

while(true) {
//ランダムにディレクトリを変更
dirNum = (int)(Math.random() * dirList.size());
//リストの詰め替え
sdmp.getMflm().musicFileListMaker(dirList.get(dirNum), musicList);
//カウントもランダムに変更
count = (int)(Math.random() * musicList.size());
//Stringに変換
str = "" + dirNum + count;
//allMusicListに含まれていなければ、つまりrandom開始後再生されていなければ
if (!allMusicList.contains(str)) break;
}

一応これで、再生済みの曲をはじけます。
が、なにぶんMath.random()を使っているので
残りが少なくなる(再生済みの曲が増える)と、
当たりを引くまで時間がかかりそう。

なので、playMusicのほうで、80%ぐらいでclearするようにしたんですが、
まあ、お好みで。

あと、読み込むファイルがmp3とwmaに変わってます。

ーーこれ以下、与太話。ーー

なんかねー。基金訓練にいく前に(16時すぎに始まるんですわ)
携帯ショップをのぞいたらgalaxyが在庫有りになってて
思わず機種変更してしまいまして。

で、そこに貼ってあったスペック表に、mp3/wma再生可能
なんてかいてあったんで。まあ、ついでに。

時間が無かったんで登録だけしといて受け取りは、翌日。(つまり今日)
まあ、結局遅刻したんで、遅れついでに受け取っとけば良かったんですが。

結構ちょこちょこ入荷してるらしいです。予約分は、はけたんですかね。
まあ、気にしてもしょうがないですが。

こんなことなら、is01いらなかった。
まあ、(普通の)TVなし生活中なので、is01のワンセグは有難いんですが。

何かここんとこ出費が多い。あぶく銭が入ったんで。
定職についてないんだから、貯金するべきなんだろうけど。

カバンとか、防風ジーンズとか。そんで、galaxy。

防風ジーンズ。ユニクロの。結構いいです。
そんな寒いとこじゃないんですが、バイクを常用しているので。
寒くないとは言わないが、かなりマシ。
普通に歩いてるだけなら、これだけで充分。パッチいらず。
(パッチ・・・股引。ここではヒートテック含む。)

カバンは、撥水の。ポリウレタン?何かそんなやつ。
まあ、バイク用。少々の雨なら大丈夫。カバンは。本人は大丈夫じゃないけど。

で、galaxy。衝動的に。・・・。

まあ、受け取ったらとりあえずこれを入れてみます。
エミュレーターだと2.3でも動いてるけど、2.2の実機でどうなるか。

ちょっと楽しみ。結構不安。まあ、結果はまた。

2010-12-15

StopWatchっぽい物を作ってみた

作ってみました。参考はこちら。というか、まあ、なんというか。

アクティビティ


package net.asasvata.stopwatchex;

import android.app.Activity;
import android.os.Bundle;
import android.os.SystemClock;
import android.view.View;
import android.widget.Chronometer;

public class StopWatchExActivity extends Activity {
    private Chronometer chronometer;
    private boolean pauseFlag;
    private boolean stopFlag;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
      
      chronometer = (Chronometer)findViewById(R.id.chronometer);
      pauseFlag = false;
      stopFlag = true;
    }
  
    public void onClickStart(View view) {
     if (stopFlag) {
     chronometer.setBase(SystemClock.elapsedRealtime());
     chronometer.start();
     stopFlag = false;
     }
     if (pauseFlag) {
     chronometer.start();
     pauseFlag = false;
     }
 
    }
  
    public void onClickStop(View view) {
     chronometer.stop();
     stopFlag = true;
     pauseFlag = false;
    }
  
    public void onClickPause(View view) {
     chronometer.stop();
     pauseFlag = true;
    }
  
    public void onClickRestart(View view) {
     if (stopFlag || pauseFlag) {
    //一時停止していた時間を取得
int stoppedMilliseconds = 0;
String chronoText = chronometer.getText().toString();
String array[] = chronoText.split(":");
if (array.length == 2) {
stoppedMilliseconds = Integer.parseInt(array[0]) * 60 * 1000
+ Integer.parseInt(array[1]) * 1000;
} else if (array.length == 3) {
stoppedMilliseconds = Integer.parseInt(array[0]) * 60 * 60 * 1000
+ Integer.parseInt(array[1]) * 60 * 1000
+ Integer.parseInt(array[2]) * 1000;
}

chronometer.setBase(SystemClock.elapsedRealtime() - stoppedMilliseconds);
chronometer.start();
stopFlag = false;
pauseFlag = false;
     }
    }
}

レイアウト


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <Chronometer
     android:id="@+id/chronometer"
     android:layout_width="fill_parent"
     android:layout_height="wrap_content"
     android:textSize="20px">
    </Chronometer>
    <LinearLayout
     android:orientation="horizontal"
     android:layout_width="fill_parent"
     android:layout_height="wrap_content">
     <Button
     android:id="@+id/startButton"
     android:layout_width="fill_parent"
     android:layout_height="wrap_content"
     android:layout_weight="1"
     android:text="@string/start_button"
     android:onClick="onClickStart">
     </Button>
     <Button
     android:id="@+id/stopButton"
     android:layout_width="fill_parent"
     android:layout_height="wrap_content"
     android:layout_weight="1"
     android:text="@string/stop_button"
     android:onClick="onClickStop">
     </Button>
     <Button
     android:id="@+id/pauseButton"
     android:layout_width="fill_parent"
     android:layout_height="wrap_content"
     android:layout_weight="1"
     android:text="@string/pause_button"
     android:onClick="onClickPause">
     </Button>
     <Button
     android:id="@+id/restartButton"
     android:layout_width="fill_parent"
     android:layout_height="wrap_content"
     android:layout_weight="1"
     android:text="@string/restart_button"
     android:onClick="onClickRestart">
     </Button>
    </LinearLayout>
</LinearLayout>

string.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="hello">Hello World, StopWatchExActivity!</string>
    <string name="app_name">StopWatchEx</string>
    <string name="start_button">start</string>
    <string name="stop_button">stop</string>
    <string name="pause_button">pause</string>
    <string name="restart_button">restart</string>
</resources>

Hello World消すのわすれてますが、まあ、まあ。
resetbuttonつけてないのも、まあ、まあ。
大体で。

startとrestart、stopとpauseの違い。

chronometerは、stopしただけだと裏で動きつづけます。
で、
pause→startだと、resetしないで裏で動いてたとこから、続けます。
stop→startだと、resetして0から始めます。
ほいで、
pause or stop→restartで、裏で動いてた時間をひいて、
つまり、表示されてるとこから、続けます。

そんだけ。秒単位の表示が、なんかねー。
handlerとか使うべきかも。
まあ、気が向いたら挑戦します。