LoginSignup
10
12

More than 5 years have passed since last update.

Androidでブルーライト軽減フィルターっぽいこと

Last updated at Posted at 2015-08-29

はじめに

最近ブルーライトをカットしてくれるメガネが売られていますが、スマホアプリにもブルーライトカットを
(本当にカット出来ているかは疑問ですが)謳っているアプリや明るさ調整のアプリがいくつか有ります。
似たような機能は"端末の輝度を設定"+"更にフィルターを掛ける"で実現出来るのでは無いでしょうか。
今回は後者の"更にフィルターを掛ける"部分を実装してみます。

実装

acticity_main.xml

フィルターを追加するボタンとフィルターを解除するボタンの2つだけがあるシンプルなものにします。
image

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="add Filter"
        android:id="@+id/ButtonAddFilter"
        android:layout_alignParentTop="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Remove Filter"
        android:id="@+id/ButtonRemoveFilter"
        android:layout_alignParentTop="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true" />
</RelativeLayout>

MainActivity.java

2つのボタンの挙動を実装します。
それぞれ単純にサービスのスタートとストップを行うだけです。

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button buttonAddFilter = (Button) findViewById(R.id.ButtonAddFilter);
        buttonAddFilter.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this, FilterService.class);
                startService(intent);
            }
        });

        Button buttonRemoveFilter = (Button) findViewById(R.id.ButtonRemoveFilter);
        buttonRemoveFilter.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this, FilterService.class);
                stopService(intent);
            }
        });
    }
}

filter.xml

画面サイズいっぱいに広がったImageViewを置きます。

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

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

FilterService.java

今回の肝となる部分。

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;

public class FilterService extends Service {

    private View mView;
    private WindowManager mWindowManager;

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        LayoutInflater layoutInflater = LayoutInflater.from(this);

        //重ねあわせするViewの設定
        WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(
                WindowManager.LayoutParams.MATCH_PARENT,
                WindowManager.LayoutParams.MATCH_PARENT,
                WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,      //オーバーレイヤーに設定
                WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
                PixelFormat.TRANSLUCENT                              //ウインドウの透明化
        );

        //WindowManagerを取得
        mWindowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);

        //レイアウトファイルから重ねあわせするViewを作成
        mView = layoutInflater.inflate(R.layout.filter, null);

        //透過率80の黒色のフィルターを指定
        //パラメータは左から(透過率,R,G,B) ココをいじれば任意のフィルターに変更可能
        mView.setBackgroundColor(Color.argb(80, 0, 0, 0));

        //Viewを画面上に重ねあわせする
        mWindowManager.addView(mView, layoutParams);

        return START_NOT_STICKY;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mWindowManager.removeView(mView);
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
}

AndroidManifest.xml

忘れがちですが、こちらにも追記が必要です。
うっかりパーミッションやサービスの定義を忘れると動きません(30分くらいハマりました。。。)。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="sample.masaibar.filtersample" >

    <!--パーミッション定義しないと動きません-->
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <!--サービスを定義しないとstartService出来ません-->
        <service android:name=".FilterService"/>
    </application>

</manifest>

動かしてみる

アプリを起動し、左側の「ADD FILTER」ボタンを押せばフィルターがかかります。
解除したいときは「REMOVE FILTER」を押して下さい。
左がフィルター無し、右がフィルター有り。同じ輝度での対比です。
フィルターを掛けた分だけ画面が暗くなっているのが分かります。
image

実際のコードを置いておきます。
https://github.com/masaibar/FilterSample

10
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
12