【Android】GooglePlay公開用のAPKファイル(.apk)を作成する

【手順1】

APKファイルを作成したいプロジェクトを[パッケージ・エクスプローラー]内から選択、
右クリックして、[Androidツール]→[Export Signed Application Package...]の順に選択する。

apkファイル作成001

【手順2】

プロジェクトを選択(デフォルトで選択されている)し、[次へ]をクリックする。

apkファイル作成02

【手順3】

新規の場合は、[Create new keystore]をチェックし、
ロケーション:保存先
パスワード:パスワードを入力
確認:パスワードを確認
を入力して[次へ]をクリックする。

apkファイル作成003

【手順4】

証明書署名
エイリアス:署名
パスワード:パスワードを入力
確認:パスワードを確認
Validity(years):使用期限(25以上)
First and Last Name:名前
を入力して[次へ]をクリックする。

apkファイル作成004

【手順5】

apkファイルの保存先を指定して[完了]をクリックする。

apkファイル作成005

apkファイルの他にもう一つ生成されるファイルがデジタル署名のカギになるので失くさないように保管しよう。

【Android】戻るボタン(BACKボタン)でアラートダイアログを表示

Androidアプリで戻るボタン(BACKボタン)が押された時にアラートダイアログを表示したい。

キーイベントをonKeyDown/onKeyUpメソッドで取得する(Viewクラスのメソッドをオーバライド)
キーイベントが発動した時に、アラートダイアログを表示する。

onKeyDownはキーを押した瞬間、onKeyUpはキーを放した瞬間にイベントが発動します。

【Activity000.java】

public class Activity000 extends Activity {
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
	}
	
	// BACKボタンが押された時の処理
	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if(keyCode==KeyEvent.KEYCODE_BACK){
			// アラートダイアログ
			showDialog(0);
			return true;
		}
		return false;
	}
	
	// アラートダイアログ
	@Override
	public Dialog onCreateDialog(int id) {
		switch (id) {
	 
		case 0:
			//ダイアログの作成(AlertDialog.Builder)
			return new AlertDialog.Builder(Activity000.this)
			.setMessage("「アプリ」を終了しますか?")
			.setCancelable(false)
			// 「終了する」が押された時の処理
			.setPositiveButton("終了する", new DialogInterface.OnClickListener() {
				public void onClick(DialogInterface dialog, int id) {
					// アクティビティ消去
					Activity000.this.finish();
				}
			})
			// 「終了しない」が押された時の処理
			.setNegativeButton("終了しない", new DialogInterface.OnClickListener() {
				public void onClick(DialogInterface dialog, int id) {

				}
			})
			.create();
		}
		return null;
	}
}

【Android】SurfaceView上でCanvasに描画する文字列の幅を取得する

SurfaceView上でCanvasに描画する前に文字列の幅を取得する方法。
取得するにはPaintクラスのmeasureText()メソッドを利用する。

【SampleSurfaceView.java】

public class SampleSurfaceView11 extends SurfaceView implements SurfaceHolder.Callback{
	
    // 描画用
	Paint paint = null;
    
    String put_txt = "文字列の横幅を取得";
    
	public SampleSurfaceView11(Context context) {
		super(context);
		
		getHolder().addCallback(this);
		paint = new Paint();
	}
	
	public void surfaceCreated(SurfaceHolder holder) {
		
		Canvas canvas = holder.lockCanvas();
		canvas.drawColor(Color.BLACK);
		paint.setColor(Color.WHITE);
		paint.setTextSize(30);
		
		// テキストの幅を取得する
		float testWidth = paint.measureText(put_txt);
		
		canvas.drawText(put_txt, 0, paint.getTextSize(), paint);
		canvas.drawText("テキスト幅は" + testWidth + "px です", 0, paint.getTextSize()*3, paint);
		
		holder.unlockCanvasAndPost(canvas);
	}
	
	public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

	}
    
	public void surfaceDestroyed(SurfaceHolder holder) {

	}
}

【Activity000.java】

public class Activity000 extends Activity {

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		
		// アクティビティにビューを追加する
		setContentView(new SampleSurfaceView(this));
	}
}

【出力結果】
Canvasに描画する文字幅を取得

measureText()メソッドで文字列(テキスト)の幅を取得できる

【Android】画面の向きを固定(回転しない)

Androidアプリでは通常、端末を横にすると横画面に、縦にすると縦画面になります。
レイアウトやデザイン上、端末を回転させても画面を回転させたくない場合は画面を固定します

【縦向きに画面を固定(AndroidManifest.xmlで指定)】

<activity
	android:label="@string/app_name"
	android:name=".Activity01"
	android:screenOrientation="portrait">
</activity>

【横向きに画面を固定(AndroidManifest.xmlで指定)】

<activity
	android:label="@string/app_name"
	android:name=".Activity01"
	android:screenOrientation="landscape">
</activity>

【縦向きに画面を固定(Activityで指定)】

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

	// 縦向きに画面を固定
	this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}

【横向きに画面を固定(Activityで指定)】

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

	// 横向きに画面を固定
	this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}

動的に指定する場合はプログラム上で処理する

【Android】プリファレンスを利用してデータを簡単に保存する

Androidアプリ開発で、データを保存する方法はいくつかある。

データを保存・利用するには「SQLite」などのデータベースを使用するのが一般的であるが、データベースを使うまでもない事もある。
そういった場合、Androidでは「プリファレンス」というキー名と値の組合わせから構成されるデータをXML形式で保存する機能がある。

保存できるデータは、boolean型、float型、int型、long型、String型のみ。

今回は、このプリファレンスを利用してデータを簡単に保存し、出力してみる。

【値を保存】

// オブジェクトを取得 getSharedPreferences("プリファレンス名", 共有モード);
SharedPreferences pref_in = getSharedPreferences("prefname", MODE_PRIVATE);
// エディターオブジェクト生成
Editor editor = pref_in.edit();
// プリファレンスファイルへの書き込み putString("キー名", "データ")
editor.putString("keyname", "data");
// commit()メソッドの実行で値を保存
editor.commit();

【保存データを取得】

// オブジェクトを取得 getSharedPreferences("プリファレンス名", 共有モード);
SharedPreferences pref_out = getSharedPreferences("prefname", MODE_PRIVATE);
// プリファレンスファイルからデータを取得 putString("キー名", "データ")
String str = pref_out.getString("keyname", "data");

【利用例】

public class Activity000 extends Activity {
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		
		// 値を保存
		SharedPreferences pref_in = getSharedPreferences("name", MODE_PRIVATE);
		Editor editor = pref_in.edit();
		editor.putString("key1", "001");
		editor.putString("key2", "あいうえお");
		editor.commit();
		
		// 保存データを取得
		SharedPreferences pref_out = getSharedPreferences("name", MODE_PRIVATE);
		String str1 = pref_out.getString("key1", "default");
		String str2 = pref_out.getString("key2", "default");
		
		// データを出力
		Toast.makeText(getBaseContext(), str1, Toast.LENGTH_SHORT).show();
		Toast.makeText(getBaseContext(), str2, Toast.LENGTH_SHORT).show();
	}
}

【出力結果】

Preferences

【Android】カスタムViewから起動させるActivityに値を渡す方法

SurfaceviewなどのカスタムViewから起動させるActivityに値を渡したい。

当然、通常のActivityから起動する時と同じ記述ではうまくいかない。
カスタムViewからコンテキスト(Context)というのを利用するらしい。

コンテキスト(Context)とは:アプリケーションの情報をグローバルに受け渡しする為のインターフェース

Intent intent = new Intent(getContext(), ActivityNext.class);
intent.putExtra("key", key);
getContext().startActivity(intent);

intent.putExtra(Keyの名前, 渡す値);

【Android】画像を画面サイズに合わせて表示する(マルチデバイス対応)

画像を複数デバイスの画面サイズに合わせて表示しマルチデバイスに対応したい。

Androidデバイスは画面サイズやアスペクト比がさまざまで、基準が決めにくい為、
iphone3G(320×480px)やiphone4(640×960px)の画像解像度のアスペクト比2:3を基準にする。

■仕様■
・準備する画像はすべてアスペクト比2:3とする。
・画面表示は横幅を基準とし、横幅いっぱいに表示する。
・ほとんどの機種で高さが少し短くなるので、画像を中央に配置し、余白(背景)は黒にする。
・現行機種でアスペクト比2:3よりも高さが小さいものはない様なので、このタイプは対応しない事とする。

【ImageResizeView.java】(マルチデバイス対応画像リサイズクラス)

public class ImageResizeView extends View{
	
	private Bitmap bmp;
	private int dp_w;
	private int dp_h;
	private int drow_h;
	private int drow_s;
	
	public ImageResizeView(Context context, int resource_name){
		super(context);
		// リソースからbitmapを作成
		bmp = BitmapFactory.decodeResource(context.getResources(), resource_name);
		// WindowManager取得
		WindowManager wm = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
		// Displayインスタンス生成
		Display dp = wm.getDefaultDisplay();
		// ディスプレイサイズ取得
		dp_w = dp.getWidth();
		dp_h = dp.getHeight();
		// リサイズ画像の高さ
		drow_h = (dp_w / 2) * 3;
		// 描画始点の高さ
		drow_s = (dp_h - drow_h) / 2;
	}

	@Override
	protected void onDraw(Canvas canvas){
		// 背景色
		canvas.drawColor(Color.BLACK);
		// イメージ画像リサイズ
		bmp = Bitmap.createScaledBitmap(bmp, dp_w, drow_h , true);  
		// 描画
		canvas.drawBitmap(bmp, 0, drow_s, null);
	}
}

Viewクラスを継承して、onDrawメソッドをオーバーライドしてcanvasに描画する。

【Activity000.java】(Activityクラス)

public class Activity000 extends Activity {

	// リソースファイル名
	int resource_name = R.drawable.img00;
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        
		setContentView(new ImageSizePut(this, resource_name));
	}
}

【出力結果】
画像マルチデバイス対応

【Android】リソースの画像サイズを取得する

リソースの画像サイズを取得してみる。

今回は、複数のActivityから利用したいので、別クラスを作成する。
Activityでインスタンスを生成して、リソースの画像を指定し、その画像サイズを受け取る。

【ImageSizeGet.java】

public class ImageSizeGet{

	// 画像のサイズを取得するメソッド
	public String getSize(Context context, int resource_name){
		// リソースからbitmapを作成
		Bitmap image = BitmapFactory.decodeResource(context.getResources(), resource_name);
		
		// 画像サイズ取得
		int width  = image.getWidth();
		int height = image.getHeight();
		
		// 画像サイズの文字列を返す
		String size = "w:" + width + ",h:" + height;
		return size;
	}
}

Context : アプリケーションの環境情報をグローバル(AndroidOSの全域)に受け渡しするためのインターフェース

【Activity000.java】

public class Activity000 extends Activity {

	// リソースファイル名を指定
	int resource_name = R.drawable.img01;
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		
		// ImageSizeGetクラスをインスタンス化する
		ImageSizeGet put_text = new ImageSizeGet();
		
		// ImageSizeGetのgetNameメソッドを呼び出す
		String size = put_text.getSize(this, resource_name);

		// TextViewを準備
		TextView tv = new TextView(this);
		
		// テキスト出力
		tv.setText(size);
		setContentView(tv);
	}
}

Activityからメソッドを呼ぶ時に渡す引数Contextには、Activity自身を指すthisを指定する

【出力結果】

w:横幅,h:高さ

【Android】SurfaceViewに対するタッチイベントで再描画する

SurfaceViewに対するイベント処理も、考え方は通常のViewでの処理とほとんどかわりません。

今回はSurfaceViewに描画した真顔のイラストをタッチ後、笑顔にする。

【準備画像】

SurfaceViewにタッチイベント

public class SampleSurfaceView extends SurfaceView implements SurfaceHolder.Callback{
	
	// 表示する画像
	private Bitmap image01;
	private Bitmap image02;
	private Bitmap image03;
	private Bitmap image02b;
     
	// コンストラクタ
	public SampleSurfaceView4(Context context) {
		super(context);
         
		getHolder().addCallback(this);
		// Bitmapリソースを用意
		image01 = BitmapFactory.decodeResource(getResources(), R.drawable.face);
		image02 = BitmapFactory.decodeResource(getResources(), R.drawable.eye);
		image02b = BitmapFactory.decodeResource(getResources(), R.drawable.eye2);
		image03 = BitmapFactory.decodeResource(getResources(), R.drawable.mouth);
	}
     
	// SurfaceView生成時に呼び出される(初期画面の描画)
	public void surfaceCreated(SurfaceHolder holder) {
    	
		doDraw(holder);
	}
     
	// SurfaceView変更時に呼び出される(画面の更新処理)
	public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
		// 処理がない場合も必要
	}
     
	// SurfaceView破棄時に呼び出される(画面の削除、削除後の処理)
	public void surfaceDestroyed(SurfaceHolder holder) {
		// 処理がない場合も必要
	}
    
	private void doDraw(SurfaceHolder holder) {
		// Canvas取得しロックする
		Canvas canvas = holder.lockCanvas();
		Paint paint = new Paint();
		//paint.setColor(Color.WHITE);
         
		// 描画処理
		canvas.drawBitmap(image01, 0, 0, paint);
		canvas.drawBitmap(image02, 0, 0, paint);
		canvas.drawBitmap(image03, 0, 0, paint);
         
		// LockしたCanvasを解放する
		holder.unlockCanvasAndPost(canvas);
	}
	
	private void onDraw(SurfaceHolder holder) {
		// Canvas取得しロックする
		Canvas canvas = holder.lockCanvas();
		Paint paint = new Paint();
		//paint.setColor(Color.WHITE);
         
		// 描画処理
		canvas.drawBitmap(image01, 0, 0, paint);
		canvas.drawBitmap(image02b, 0, 0, paint);
		canvas.drawBitmap(image03, 0, 0, paint);
         
		// LockしたCanvasを解放する
		holder.unlockCanvasAndPost(canvas);
	}
	
	// タッチイベント
	@Override
	public boolean onTouchEvent(MotionEvent event){
		onDraw(getHolder());
		return true;
	}
}

【実行結果】
SurfaceViewでオンタッチイベント

【Android】FrameLayout内でTextViewにマージンを指定する

前回、「FrameLayoutでSurfaceViewとTextViewと重ねて表示する」で作成したTextViewにマージンを指定する。
しかし、元となるレイアウトがFrameLayoutの場合、TextViewにmarginが設定できない。

FrameLayoutとTextViewの間にmarginが設定できるLinearLayoutを噛ませてやればうまくいく。

例)
FrameLayout -> TextView

FrameLayout -> LinearLayout -> TextView

【Activity000.java】

public class Activity000 extends Activity {

	// LayoutParamsにセットするパラメータを準備
	private final int FP = ViewGroup.LayoutParams.FILL_PARENT; 
	private final int WC = ViewGroup.LayoutParams.WRAP_CONTENT;
	private final int LFP = LinearLayout.LayoutParams.FILL_PARENT;
	private final int LWC = LinearLayout.LayoutParams.WRAP_CONTENT;
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		
		// FrameLayoutを準備
		FrameLayout fl = new FrameLayout(this);
		setContentView(fl);
 
		// FrameLayoutにSurfaceViewをセットする
		fl.addView(new SampleSurfaceView2(this),new ViewGroup.LayoutParams(WC, WC));
        
		// SurfaceViewと重ねるTextViewを準備
		TextView tv = new TextView(this);
		tv.setText("SurfaceViewとTextViewを重ねる\nさらにTextViewにマージンを指定する");
		tv.setHeight(120);
		tv.setTextColor(Color.BLACK);
		tv.setBackgroundColor(Color.WHITE);
		
		// TextViewを入れるLinearLayoutを準備
		LinearLayout ll = new LinearLayout(this);
		LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LFP, LWC);
		lp.setMargins(10, 10, 10, 10);
		tv.setLayoutParams(lp);
		ll.addView(tv);
		
		// FrameLayoutにLinearLayoutをセットする
		fl.addView(ll, new ViewGroup.LayoutParams(FP, WC));
	}
}

setMarginsのパラメータ指定 : setMargins(左, 上, 右, 下)

【実行画面】

setMargins