2

I'm trying to make app for Android which manipulate its screen (its colours, to be specific). I've got these two following classes:

static class ScreenAdjuster {

    public static void setAlpha(Layer view, int alpha){
        //Handle all conditions
           view.setColor(alpha, 0, 0, 0);
    }
    public static void setContrast(Layer view, int contrast){
        //Handle all conditions
        view.setColor(contrast, 100, 100, 100);
    }

    public static void setColor(Layer redView, Layer greenView, Layer blueView, int r, int g, int b){
        //Handle all conditions
        redView.setColor(r, 255, 0, 0);
        greenView.setColor(g, 0, 255, 0);
        blueView.setColor(b, 0, 0, 255);
        Log.d("display", "setting..." + r + " " + g + " " + b);
    }

}

class Layer extends View
{
      private int a;
      private int b;
      private int g;
      private int r;

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

      @Override
      protected void onDraw(Canvas canvas){
        super.onDraw(canvas);
        canvas.drawARGB(this.a, this.r, this.g, this.b);
        Log.d("display", "rendering..");
      }

      @Override 
      protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
         int parentWidth = MeasureSpec.getSize(widthMeasureSpec);
         int parentHeight = MeasureSpec.getSize(heightMeasureSpec);
         this.setMeasuredDimension(parentWidth/2, parentHeight);
         this.setLayoutParams(new ViewGroup.LayoutParams(parentWidth/2,parentHeight));
         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
         Log.d("display", "filling...");
      }

      public void setColor(int a, int r, int g, int b){
        this.a = a;
        this.r = r;
        this.g = g;
        this.b = b;
        invalidate();
       }
}

I'm adding views to manager in this function:

public void setColorsViews() {
    if(!colorsFirstTime) {
        view = new Layer(cordova.getActivity());
        redView = new Layer(cordova.getActivity());
        greenView = new Layer(cordova.getActivity());
        blueView = new Layer(cordova.getActivity());


        WindowManager localWindowManager = (WindowManager)cordova.getActivity().getSystemService("window");
        WindowManager.LayoutParams layoutParams = cordova.getActivity().getWindow().getAttributes();
        localWindowManager.addView(view, layoutParams);
        localWindowManager.addView(greenView, layoutParams);
        localWindowManager.addView(redView, layoutParams);
        localWindowManager.addView(blueView, layoutParams);
        colorsFirstTime = true;
         Log.d("display", "views added");
    }
}

(It will be plugin for Cordova, so I get Activity by cordova.getActivity(). It works with my another functions, so I suppose it works here too).

I invoke all this by: ScreenAdjuster.setColor(redView, greenView, blueView, red, green, blue) ;

But... nothing happens. All functions are invoked( onDraw(), onMeasure(), setColorsViews(), but screen remains the same.

What am I doing wrong?

Thanks in advance!

tomwesolowski
  • 956
  • 1
  • 11
  • 27
  • Can you try using the solution in [this](http://stackoverflow.com/a/7658364/2581872) answer? – hichris123 Jan 06 '14 at 03:34
  • It's not about brightness (I used this solution and it works). It's about manipulating with colors. – tomwesolowski Jan 06 '14 at 09:51
  • I'm not sure the view will get positioned as you expect. Could you try to just test the view positioning giving them a background color just to understand where they are getting positioned? – Pasquale Anatriello Jan 06 '14 at 10:44
  • When do you call `setColorsViews()` in the activity life cycle? Also, why are you using 4 copies of your Layer view, instead of a single one? Drawing four full-screen views is really going to make your app's framerate drop--will look bad if there are any scrollable lists or animations. – Tenfour04 Jan 07 '14 at 01:19
  • several mistakes are made in your code overall in onMeasure hook. I recommend to simplify your code, doing a overlay with a view and then call View.setBackgroundColor(int color) – Xenione Jan 08 '14 at 18:43
  • But, with these changes, I will be still able to change colours saturation? – tomwesolowski Jan 08 '14 at 19:50
  • yes of course, setBackgroundColor(int color) where color is hex refresentation of alpha, Red, Green and Blue – Xenione Jan 09 '14 at 15:37

2 Answers2

3

Change:

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int parentWidth = MeasureSpec.getSize(widthMeasureSpec);
        int parentHeight = MeasureSpec.getSize(heightMeasureSpec);
        this.setMeasuredDimension(parentWidth / 2, parentHeight);
        //Since you are attatching it to the window use window layout params.
        WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(parentWidth / 2,
                parentHeight);
        this.setLayoutParams(layoutParams);

        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        Log.d("display", "filling...");
    }

Add: layoutParams.format = PixelFormat.TRANSLUCENT;

public void setColorsViews() {
    if (!colorsFirstTime) {
        view = new Layer(cordova.getActivity());
        redView = new Layer(cordova.getActivity());
        greenView = new Layer(cordova.getActivity());
        blueView = new Layer(cordova.getActivity());

        WindowManager localWindowManager = (WindowManager) cordova.getActivity()
                .getSystemService("window");
        WindowManager.LayoutParams layoutParams = cordova.getActivity().getWindow()
                .getAttributes();
        layoutParams.format = PixelFormat.TRANSLUCENT;

        localWindowManager.addView(view, layoutParams);
        localWindowManager.addView(greenView, layoutParams);
        localWindowManager.addView(redView, layoutParams);
        localWindowManager.addView(blueView, layoutParams);
        colorsFirstTime = true;
        Log.d("display", "views added");
    }
}

ScreenAdjuster.setColor(redView, greenView, blueView, 50, 150, 0); ScreenAdjuster.setColor(redView, greenView, blueView, 50, 150, 0);

ejohansson
  • 2,832
  • 1
  • 23
  • 30
  • I'm afraid, it's not working for me. When I call setColor for the first time, screen blinks for a moment and nothing changed. I attach whole file: http://speedy.sh/tXHmD/Display.java – tomwesolowski Jan 12 '14 at 12:48
  • ok, I'll have to install cordova and try it. This is Android native code (mistakenly I thought it would work). What device are you testing it on? – ejohansson Jan 12 '14 at 20:07
  • HTC Nexus One (Android 2.3) – tomwesolowski Jan 12 '14 at 20:55
1

Looks like, from the Android spec for the WindowManager:

Throws WindowManager.BadTokenException for certain programming errors, 
such as adding a second view to a window without removing the first view.

By adding the following line between each addView(...), it would remove the previous view, and load the next view:

localWindowManager.removeView(View view);

Or, you could change the subsequent three lines to the following, having them replace the current view:

lastWindowManager.updateViewLayout(view, params);

You should also change to the following code (or something similar) if you want to be displaying the RGB color that is input by the user:

view = new Layer(cordova.getActivity());
view.setColor(int a, int r, int g, int b)      //enter values here somehow?
localWindowManager.addView(view, layoutParams);

This will create a view from the new class, assign values to the A, R, G, and B, and then add that new view as the current view.

p.s. - I have limited Android development experience, so I am unsure as to whether this is correct, but looking at the documentation it would seem to point to this solution. Also, without seeing all the code I'm not certain this is the fix...

MaineCoder
  • 159
  • 1
  • 10