2013年5月15日水曜日

エラー (Multiple substitutions specified in non-positional format; did you mean to add the formatted="false" attribute? エラー)

Androidの2.33にバージョンアップしたら、

Multiple substitutions specified in non-positional format; did you mean to add the formatted="false" attribute?


というエラーが!!!


formatted="false"

ここが臭い。。

xmlファイルで

  <string name="xxxxURL">http://xxxxx2a.%s?url=http://xxxxx1a%s</string>

と記述している場所がエラーに!!

<string name="xxxxURL">http://xxxxx2a.%1$s?url=http://xxxxx1a%1$s</string>
or
<string name="xxxxURL">http://xxxxx2a.%1$s?url=http://xxxxx1a%2$s</string>


こんな感じで、引数の順番を渡したら、エラーは消えました。


2013年5月13日月曜日

端末識別コード(TelephonyManager, TELEPHONY_SERVICE)

端末シリアルの取得の仕方です。

ガラケの時は何も考えずに取得できたのですが、
Androidだと、そうは問屋が卸してくれません。

しかも、Manifestに専用のパーミッションを書かなければいけないので、
ユーザーにインストールを警戒されてしまいます。

■サンプルソース

・MainActivity
package com.example.tanmatu;

import android.app.Activity;
import android.content.Context;
import android.provider.Settings;
import android.os.Bundle;
import android.telephony.TelephonyManager;
import android.widget.LinearLayout;
import android.widget.TextView;


public class MainActivity extends Activity {
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        //レイアウトの生成
        LinearLayout oLayout = new LinearLayout(getApplicationContext());
        //上から下にパーツを組み込む
        oLayout.setOrientation(LinearLayout.VERTICAL);
        //画面の設定
        setContentView(oLayout);

        //端末情報取得クラス:TelephonyManager生成
        TelephonyManager telMgr = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);

        //デヴァイスID
        String deviceid = telMgr.getDeviceId();
        //電話番号
        String phoneNumber = telMgr.getLine1Number();
        //SIM国別コード
        String simCountryIso = telMgr.getSimCountryIso();
        //SIMシリアルナンバー
        String simSerialNumber = telMgr.getSimSerialNumber();
        // 携帯端末固有ID
        String deviceId = telMgr.getDeviceId();

        //AndroiIDの取得
        String sAndroid = Settings.Secure.getString(this.getContentResolver(), Settings.System.ANDROID_ID);
        oLayout.addView(Make_TextView("Phone Number" + phoneNumber));
        oLayout.addView(Make_TextView("SIM国別コード" + simCountryIso));
        oLayout.addView(Make_TextView("SIMシリアルナンバー" + simSerialNumber));
        oLayout.addView(Make_TextView("携帯端末固有" + deviceId));
        oLayout.addView(Make_TextView("Android ID" + sAndroid));
    }
    private TextView Make_TextView(String sTitle){
        TextView oTv = new TextView(this);
        oTv.setText(sTitle);
        return oTv;
    }
}

・manifest.xml

<uses-permission android:name="android.permission.READ_PHONE_STATE"/>

を追加

■実行結果



他にもたくさんの関数が用意されているので、詳しはリファレンスで!!

リファレンスはこちら


エミュレータだと携帯端末固有IDが0000のようになっています。
端末やSIMカードの有無によって、取得できる値が変わってくるので、注意が必要です。

また、今回はAndroidIDの取得をしていますが、AndroidIDはTelephonyManagerとは関係のない処理です。

AndroidIDとはすべてのAndroidの端末に設定されている数値で、端末を初期化すると、この値は変更されます。

端末を識別したいのか?
ユーザーを識別したいのか?

ちゃんと考えてからの実装をおすすめします。



2013年5月10日金曜日

画面遷移(ViewFlipper)

Viewを切り替えることができるViewFlipper
ViewFlipperにレイアウトを追加すると、追加した順番で、
1つ1つのViewが表示されます。

次のViewに
showNext();

前のViewに
showPrevious();

スライドショーの再生
startFlipping();

スライドショーの停止
stopFlipping();

スライドショーを勝手に始める
setAutoStart(boolean);

スライドショーの間隔
setFlipInterval(int);

■サンプルソース
package com.pulepule.linear;

import android.os.Bundle;
import android.app.Activity;
import android.graphics.Color;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.NumberPicker;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.NumberPicker.OnValueChangeListener;
import android.widget.ViewFlipper;

public class MainActivity extends Activity implements OnClickListener{
 
    //ViewFlipperを宣言
    private ViewFlipper oViewFliper;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        //基レイアウトの作成
        LinearLayout oLayout = new LinearLayout(getApplicationContext());
        oLayout.setOrientation(LinearLayout.VERTICAL);
        //基レイアウトを画面に設定
        setContentView(oLayout);

        //ViewFlipperの生成
        oViewFliper = new ViewFlipper(getApplicationContext());
        //自動でスライドショーを始める
        oViewFliper.setAutoStart(false);
        //スライドショーの感覚を指定する
        oViewFliper.setFlipInterval(1000);
        //ViewFlipper、1ページ目、2ページ目の作成と共に追加
        oViewFliper.addView(Make_Text(1, "1ページ目"));
        oViewFliper.addView(Make_Text(2, "2ページ目"));

        //ViewFlipper、3ページ目の作成
        //子layoutを作成
        LinearLayout oViewFliperChildLayout = new LinearLayout(getApplicationContext());

        //ImageViewの生成
        ImageView oImage = new ImageView(getApplicationContext());
        //ImageViewに画像を設定
        oImage.setImageResource(R.drawable.ic_launcher);

        //子layoutに作成したtextviewやら、画像を追加
        oViewFliperChildLayout.addView(Make_Text(3, "3ページ目"));
        oViewFliperChildLayout.addView(oImage);

        //ViewFlipper、3ページ目に子Layoutを追加
        oViewFliper.addView(oViewFliperChildLayout);

        //ViewFlipperをレイアウト(setVontentViewした)に追加
        oLayout.addView(oViewFliper);

        //ボタンの作成
        oLayout.addView(Make_Button(4, "次へ"));
        oLayout.addView(Make_Button(5, "戻る"));
        oLayout.addView(Make_Button(6, "スライドショー再生"));
        oLayout.addView(Make_Button(7, "スライドショー停止"));
    }

    private TextView Make_Text(int id, String sTitle){
        TextView tv = new TextView(getApplicationContext()); 
        tv.setText(sTitle);
        tv.setId(id);
        return tv;
    }
 
    private Button Make_Button(int id, String sTitle){
        Button btn = new Button(getApplicationContext()); 
        btn.setText(sTitle);
        btn.setTag(sTitle);
        btn.setId(id);
        btn.setOnClickListener(this);
        return btn;
    }

    @Override
    public void onClick(View v) {
        Log.d("ボタン",(String) v.getTag());
        if (v.getTag().equals("次へ")){
            oViewFliper.showNext();
        }else if (v.getTag().equals("戻る")){
            oViewFliper.showPrevious();
        }else if (v.getTag().equals("スライドショー再生")){
            oViewFliper.startFlipping();
        }else if (v.getTag().equals("スライドショー停止")){
            oViewFliper.stopFlipping();
        }
    }
}

■実行結果







最終ページで次ボタンを押すと、最初のページに遷移して、
最初のぺージで戻るボタンをおすと最終ページに遷移するのが確認できると思います。


1つのソースコードで複数の画面を制御できるのが魅力です。

2013年5月2日木曜日

アラートダイアログにレイアウトを読み込ませる(AlertDialog, inflate)

今回はレイアウトをxmlで作成して、そのxmlをダイアログに適用させる方法について記述します。

dialog.xmlのサンプルソースはlayoutフォルダに格納してください。
dialog_bg_layout.xmlのサンプルソースはdrawableフォルダに格納してください。

■サンプルソース
●MainActivity
package com.example.rgrgre;

import android.os.Bundle;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.Toast;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //レイアウトの作成
        LinearLayout oLayout = new LinearLayout(getApplicationContext());
        //作成したレイアウトを画面に設定
       setContentView(oLayout);

        //ボタンを生成
        Button oBtn = new Button(getApplicationContext());
        oBtn.setText("ダイアログを出現させるボタンです。");
        //ボタンを押したら、ダイアログを出現させる
        oBtn.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
               showDialog(0);
            }
        });
        //ボタンをレイアウトに追加
        oLayout.addView(oBtn);
    }
 
    @Override
    protected Dialog onCreateDialog(int id) {
        //アラートダイアログの生成
        AlertDialog.Builder dialog = new AlertDialog.Builder(this);
        //カスタムビューを設定
        LayoutInflater inflater = (LayoutInflater)this.getSystemService(LAYOUT_INFLATER_SERVICE);
        //レイアウトのインフレーター
        final View layout = inflater.inflate(R.layout.dialog, (ViewGroup)findViewById(R.id.dialog_root));
        //パーツの作成
        dialog.setIcon(R.drawable.ic_launcher);
        dialog.setTitle("サンプル");
        //ダイアログのレイアウトを適用
        dialog.setView(layout);
        //ラジオグループの取得
        final RadioGroup oRGLEVEL = (RadioGroup)layout.findViewById(R.id.RG_LEVEL);
        final RadioGroup oRGBMG = (RadioGroup)layout.findViewById(R.id.RG_BGM);
        //起動時のチェックを付ける
        oRGLEVEL.check(R.id.RB_NORMAL);
        oRGBMG.check(R.id.RB_ON);

        //OKボタン押下後の処理を記述
        dialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {

            //チェックされているラジオボタンを取得
            RadioButton checkedLEVEL = (RadioButton)oRGLEVEL.findViewById(oRGLEVEL.getCheckedRadioButtonId());
            RadioButton checkedBGM =(RadioButton)oRGBMG.findViewById(oRGBMG.getCheckedRadioButtonId());

           //チェックされているラジオボタンのテキストを取得
            String sText = "難易度:" + checkedLEVEL.getText() + " BGM:" +checkedBGM.getText();
            //出力
            Toast.makeText(getApplicationContext(), sText , Toast.LENGTH_SHORT).show();
            //ダイアログを消す
            removeDialog(0);}
        });
        return dialog.create();
    }
}

●layout
dialog.xml



  
  
  
    
    
    
  
    
  

  
    
    
  


●drawable
dialog_bg_layout.xml


  
    
      
    
  
  
    
      
    
  
  
    
      
      
    
  



■実行結果





//レイアウトのインフレーター
final View layout = inflater.inflate(R.layout.dialog, (ViewGroup)findViewById(R.id.dialog_root));
ダイアログのビューとして利用できるようレイアウトを1度インフレートします。
また、定義することで、外部から関数からも参照できるように設定します。

//ダイアログのレイアウトを適用
dialog.setView(layout);
ビューに先ほどのレイアウトを適用させます。
これで、ダイアログの画面の設定は完了です。

//ラジオグループの取得
final RadioGroup oRGLEVEL = (RadioGroup)layout.findViewById(R.id.RG_LEVEL);
final RadioGroup oRGBMG = (RadioGroup)layout.findViewById(R.id.RG_BGM);
ラジオグループも定義して、外部参照できるようにして、ダイアログのOKボタンがクリックされたときに

//チェックされているラジオボタンを取得
RadioButton checkedLEVEL =(RadioButton)oRGLEVEL.findViewById(oRGLEVEL.getCheckedRadioButtonId());
RadioButton checkedBGM = (RadioButton)oRGBMG.findViewById(oRGBMG.getCheckedRadioButtonId());
クリック時の処理を取得できるようにしています。



アラートダイアログはAndroidで用意されている部品で作っているダイアログです。
なので、簡単に作成できます。
しかし、用意されている物なので、いかんせん自由度は低いです。

自由度が低い中で、今回は少しだけ頑張ってみました。。。