我给自己买了一个安卓车载单元,得出的结论是夜间开车时最低亮度仍然很明亮。有一个聪明的应用程序称为屏幕过滤器(我认为它的工作原理)在屏幕上使用覆盖来伪造屏幕变暗。我想自己做这个,因为我希望在日落时启用它并在日出后禁用它。
在网上搜索后,我发现了一个可用的代码。 使用名为Overlayservice的服务创建Main活动。该服务在我启动应用程序时运行,并且叠加层也可正常运行。
我想做的下一件事是代码,所以我可以改变叠加透明度。我希望程序在日落开始时开始淡化,例如半小时后透明度为50%。 我面临的问题是,当覆盖在服务中处于活动状态时,我无法设置新的颜色和透明度。
我厌倦了在服务中创建一个定时器,在5秒后设置颜色但我遇到了错误:
只有创建视图层次结构的原始线程才能触及其视图。
我现在的代码如下:
package erik.autostart;
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.util.Log;
import android.view.Gravity;
import android.view.WindowManager;
import android.widget.LinearLayout;
import java.util.Timer;
import java.util.TimerTask;
public class OverlayService extends Service {
String color;
LinearLayout oView;
WindowManager.LayoutParams localLayoutParams;
private static Timer timer = new Timer();
@Override
public IBinder onBind(Intent i) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
this.color = intent.getExtras().getString("color");
Log.v("Message","Intent: " + Color.parseColor(this.color));
oView = new LinearLayout(getBaseContext());
localLayoutParams = new WindowManager.LayoutParams();
oView.setBackgroundColor(Color.parseColor(this.color)); //De eerste 2 waardes zijn de density ff is volledig en 00 is weg de laatste 6 waardes zijn hex color waardes, kan dus zwart zijn.
WindowManager.LayoutParams localLayoutParams = new WindowManager.LayoutParams();
WindowManager manager = ((WindowManager) getApplicationContext().getSystemService(Context.WINDOW_SERVICE));
localLayoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;
localLayoutParams.gravity = Gravity.TOP;
localLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE|
// this is to enable the notification to recieve touch events
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |
// Draws over status bar
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
localLayoutParams.width = WindowManager.LayoutParams.MATCH_PARENT;
localLayoutParams.height = WindowManager.LayoutParams.MATCH_PARENT;
localLayoutParams.format = PixelFormat.TRANSLUCENT;
manager.addView(oView, localLayoutParams);
timer.scheduleAtFixedRate(new Task(), 0, 500);
return START_STICKY;
}
private class Task extends TimerTask
{
public void run()
{
Log.v("Message", "Tasker");
runtask();
}
}
void runtask()
{
if(oView!=null){
oView.setBackgroundColor(Color.parseColor("#ff000000"));
WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
wm.updateViewLayout(oView, oView.getLayoutParams());
}
}
@Override
public void onCreate() {
super.onCreate();
Log.v("Message", "OverlayService started");
}
@Override
public void onDestroy() {
if(oView!=null){
WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
wm.removeView(oView);
}
Log.v("Message", "Destroying OverlayService");
super.onDestroy();
}
}
我想在某处运行任务器,以便我可以设置新颜色并更新叠加层。 为了解决这个问题,我想也许停止服务并用新颜色再次启动它会有所帮助,所以我在Mainactivity中取得了一个接受者并停止了服务并开始了一个不同颜色的新服务。问题在于屏幕闪烁。
我希望有人可以帮我解决这个问题。甚至可以做我想做的事情吗?
答案 0 :(得分:0)
我之前承诺的完整答案。对于未经测试的代码,我很抱歉,我在大约半年内没有对Android开发做任何事情,也没有准备好测试代码。
那说,最好的方法可能就是使用Handler。 Handler初始化为在主(UI)线程上运行,以便它可以修改UI。 Dimmer在UI线程上执行,从而避免了您遇到的问题。
...
public class OverlayService extends Service {
Handler handler;
...
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
...
manager.addView(oView, localLayoutParams);
handler.postDelayed(new Dimmer("#ff000000"), 500);
return START_STICKY;
}
private class Dimmer implements Runnable {
private String color;
public Dimmer (String color) {
this.color = color;
}
public void run() {
if(oView!=null){
oView.setBackgroundColor(Color.parseColor(color));
WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
wm.updateViewLayout(oView, oView.getLayoutParams());
}
}
}
@Override
public void onCreate() {
super.onCreate();
Log.v("Message", "OverlayService started");
handler = new Handler(Looper.getMainLooper());
}
...
}