非同期で(asynchronously)MediaPlayerを使う
Mediaに書かれているとおりに書いたつもりのsourceを掲載しておきます。
音楽ファイルは次のサイトのを使いました。
MP3ダウンロード(童謡 唱歌 世界の民謡)
動作内容:SDカードにある、複数の音楽ファイル(mp3)を連続再生する。実験・学習目的なので、簡単にするため、serviceを使っていません。
留意点:指定された音楽ファイルが存在しない場合、setDataSourceメソッドでエラーを補足するのでは無く、prepare系でエラーを補足する、というのがMediaPlayerの仕様です。
では、setDataSourceメソッドのIOExceptionは何のために存在するのでしょうか。そんなことまでは、私は興味はありません。
public class SoundWAVActivity extends Activity
implements
MediaPlayer.OnCompletionListener,
MediaPlayer.OnPreparedListener,
MediaPlayer.OnErrorListener
{
MediaPlayer mp = null;;
int iFileNumber = 1647;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
StartMusic();
}
//演奏が終了した場合、呼ばれる。
@Override
public void onCompletion(MediaPlayer arg0) {
if(mp==arg0) StartMusic();
}
//演奏の準備が完了したら呼ばれる。
@Override//Running asynchronously
public void onPrepared(MediaPlayer ThisMP) {
if(mp==ThisMP) mp.start();
}
//演奏の準備の段階でエラーが発生した時に呼ばれる。
@Override//Handling asynchronous errors
public boolean onError(MediaPlayer ThisMP, int what, int extra) {
if(mp==ThisMP){
if(what==MediaPlayer.MEDIA_ERROR_SERVER_DIED)
Log.e("SoundWAV", "onError:MEDIA_ERROR_SERVER_DIED");
else//ファイルが存在しない場合、ここに来る。
Log.e("SoundWAV", "onError:MEDIA_ERROR_UNKNOWN");
//エラーになっても何もしなければ、onCompletionメソッドが呼ばれる。
finish();
return true;//次のonCompletion()が呼ばれないようにする。
}
return false;
}
@Override
protected void onDestroy() {
if(mp!=null) mp.release();//Performing cleanup
super.onDestroy();
}
private void StartMusic(){
File f, fSD;
String sFile;
fSD = Environment.getExternalStorageDirectory();
fSD = new File(fSD, "music");
sFile = "m" + String.valueOf(iFileNumber) + ".mp3";
f = new File(fSD, sFile);
sFile = f.getPath();//ファイルの存在確認はMediaPlayerで行う。
iFileNumber++;
if(mp!=null) mp.release();
mp = new MediaPlayer();
if(mp==null){
Log.e("SoundWAV", "mp == null");
finish();
return;
}
try{
mp.setDataSource(sFile);
}
catch (IOException e) {//ファイルが存在しなくても。ここには来ない。
Log.e("SoundWAV", "IOException");
finish();
return;
}
catch (IllegalStateException e) {
//release()&Newを実行しない場合、ここに来る。
Log.e("SoundWAV", "IllegalStateException");
finish();
return;
}
catch (IllegalArgumentException e) {
Log.e("SoundWAV", "IllegalArgumentException");
finish();
return;
}
mp.setOnCompletionListener(this);
mp.setOnPreparedListener(this);
mp.setOnErrorListener(this);
mp.prepareAsync ();
Toast.makeText(this, "Start", Toast.LENGTH_SHORT).show();
}
}
2011年8月23日火曜日
2011年8月19日金曜日
テキストファイルのコード変換 その後
テキストファイルのコード変換 その後
以前テキストファイルのコード変換を書きましたが、過ちがありました。
そして、ここにも問題が有ることが判明しましたので、こっちに後日談を書きました。
入力用のテキストデータとして次の文字列を使用しました。
原文:つかいやすいといえます。
Shift_JISで変換すると正確にコード変換されます。
これをUTF-16で復号すると次のように変換されます。
UTF-16で復号後:苂芩芢苢芷芢苆芢芦苜芷腂
これだと、コード変換じゃなくって、中国語への翻訳ですな。
UTF-16を使うと、エラーが無く、変換ができてしまうのです。中国語に。
Charsetの順序を"UTF-8", "UTF-16", "Shift_JIS"にすると、UTF-16変換がエラー無く実行されるため、Shift_JIS変換が実行されません。このため、上記の不都合が発生してしまいました。
この問題を解決したプログラムを掲載しておきます。
public class CodeChangeActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
int iSize;
File fSD, f;
FileInputStream fs;
byte[] ba;
fSD = Environment.getExternalStorageDirectory();
f = new File(fSD, "tyi.txt");
ba = new byte[6000];
try{
fs = new FileInputStream(f);
iSize = fs.read(ba, 0, 6000);
fs.close();
}
catch(FileNotFoundException e){
return;
}
catch(IOException e){
return;
}
int i;
Charset charset;
CharsetDecoder d;
CoderResult r;
CharBuffer cb;
ByteBuffer bb;
String[] sCharset =
{"UTF-8", "Shift_JIS", "EUC-JP", "ISO-2022-JP", "UTF-16"};
bb = ByteBuffer.wrap(ba);
cb = null;
for(i=0; i<sCharset.length; i++){
if(Charset.isSupported(sCharset[i])==true){
charset = Charset.forName(sCharset[i]);
d = charset.newDecoder();
cb = CharBuffer.allocate(iSize);
r = d.decode(bb, cb, true);
if(r.isError()==false) break;
bb.rewind();
}
}
String s;
TextView tv;
if(i>=sCharset.length){
s = "have no charset";
}
else{
cb.rewind();
s = cb.toString();
}
tv = (TextView)findViewById(R.id.MyText);
tv.setText(s);
}
}
CharsetDecoder.decodeメソッドの長所は、コード変換エラーが発生した場合、その時点で実行を停止することです。
以前テキストファイルのコード変換を書きましたが、過ちがありました。
そして、ここにも問題が有ることが判明しましたので、こっちに後日談を書きました。
入力用のテキストデータとして次の文字列を使用しました。
原文:つかいやすいといえます。
Shift_JISで変換すると正確にコード変換されます。
これをUTF-16で復号すると次のように変換されます。
UTF-16で復号後:苂芩芢苢芷芢苆芢芦苜芷腂
これだと、コード変換じゃなくって、中国語への翻訳ですな。
UTF-16を使うと、エラーが無く、変換ができてしまうのです。中国語に。
Charsetの順序を"UTF-8", "UTF-16", "Shift_JIS"にすると、UTF-16変換がエラー無く実行されるため、Shift_JIS変換が実行されません。このため、上記の不都合が発生してしまいました。
この問題を解決したプログラムを掲載しておきます。
public class CodeChangeActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
int iSize;
File fSD, f;
FileInputStream fs;
byte[] ba;
fSD = Environment.getExternalStorageDirectory();
f = new File(fSD, "tyi.txt");
ba = new byte[6000];
try{
fs = new FileInputStream(f);
iSize = fs.read(ba, 0, 6000);
fs.close();
}
catch(FileNotFoundException e){
return;
}
catch(IOException e){
return;
}
int i;
Charset charset;
CharsetDecoder d;
CoderResult r;
CharBuffer cb;
ByteBuffer bb;
String[] sCharset =
{"UTF-8", "Shift_JIS", "EUC-JP", "ISO-2022-JP", "UTF-16"};
bb = ByteBuffer.wrap(ba);
cb = null;
for(i=0; i<sCharset.length; i++){
if(Charset.isSupported(sCharset[i])==true){
charset = Charset.forName(sCharset[i]);
d = charset.newDecoder();
cb = CharBuffer.allocate(iSize);
r = d.decode(bb, cb, true);
if(r.isError()==false) break;
bb.rewind();
}
}
String s;
TextView tv;
if(i>=sCharset.length){
s = "have no charset";
}
else{
cb.rewind();
s = cb.toString();
}
tv = (TextView)findViewById(R.id.MyText);
tv.setText(s);
}
}
2011年8月17日水曜日
ArrayAdapterのsort()を使ってみる
複数の文字列を画面に表示する場合、それらをアルファべット順とかで並べ替えたい(ソートしたい)ですね。
多くのプログラマはjavaベースのCollections.sortを行うのかもしれません。
私が作ったのはArrayAdapterのsortメソッドを使っているので、androidに特化したものです。
compareメソッド内で文字列の比較を行います。一覧内で先頭や末尾に表示したい文字列を設定できます。例えば、ディレクトリを意味する文字列の末尾に/があれば、それを一括りにもできますので、ディレクトリ群を最初に、ファイル群を後に表示することもできます。
androidのファイルシステムでは、ファイルやディレクトリはソートされた状態ではありませんので、このソートを使って表示する必要があります。
AASortActivity.java
public class AASortActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ListView lv;
lv = new ListView(this);
setContentView(lv);
ArrayAdapter<String> aa;
aa = new ArrayAdapter<String>(this, R.layout.list_item, MyStringData);
aa.sort(new MyComparator());
lv.setAdapter(aa);
}
public class MyComparator implements Comparator<String>{
@Override
public int compare(String s1, String s2){
if(s1.equals("First")==true) return -1;
if(s2.equals("First")==true) return 1;
if(s1.length()==0) return 1;
if(s2.length()==0) return -1;
if(s1.charAt(s1.length()-1)=='/'
&& s2.charAt(s2.length()-1)!='/') return -1;
if(s1.charAt(s1.length()-1)!='/'
&& s2.charAt(s2.length()-1)=='/') return 1;
return s1.compareTo(s2);
}
}
static final String[] MyStringData = new String[] {
"qqq8", "qqq3", "qqq4", "qqq/", "qqqr",
"www5", "www7", "www/", "www3", "wwwe",
"First", "..", "",
"eee2", "eee0", "eee/", "eee6", "eee3"
};
}
list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
</TextView>
この技術を使ってファイル選択ダイアログボックスの作成をしてみました。
多くのプログラマはjavaベースのCollections.sortを行うのかもしれません。
私が作ったのはArrayAdapterのsortメソッドを使っているので、androidに特化したものです。
compareメソッド内で文字列の比較を行います。一覧内で先頭や末尾に表示したい文字列を設定できます。例えば、ディレクトリを意味する文字列の末尾に/があれば、それを一括りにもできますので、ディレクトリ群を最初に、ファイル群を後に表示することもできます。
androidのファイルシステムでは、ファイルやディレクトリはソートされた状態ではありませんので、このソートを使って表示する必要があります。
AASortActivity.java
public class AASortActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ListView lv;
lv = new ListView(this);
setContentView(lv);
ArrayAdapter<String> aa;
aa = new ArrayAdapter<String>(this, R.layout.list_item, MyStringData);
aa.sort(new MyComparator());
lv.setAdapter(aa);
}
public class MyComparator implements Comparator<String>{
@Override
public int compare(String s1, String s2){
if(s1.equals("First")==true) return -1;
if(s2.equals("First")==true) return 1;
if(s1.length()==0) return 1;
if(s2.length()==0) return -1;
if(s1.charAt(s1.length()-1)=='/'
&& s2.charAt(s2.length()-1)!='/') return -1;
if(s1.charAt(s1.length()-1)!='/'
&& s2.charAt(s2.length()-1)=='/') return 1;
return s1.compareTo(s2);
}
}
static final String[] MyStringData = new String[] {
"qqq8", "qqq3", "qqq4", "qqq/", "qqqr",
"www5", "www7", "www/", "www3", "wwwe",
"First", "..", "",
"eee2", "eee0", "eee/", "eee6", "eee3"
};
}
list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
</TextView>
この技術を使ってファイル選択ダイアログボックスの作成をしてみました。
2011年8月15日月曜日
テキストファイルのコード変換
Microsoft社のWindowsのディスクにあるテキストファイル内の文字データのコードはShift_JISです。
このファイルを、そのままandroidシステム内のディレクトリにコピーすると、Shift_JISデータのままのファイルになってしまいます。
このことを何も知らずに、androidで当該ファイルを開くと文字化けが発生します。
androidシステムでは文字コードはUTF-8なのです。
この情報をandroid端末利用者に周知して文字化けを未然に防ぐことも一つの方法ですが、周知が行き届くとは限りません。また、利用者側でコード変換をするのは面倒です。
このため、androidアプリ側でコード変換を行います。サンプルのsourceを作成しましたので掲載しておきます。
入力のテキストファイルのコードが何であるか事前にはわかりません。このため、適正な復号が行えるまで、異なったコードで復号を試みることがポイントです。
動作内容:SDカードのルートディレクトリのsammm3.txtファイル内の文字データをandroid用のコードに変換して画面に表示します。
本文章を掲載後、プログラムに誤りを見つけましたので、修正後をテキストファイルのコード変換 その後に書いておきました。
/*
* 参考になったサイト
* http://www.ne.jp/asahi/hishidama/home/tech/java/Buffer.html
* http://www.javadb.jp/Code.sd?id=53
* http://blog.goo.ne.jp/xmldtp/e/b1fb4c01508e21a1325c41c3a44c7655
* http://www.opensourcejavaphp.net/java/harmony/tests/api/java/nio/charset/CharsetTest.java.html
*/
public class CodeChangeActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
int iSize;
File fSD, f;
FileInputStream fs;
byte[] ba;
fSD = Environment.getExternalStorageDirectory();
f = new File(fSD, "sammm3.txt");
ba = new byte[6000];
try{
fs = new FileInputStream(f);
iSize = fs.read(ba, 0, 6000);
fs.close();
}
catch(FileNotFoundException e){
return;
}
catch(IOException e){
return;
}
int i;
Charset charset;
CharsetDecoder d;
CoderResult r;
CharBuffer cb;
ByteBuffer bb;
String[] sCharset = {"UTF-8", "UTF-16", "Shift_JIS"};
bb = ByteBuffer.wrap(ba);
cb = null;
for(i=0; i<sCharset.length; i++){
charset = Charset.forName(sCharset[i]);
d = charset.newDecoder();
cb = CharBuffer.allocate(iSize);
r = d.decode(bb, cb, true);
if(r.isError()==false) break;
bb.rewind();
}
String s;
TextView tv;
if(i>=sCharset.length){
s = "have no charset";
}
else{
cb.rewind();
s = cb.toString();
}
tv = (TextView)findViewById(R.id.MyText);
tv.setText(s);
}
}
このファイルを、そのままandroidシステム内のディレクトリにコピーすると、Shift_JISデータのままのファイルになってしまいます。
このことを何も知らずに、androidで当該ファイルを開くと文字化けが発生します。
androidシステムでは文字コードはUTF-8なのです。
この情報をandroid端末利用者に周知して文字化けを未然に防ぐことも一つの方法ですが、周知が行き届くとは限りません。また、利用者側でコード変換をするのは面倒です。
このため、androidアプリ側でコード変換を行います。サンプルのsourceを作成しましたので掲載しておきます。
入力のテキストファイルのコードが何であるか事前にはわかりません。このため、適正な復号が行えるまで、異なったコードで復号を試みることがポイントです。
動作内容:SDカードのルートディレクトリのsammm3.txtファイル内の文字データをandroid用のコードに変換して画面に表示します。
本文章を掲載後、プログラムに誤りを見つけましたので、修正後をテキストファイルのコード変換 その後に書いておきました。
/*
* 参考になったサイト
* http://www.ne.jp/asahi/hishidama/home/tech/java/Buffer.html
* http://www.javadb.jp/Code.sd?id=53
* http://blog.goo.ne.jp/xmldtp/e/b1fb4c01508e21a1325c41c3a44c7655
* http://www.opensourcejavaphp.net/java/harmony/tests/api/java/nio/charset/CharsetTest.java.html
*/
public class CodeChangeActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
int iSize;
File fSD, f;
FileInputStream fs;
byte[] ba;
fSD = Environment.getExternalStorageDirectory();
f = new File(fSD, "sammm3.txt");
ba = new byte[6000];
try{
fs = new FileInputStream(f);
iSize = fs.read(ba, 0, 6000);
fs.close();
}
catch(FileNotFoundException e){
return;
}
catch(IOException e){
return;
}
int i;
Charset charset;
CharsetDecoder d;
CoderResult r;
CharBuffer cb;
ByteBuffer bb;
String[] sCharset = {"UTF-8", "UTF-16", "Shift_JIS"};
bb = ByteBuffer.wrap(ba);
cb = null;
for(i=0; i<sCharset.length; i++){
charset = Charset.forName(sCharset[i]);
d = charset.newDecoder();
cb = CharBuffer.allocate(iSize);
r = d.decode(bb, cb, true);
if(r.isError()==false) break;
bb.rewind();
}
String s;
TextView tv;
if(i>=sCharset.length){
s = "have no charset";
}
else{
cb.rewind();
s = cb.toString();
}
tv = (TextView)findViewById(R.id.MyText);
tv.setText(s);
}
}
2011年8月9日火曜日
【教訓】コンストラクタはpublicにせよ
【教訓】コンストラクタはpublicにせよ
ActivityのクラスにおいてbindServiceメソッドを用いて、Serviceのクラスを立ち上げようとしたところ、下記の実行時エラーがLogに出る。
DEBUG/dalvikvm(5311): newInstance failed: Ljp/(省略)/(省略)/XXXService;.<init>() not accessible to Landroid/app/ActivityThread;
ActivityのクラスにおいてbindServiceメソッドを用いて、Serviceのクラスを立ち上げようとしたところ、下記の実行時エラーがLogに出る。
DEBUG/dalvikvm(5311): newInstance failed: Ljp/(省略)/(省略)/XXXService;.<init>() not accessible to Landroid/app/ActivityThread;
このエラーは、Serviceのクラスのコンストラクタ(constructor)にアクセス修飾子(access modifier)を記述していなかったため発生したものである。
アクセス修飾子を記述しない場合、デフォルトのアクセス制限が課せられる。この制限の強度は、privateよりは弱く、protectedよりは強いというものである。
何も考えずに、何も書かないでおくと、何も想定していないエラーに遭遇する。
どうせ何も考えないのであれば、コンストラクタのアクセス修飾子はpublicにしておこう。
コンストラクタをpublicにした場合における不都合ってのは、普通は、ありえない。逆に、コンストラクタにアクセス制限をかけると上記の災難に遭遇する。
クラス宣言をpublicにしておきながら、そのコンストラクタにはアクセス制限を加えるってのは特殊な設計ですな。そういう場合には、そういうアナウンスをしっかりすべきですな。
実際には、特殊な設計を積極的に行ったのではなく、な~んにも考えずに書きました、ってことかもしれない。
実際には、特殊な設計を積極的に行ったのではなく、な~んにも考えずに書きました、ってことかもしれない。
で、繰り返しになりますが、
【教訓】コンストラクタはpublicにせよ
2011年8月5日金曜日
AlertDialogが正常に表示されない件 その3
AlertDialogが正常に表示されない件 その3
これはAlertDialogが正常に表示されない件 その2の続編です。
android developersのR.layoutには各constantsに対する解説が書かれていません。このため、読解するための難易度が上がります。まるで、なぞなぞです。
皆さんは、このなぞなぞをお楽しみ頂けたでしょうか。
public class AlertDialogActivity extends Activity
implements
DialogInterface.OnClickListener
{
AlertDialog ad;
@Override
public void onClick(DialogInterface dialog, int which) {
if(dialog==ad){
dialog.cancel();
finish();
}
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
AlertDialog.Builder b;
ArrayAdapter<CharSequence> aa;
ArrayList<CharSequence> al;
al = new ArrayList<CharSequence>();
al.add("なんじゃ");
al.add("これは");
al.add("動かん");
al.add("や");
al.add("ないか");
//ここの第二引数が重要
aa = new ArrayAdapter<CharSequence>(
this,
android.R.layout.select_dialog_singlechoice,
al
);
b = new AlertDialog.Builder(this);
b.setTitle("アラートダイアログ");
b.setSingleChoiceItems(aa, 0, this);
b.setNegativeButton("閉じる",
new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
finish();
}
}
);
ad = b.show();
}
}
この技術を使ってファイル選択ダイアログボックスの作成をしてみました。
これはAlertDialogが正常に表示されない件 その2の続編です。
android developersのR.layoutには各constantsに対する解説が書かれていません。このため、読解するための難易度が上がります。まるで、なぞなぞです。
皆さんは、このなぞなぞをお楽しみ頂けたでしょうか。
私は、このなぞなぞをなんとか解くことができました。sourceは次のとおりです。
implements
DialogInterface.OnClickListener
{
AlertDialog ad;
@Override
public void onClick(DialogInterface dialog, int which) {
if(dialog==ad){
dialog.cancel();
finish();
}
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
AlertDialog.Builder b;
ArrayAdapter<CharSequence> aa;
ArrayList<CharSequence> al;
al = new ArrayList<CharSequence>();
al.add("なんじゃ");
al.add("これは");
al.add("動かん");
al.add("や");
al.add("ないか");
//ここの第二引数が重要
aa = new ArrayAdapter<CharSequence>(
this,
android.R.layout.select_dialog_singlechoice,
al
);
b = new AlertDialog.Builder(this);
b.setTitle("アラートダイアログ");
b.setSingleChoiceItems(aa, 0, this);
b.setNegativeButton("閉じる",
new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
finish();
}
}
);
ad = b.show();
}
}
この技術を使ってファイル選択ダイアログボックスの作成をしてみました。
2011年8月4日木曜日
AlertDialogが正常に表示されない件 その2
AlertDialogが正常に表示されない件 その2
AlertDialogを作成するにはAlertDialog.Builderを使います。
このAlertDialog.Builderには、引数の形式が異なる4種類のsetSingleChoiceItemsメソッドが用意されています。
皆さんの多くが使うのは次の形式でしょう。第一引数がCharSequence[]になっています。
public AlertDialog.Builder setSingleChoiceItems (CharSequence[] items, int checkedItem, DialogInterface.OnClickListener listener)
私も止むを得ずこれを使いました。
第一引数にListAdapterを設定するメソッドも用意されています。
引数にCharSequence[]を設定するよりも、ListAdapterを設定する方が便利です。
私は、リソースから文字列データを取得するのではなく、リソース以外の場所からデータを取得・追加したいのです。
しかし、残念ながら、ListAdapter型setSingleChoiceItemsメソッドは正常に動きません。真っ白に表示されてしまうのです。
どなたか、我こそは腕自慢ってな御仁は、正常に動作するListAdapter型setSingleChoiceItemsメソッドのサンプルプログラムをブログかなんかに掲載してください。謝礼はありませんが。
この続編をAlertDialogが正常に表示されない件 その3に書きました。
AlertDialogを作成するにはAlertDialog.Builderを使います。
このAlertDialog.Builderには、引数の形式が異なる4種類のsetSingleChoiceItemsメソッドが用意されています。
皆さんの多くが使うのは次の形式でしょう。第一引数がCharSequence[]になっています。
public AlertDialog.Builder setSingleChoiceItems (CharSequence[] items, int checkedItem, DialogInterface.OnClickListener listener)
私も止むを得ずこれを使いました。
第一引数にListAdapterを設定するメソッドも用意されています。
引数にCharSequence[]を設定するよりも、ListAdapterを設定する方が便利です。
私は、リソースから文字列データを取得するのではなく、リソース以外の場所からデータを取得・追加したいのです。
しかし、残念ながら、ListAdapter型setSingleChoiceItemsメソッドは正常に動きません。真っ白に表示されてしまうのです。
どなたか、我こそは腕自慢ってな御仁は、正常に動作するListAdapter型setSingleChoiceItemsメソッドのサンプルプログラムをブログかなんかに掲載してください。謝礼はありませんが。
この続編をAlertDialogが正常に表示されない件 その3に書きました。
登録:
投稿 (Atom)