0

我有一个应用程序通过服务创建系统警报窗口。Android系统警报窗口关闭并定期打开

MainActivity我实例化意图:

i = new Intent(getApplicationContext(), TintOverlayService.class); 
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP); 

在TintOverlayService,我创建了系统警报窗口,像这样:

LayoutInflater li = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE); 
windowManager = (WindowManager) getApplicationContext().getSystemService(Context.WINDOW_SERVICE); 

mTopView = (ViewGroup) li.inflate(R.layout.red_overlay, null); 

mTopView.setBackgroundColor(Color.parseColor(colorCode.replace("#", tintValue))); 

DisplayMetrics dm = getApplicationContext().getResources().getDisplayMetrics(); 
int densityDpi = dm.densityDpi; 

    int LayoutParamFlags = WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN 
      | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION 
      | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS; 

    WindowManager.LayoutParams params = new WindowManager.LayoutParams(
      WindowManager.LayoutParams.MATCH_PARENT, 
      densityDpi * 6, 
      WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY, 
      LayoutParamFlags, 
      PixelFormat.TRANSLUCENT); 

而且TintOverlayService的onStartCommand覆盖回报:

return START_STICKY; 

这成功创建了一个完整的覆盖t他筛选,到边缘。即使在应用程序之外,正如预期的那样。

但是,当您激活覆盖并杀死应用程序。覆盖层将闪烁一两秒钟,然后再次启动。或者,如果您只是通过浏览互联网或观看视频来使用手机,覆盖屏幕会在几秒到三十秒之间的任何地方关闭,然后重新开启。

任何想法指向正确的方向将是有益的。我一直试图弄清楚这一点现在。

回答

0

当你杀死应用程序时,服务也被终止。将START_STICKY设置为返回值时,系统会尽快尝试再次启动服务(当它具有足够的内存时)。 这会导致服务再次创建叠加层。 如果您想防止这种情况发生,应该足以将返回值更改为START_NOT_STICKY。

正在扼杀应用程序功能的应用程序的一部分,或者只是你压力测试它?

编辑 消失,再次出现的可能是系统停止服务的结果(认为它不再需要),并START_STICKY导致服务再次启动。 我通过每X分钟触发一次服务启动来绕过类似的问题。下面的代码是从内存中编写的,我现在无法测试它,所以它可能包含一些错误。

public class OverlayService extends Service{ 
Handler handler; 
Runnable runnable; 
boolean isKeepAliveActive = false; 


@Override 
public void onCreate(){ 

//DO YOUR STUFF 
initKeepAlive(); 
startKeepAlive(); 
} 

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

String action = intent.getAction() == null ? "empty": intent.getAction(); 
if (action.equals("KeepAlive")){ 
    //KEEP ALIVE TRIGGER, NOTHING TO DO 
    return START_NOT_STICKY; 
} 
else if (action.equals("WHATEVER")){ 
    //DO SOMETHING ELSE 
} 

//DO YOUR STUFF 

return START_NOT_STICKY; 
} 

@Override 
public void onDestroy(){ 
stopKeepAlive(); 
super.onDestroy(); 
} 

private void initKeepAlive(){ 
    handler = new Handler(); 
    runnable = new Runnable(){ 

     @Override 
     private void run(){ 
      try{ 
       isKeepAliveActive = true; 

       //Get context of your service and the class name of your service 
       Intent intent = new Intent(context, OverlayService.class); 
       intent.setAction("KeepAlive"); 
       context.startService(intent); 

       handler.postDelayed(runnable, 20*60*1000); 
      } catch (Exception e){ 
       isKeepAliveActive = false; 
      } 
     } 

private void startKeepAlive(){ 
    if (!isKeppAliveActive){ 
     runnable.run(); 
    } 

private void stopKeepAlive(){ 
    if (isKeepAliveActive){ 
     handler.removeCallbacks(runnable); 
     isKeepAliveActive = false; 
    } 
} 
} 
+0

杀死它只是压力测试它。我认为这是杀死应用程序的情况。最让我担心的是,当你正常使用手机时,叠加层会被杀死并重新启动。我不确定是否有办法补丁,或只是一个愚蠢的机器人的东西。 – cfisher

+0

你想要什么行为?如果覆盖图应该在应用程序死亡/崩溃时保持移除状态,则START_NOT_STICKY应解决此问题。 – chevalier

+0

我希望它留下来。问题是,它会关闭并定期重启。即使没有杀死应用程序。所以,你打开覆盖层并切换到其他应用程序或开始浏览互联网。最终,叠加层将打开和关闭。 – cfisher