ひらい ぶらり Hi-Library

ぷろぐらみんぐについて。ときどきどうでもいいことについて。

ImageViewの明度、コントラスト、彩度、色相をObjectAnimatorでアニメーションする

タイトルのようなことをしたかったんですが、そんなプロパティはなかったのでImageViewを拡張してプロパティをつけたら出来ました。

↓のようなクラスを作って、xmlなり動的に生成するなりしたImageViewに対して操作をすれば期待した動きをしてくれる。

public class ExtendedPropatyImageView extends ImageView{

    private static final float[] defaultValues = {
            1, 0, 0, 0, 0,
            0, 1, 0, 0, 0,
            0, 0, 1, 0, 0,
            0, 0, 0, 1, 0
    };
    private int mBrightness = 0;
    private float mContrast = 0f;
    private float mSaturation = 0f;
    private float mHue = 0f;
    private int mRed = 0;
    private int mGreen = 0;
    private int mBlue = 0;

    public ExtendedPropatyImageView(Context context) {
        super(context);
    }

    public ExtendedPropatyImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public void setBrightness(int brightness) {
        float[] values = defaultValues;
        ColorMatrix matrix = new ColorMatrix();
        values[4] = values[9] = values[14] = brightness;
        setColorFilter(new ColorMatrixColorFilter(values));
        mBrightness = brightness;
    }

    public int getBrightness() {
        return mBrightness;
    }

    public void setContrast(float contrast) {
        float[] values = defaultValues;
        values[0] = values[6] = values[12] = contrast;
        setColorFilter(new ColorMatrixColorFilter(values));
        mContrast = contrast;
    }

    public float getContrast() {
        return mContrast;
    }

    public void setSaturation(float saturation) {
        ColorMatrix matrix = new ColorMatrix();
        matrix.setSaturation(saturation);
        setColorFilter(new ColorMatrixColorFilter(matrix));
        mSaturation = saturation;
    }

    public float getSaturation() {
        return mSaturation;
    }

    public void setHue(float hue) {
        float[] values = defaultValues;
        float a = Math.max(0, (float) Math.cos(hue / 360 * 2 * Math.PI));
        float b = Math.max(0, (float) Math.cos((hue - 120) / 360 * 2 * Math.PI));
        float c = Math.max(0, (float) Math.cos((hue - 240) / 360 * 2 * Math.PI));
        float sum = a + b + c;
        values[0] = values[6] = values[12] = a / sum;
        values[1] = values[7] = values[10] = b / sum;
        values[2] = values[5] = values[11] = c / sum;
        setColorFilter(new ColorMatrixColorFilter(values));
        mHue = hue;
    }

    public float getHue() {
        return mHue;
    }

    public void setRed(int red) {
        float[] values = defaultValues;
        values[4] = red;
        setColorFilter(new ColorMatrixColorFilter(values));
        mRed = red;
    }

    public int getRed() {
        return mRed;
    }

    public void setGreen(int green) {
        float[] values = defaultValues;
        values[9] = green;
        setColorFilter(new ColorMatrixColorFilter(values));
        mGreen = green;
    }

    public int getGreen() {
        return mGreen;
    }

    public void setBlur(int blue) {
        float[] values = defaultValues;
        values[14] = blue;
        setColorFilter(new ColorMatrixColorFilter(values));
        mBlue = blue;
    }

    public int getBlue() {
        return mBlue;
    }
}

アニメーションさせるときはこんな感じ

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ExtendedPropatyImageView image = (ExtendedPropatyImageView) findViewById(R.id.image_view);
    ObjectAnimator objectAnimator = ObjectAnimator.ofInt(image, "brightness", 0, 255);
    objectAnimator.setDuration(1000);
     objectAnimator.start();

}

後は値の型に合わせてofFloatにするなり、brightnessをhueやらに変えればそのプロパティを変更するアニメーションを実行することが出来た。

ColorMatrixクラスに彩度をセットするメソッドはあったけど、なんで他は無いんだろう・・・

Android Studio を 0.8.14 にアップデートしたら「The Android SDK folder can no longer be inside the application folder.」とか言われた

こんにちはこんにちは

久しぶりにAndroid Studioを起動することになったらアップデートが来てたので、作業後にアップデートしてみることに。

f:id:shin_bashi:20141031212849p:plain

なんか出た。

んー、SDKフォルダをApplicationsに置くなということらしい。詳細を見てみると本来はそういうとこに置くもんじゃないでしょ、的なことが書いてある。

いや、それはそうなんだけど、そこに配置してたのは(ry という言葉はぐっと飲み込み言われる通りに

mv /Applications/Android Studio.app/Contents/sdk ~/

適当にUsers以下とかに移す。

Retryを押す。進む。

当然の如くSDKのパスが変わっているので、起動するとSDKはどこだ!って言われる。

f:id:shin_bashi:20141031215614p:plain

他にもSDKを使ってるツールがアレばひと通りパスを修正してあげましょう。

終わり。

androidで強制的にChromeで開くリンク

<a href="intent://yahoo.co.jp#Intent;scheme=http;action=android.intent.action.VIEW;package=com.android.chrome;end
">Chromeで開く</a>

このリンクを開くアプリケーションがまともな実装をしている場合に限り、http://yahoo.co.jpが開かれるっぽい。 Operadで実験してみたところ成功したけど、全てのアプリで起動するかわWebViewClientの実装によるので絶対とはいえないのが切ないところ。

そして、使いどころもよくわからない。

WebViewとかで未知のSchemeに対する処理最新版(?)

androidアプリを作る際にWebViewを組み込んでアプリ内ブラウザで表示することとかよくあると思います。 そんな時にWebページの中にhoge://hugahugaみたいなURIが出てきた場合は、大体shouldOverrideUrlLoading内に

   @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
        Uri uri = Uri.parse(url);
        String scheme = uri.getScheme();
        if (scheme.indexOf("http") != 0) {
            Uri intent_uri = Uri.parse(url);
            Intent intent = new Intent(Intent.ACTION_VIEW, intent_uri);
            activity.startActivity(intent);
            return true;
        }
        return super.shouldOverrideUrlLoading(view, url);
    }

こんなかんじの(他にもjavascript://とかありますけど割愛)処理を書いていると思います。 要は自前でハンドリングしてないSchemeはIntentとして飛ばすよ、的な処理ですがこれでちょっとこまったことに

何に困ったかって「アプリがインストールされてればschemeで起動、なければマーケットに飛ばすリンク」の場合、コレだとおかしくなるんですね。

<a href="intent://sample#Intent;scheme=foo;package=jp.example.foo;end">OPEN</a>

↑こんなやつ

どう困るかってUri.parse(url)こいつは#とか余計なものを弾いてしまうので、正しくIntentが送られない。どうすっぺかってんで調べてみたらIntent.getIntent(url)を使うと良いらしいのですが、こいつ結構前から非推奨になってる。 なのでIntent.parseUri(url, flag)を使うのが良さそう。

でも最近android全然触れてないので動作検証すらしてない。 これ正しいのかなぁ。 おわり。

Laravel4 でSessionをMemcachedに保存したい

備忘録

  • phpのモジュールでmemcached入れておく必要があるよ
  • memcacheじゃないよ

app/config/session.php

<?php
    /*
    |--------------------------------------------------------------------------
    | Default Session Driver
    |--------------------------------------------------------------------------
    |
    | This option controls the default session "driver" that will be used on
    | requests. By default, we will use the lightweight native driver but
    | you may specify any of the other wonderful drivers provided here.
    |
    | Supported: "file", "cookie", "database", "apc",
    |            "memcached", "redis", "array"
    |
    */

    'driver' => 'memcached',

こうかきます。なんか動いてます。memcacheの設定はどこに書くのだ・・・(:3」∠)

app/config/cache.php

<?php
    /*
    |--------------------------------------------------------------------------
    | Memcached Servers
    |--------------------------------------------------------------------------
    |
    | Now you may specify an array of your Memcached servers that should be
    | used when utilizing the Memcached cache driver. All of the servers
    | should contain a value for "host", "port", and "weight" options.
    |
    */

    'memcached' => array(

        array('host' => '127.0.0.1', 'port' => 11211, 'weight' => 100),

    ),

cache・・・だと・・・(:3」∠)!? 見た感じ、これ複数サーバー書くだけで分散されるんだろうか?細かい説明あんまりかいてないんだよなぁ・・・Max100なのかなぁ・・・

Laravel4で複合プライマリーキーを設定する

Laravel4のSchemeBuilderを使って複合プライマリーキーを設定したかったけどダメだった。 パーティションを切りたかったので、パーティションのキーになる日時も合わせて複合主キーにしたかったけど、incrementsメソッドにはもれなくprimaryがついちゃうらしく

<?php
// こうとか
Schema::create("log", function($table) {
                $table->increments('id');
                $table->timestamps();
                $table->primary(['id', 'created_at']);
            });
// こうとか
 Schema::create("log", function($table) {
                $table->increments('id');
                $table->timestamps();
                $table->primary('created_at');
            });

こんなかんじにやってもエラーがでます。idからdropPrimaryをしてみてもエラーになる。 どないせいっちゅうねん

結論:使わない

本末転倒な気もするけど、とりあえずmigrationの最初に設定できればいいので、以下みたいにすれば問題ない(ある)

<?php
Schema::create("log", function($table) {
                $table->increments('id');
                $table->timestamps();
            });

DB::statement("
    ALTER TABLE `log`
    DROP PRIMARY KEY,
    ADD PRIMARY KEY (`id`, `created_at`);
    ");

わーい\\٩( 'ω' )و ///できたぞー(当たり前) incrementsとprimaryは別々にしてほしい(小並感)

Android Studio 0.4.2 にあげたら 「You are using Gradle version 1.6, which is not supported. Please use version 1.9. Please point to a supported Gradle version in the project's Gradle settings or in the project's Gradle wrapper (if applicable.)」とか言われた

久しぶりにandroidのアプリケーションをいじることになったので、AndroidStudioを新しいマシンに入れ直して、目的のプロジェクトをcloneして、gradleはwrapperを使うようにして開いたところ、表題のようなことを言われた。

「おめーのプロジェクトで使ってるgradle古いから。サポートしてねぇから。」 ということらしい。たぶん。

以下の手順で解消。

  1. build.gradleのバージョンを修正

各モジュール以下にあるbuild.gradleファイルのdependenciesの項目で、gradle:0.5.+になってるのをgradle:0.7.+に変更

 buildscript {
    repositories {
      mavenCentral()
    }
   dependencies {
      classpath 'com.android.tools.build:gradle:0.7.+'
   }
}
  1. wrapperで指定しているgradleのバージョンを修正

[yourproject]/gradle/wrapper/gradle-wrapper.properties このファイルのgradle-1.6-bin.zipとかってなってるのをgradle-1.9-bin.zipに変更

distributionUrl=http\://services.gradle.org/distributions/gradle-1.9-bin.zip

これで開き直せば解決。

参考:http://stackoverflow.com/questions/21069275/android-studio-0-4-2-gradle-version-is-confused Android Studio 0.4.2, Gradle version is confused