カメラ機能のパーミッションを追加すると、多くの端末でインストール不可になる現象について

アプリでカメラ機能を実装するために、AndroidManifest.xmlにパーミッションを追加しました。

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

しかし、これだけだとGooglePlayにおいて多くの端末で非表示になり、インストールできない状態になります。
カメラ機能が必須な設定になっているためで、それを解除しましょう。

<uses-feature android:name="android.hardware.camera.autofocus" android:required="false" />
<uses-feature android:name="android.hardware.camera" android:required="false" />

この記述を入れるだけで、対応端末が一気に2倍近く増えました!
忘れずに書いておきましょう!

参考:uses-permissionの落とし穴、サポートデバイスを増やすmanifestの記述 | Program Resource

Android開発者のみなさん、レイアウトを作るとき、文字やマージンの大きさって端末間の差をどうやって対応していますか?

レイアウトxmlを作るじゃないですか。

TextViewで、

android:paddingTop="4dp"

とか

android:textSize="12sp"

とかって書くじゃないですか。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@drawable/splash"
    android:orientation="vertical" >

    <TextView
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:paddingTop="4dp"
      android:textSize="12sp"
      android:text="フォントサイズ12sp" />

    <TextView
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:paddingTop="8dp"
      android:textSize="16sp"
      android:text="フォントサイズ16sp" />

    <TextView
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:paddingTop="12dp"
      android:textSize="20sp"
      android:text="フォントサイズ20sp" />

    <TextView
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:paddingTop="16dp"
      android:textSize="24sp"
      android:text="フォントサイズ24sp" />

    <TextView
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:paddingTop="20dp"
      android:textSize="28sp"
      android:text="フォントサイズ28sp" />

</LinearLayout>

Graphical Layoutで画面を確認するじゃないですか。

 

NexusSだとこう。

1

Nexus7だとこう。

2

もうイヤになっちゃいますよね……。

 

いかにAndroidでレイアウトを作るのが大変か、開発者以外の人にうまく伝える方法ってありませんかね?

 

さて、このような文字やマージンの大きさの端末対応、私はこのようにしています。

最近始めたやり方なので、まだ実証データが揃っていません。これで完全に対応できているとは思っていませんので、指摘やアドバイスなどあればコメントいただけるとありがたいです。

 

・valuesフォルダをいくつかに分け、その中にdimens.xmlを設置する

resフォルダ内のvaluesを、この画像のような構成で分けます。それぞれのフォルダにdimens.xmlを設置すると、アプリが動作するときに、そのAndroid端末の解像度ごとに適したフォルダのdimensを参照してくれます。

3

実際に色んなパターンで試したのですが、実際に参照してくれるフォルダは「values-sw600dp」と「values-v14」だけで、他のフォルダとdimensがあっても特にレイアウトに変化はありませんでした。

4

 

・dimens.xmlの中身を書く

それぞれのdimensに、文字のサイズとマージンの大きさの定義を書いていきます。

ここの実際の値は、まだ試行錯誤の途中です。もっと良い値の設定がありそうです。
[values]-[dimens.xml]

<resources>
    <dimen name="padding_size_SS">4dp</dimen>
    <dimen name="padding_size_S">6dp</dimen>
    <dimen name="padding_size_M">8dp</dimen>
    <dimen name="padding_size_L">12dp</dimen>
    <dimen name="padding_size_LL">16dp</dimen>
    <dimen name="padding_size_LLL">32dp</dimen>

    <dimen name="font_size_SS">12sp</dimen>
    <dimen name="font_size_S">14sp</dimen>
    <dimen name="font_size_M">16sp</dimen>
    <dimen name="font_size_L">20sp</dimen>
    <dimen name="font_size_LL">24sp</dimen>

</resources>

[values-sw600dp]-[dimens.xml]

<resources>
    <dimen name="padding_size_SS">12dp</dimen>
    <dimen name="padding_size_S">20dp</dimen>
    <dimen name="padding_size_M">28dp</dimen>
    <dimen name="padding_size_L">40dp</dimen>
    <dimen name="padding_size_LL">52dp</dimen>
    <dimen name="padding_size_LLL">100dp</dimen>

    <dimen name="font_size_SS">22sp</dimen>
    <dimen name="font_size_S">30sp</dimen>
    <dimen name="font_size_M">38sp</dimen>
    <dimen name="font_size_L">48sp</dimen>
    <dimen name="font_size_LL">60sp</dimen>

</resources>

[values-v14]-[dimens.xml]

<resources>
    <dimen name="padding_size_SS">4dp</dimen>
    <dimen name="padding_size_S">6dp</dimen>
    <dimen name="padding_size_M">8dp</dimen>
    <dimen name="padding_size_L">12dp</dimen>
    <dimen name="padding_size_LL">16dp</dimen>
    <dimen name="padding_size_LLL">32dp</dimen>

    <dimen name="font_size_SS">12sp</dimen>
    <dimen name="font_size_S">14sp</dimen>
    <dimen name="font_size_M">16sp</dimen>
    <dimen name="font_size_L">20sp</dimen>
    <dimen name="font_size_LL">24sp</dimen>

</resources>

・レイアウトXMLを書き換える

値を直接指定するのではなく、dimensを参照するようにします。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@drawable/splash"
    android:orientation="vertical" >

    <TextView
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:paddingTop="@dimen/padding_size_SS"
      android:textSize="@dimen/font_size_SS"
      android:text="フォントサイズSS" />

    <TextView
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:paddingTop="@dimen/padding_size_S"
      android:textSize="@dimen/font_size_S"
      android:text="フォントサイズS" />

    <TextView
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:paddingTop="@dimen/padding_size_M"
      android:textSize="@dimen/font_size_M"
      android:text="フォントサイズM" />

    <TextView
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:paddingTop="@dimen/padding_size_L"
      android:textSize="@dimen/font_size_L"
      android:text="フォントサイズL" />

    <TextView
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:paddingTop="@dimen/padding_size_LL"
      android:textSize="@dimen/font_size_LL"
      android:text="フォントサイズLL" />

</LinearLayout>

・これで端末対応でき……てるのかな?

5 6 7

Nexus7はまだちょっと見た目が遠いですが、さっきよりかは遥かにマシですね。

一番大きいNexus10なんかは、NexusSとそこまで違いがないように感じます。

 

今現在、私がやっている端末対応は以上となります。

もっと良い方法があるよー、という方は教えてください。(でも、簡単ですぐできる方法でお願いします)

WordPressでLightboxが動作しなくなった

記事にギャラリーを設置していたのですが、画像をクリックしても画像ページが開くだけでLightboxのスライドショーが動作しなくなる問題が発生しました。

原因は、jqueryの競合のようで、ネット上で探せばいくつか対応策が見つかります。

最も簡単な対応策としては、「wp-jquery-lightbox」というプラグインをインストールして、有効化することです。

ヘッダーファイルを書き換えたり、php.iniを書き換えたり、複数のプラグインをインストールしたり、いくつか試しましたがだめでした。自分の場合はwp-jquery-lightboxだけで直ってしまったので、拍子抜けです。

メディアを挿入するとき、フルサイズしか選択できない問題

記事に画像を入れようとしたときに、サイズ欄で「フルサイズ」しか表示されず、サムネイルなどが選択できなくなることがあります。

1

いくつか可能性は考えられますが、原因のひとつとして、「PHPでGDモジュールが有効になっていない」ことがあげられます。

 

・GDモジュールがインストールされているか確認

まずはGDモジュールがすでにインストールされているかどうかを確認します。

確認する方法は2つあります。

1.ターミナルから構成を確認

ターミナルにログインして

rpm -qa | grep php

とコマンドを実行して、「php-gd」が見つからなければインストールされていません。

 

2.phpの関数から確認

phpが有効になっているページで、

<?php

phpinfo();

?>

と入力して、ブラウザからアクセスしてください。すると、サーバーにインストールされているPHPの情報を見る事ができます。

2

このようなGDの欄が見当たらなければ、インストールされていません。

 

・GDモジュールをインストール

インストールは簡単です。

ターミナルから下記のコマンドを実行します。

$ yum install php-gd

そしてApacheの再起動

$ service httpd restart

これでGDモジュールが有効になったはずです!

 

・画像を再度アップロード

画像のサムネイルが生成されるのは、画像をメディアにアップロードした瞬間です。

なので、すでにアップロードした画像はGDが有効になっても、サムネイルが選択できるようにはなりません

使用したい画像を再度アップロードすれば、サムネイルが選択できるようになります!

3

プリファレンスで値をアプリ内に保存する かんたんライブラリ

前回の記事でプリファレンスについて書きましたが、いちいちあの記述で読み込み・保存するのはめんどくさい……という人もいると思います。
自分もそうだったので、簡易ライブラリを作りました。
これで多少はすっきりしたソースになるんじゃないかと思います。

[WrapperShared.java]

public class WrapperShared {
	Context context;
	
	SharedPreferences pref;
	final String FILE_NAME = "file_name";
	
	public static final String KEY_FIRST	= "first";
	
	public WrapperShared(Context context) {
		this.context = context;
		this.pref = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE);
	}
	
	//データの保存
	public void saveInt(String key, int value) {
		Editor editor = pref.edit();
		editor.putInt(key, value);
		editor.commit();
	}
	public void saveString(String key, String value) {
		Editor editor = pref.edit();
		editor.putString(key, value);
		editor.commit();
	}
	public void saveBoolean(String key, boolean value) {
		Editor editor = pref.edit();
		editor.putBoolean(key, value);
		editor.commit();
	}
	
	//データの取得
	public int getInt(String key, int default_value) {
		return pref.getInt(key, default_value);
	}
	public String getString(String key, String default_value) {
		return pref.getString(key, default_value);
	}
	public boolean getBoolean(String key, boolean default_value) {
		return pref.getBoolean(key, default_value);
	}
}

[MainActivity.java]

WrapperShared shared = new WrapperShared(this);
//値の読み込み
boolean first = shared.getBoolean(WrapperShared.KEY_FIRST, false);
//値の保存
shared.saveBoolean(WrapperShared.KEY_FIRST, true);
Top