2017-12-30 37 views
0

어떤 기준으로 오버레이가 우선 순위가 높습니까? 호출 후 "WindowManager.LayoutParams"를 사용하여 내 응용 프로그램 오버레이를 실행하면 두 오버레이가 실행되지만 실제 호출자 응용 프로그램의 오버레이는 항상 위에 표시됩니다. 내 의도는 오버레이로 전체 화면을 덮어 사용자가 전화하는 번호를 알 수 없도록 제한하는 것입니다. 모든 것이 잘 작동하고 통화를 종료 한 후 통화 로그를 삭제해도 문제가 없습니다. 하지만 진정한 호출자 오버레이는 큰 문제를 만들고 있습니다. 진정한 호출자 앱 오버레이가 실행되기 시작한 후에도 내 오버레이를 시작하려고했지만 내 오버레이는 그 오버레이 뒤에서 실행되기 시작했습니다. 누구든지 제발 도와 줄 수 있어요. 나는 많이 엉망이되었다. 오버레이에서 오버레이를 만드는 이유전화가 걸려 올 때 내 애플리케이션의 오버레이에서 실제로 발신자 오버레이가 실행되는 이유는 무엇입니까?

P.S. 확인 목적으로 오버레이의 너비는 400입니다.

내 코드 :

MainActivity.java

 call.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 

      askForPermission(Manifest.permission.CALL_PHONE, PERMISSION_ALL); 

      Intent callIntent = new Intent(Intent.ACTION_CALL); 
      callIntent.setData(Uri.parse("tel:" + number)); 
      if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) { 
       // TODO: Consider calling 
       // ActivityCompat#requestPermissions 
       // here to request the missing permissions, and then overriding 
       // public void onRequestPermissionsResult(int requestCode, String[] permissions, 
       //           int[] grantResults) 
       // to handle the case where the user grants the permission. See the documentation 
       // for ActivityCompat#requestPermissions for more details. 
       Log.e("apkflow","no call permission"); 
       return; 
      } 

      startActivity(callIntent); 

      try { 
       sleep(800); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 


      finish(); 
      intent = new Intent(MainActivity.this, OverlayShowingService.class); 
      intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
      startActivity(intent); 
      overridePendingTransition(0, 0); 

      } 
     }); 

OverlayShowingService.class :

ImageButton end; 
WindowManager wm; 
View view = null; 

private Handler customHandler = new Handler(); 
private long startTime = 0L; 
long timeInMilliseconds = 0L; 
private TextView timerValue; 

static final Integer PERMISSION_ALL = 1; 
String number = "9860450235"; 
String queryString = "NUMBER="+number; 
Intent intent; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE); 

    LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    view = inflater.inflate(R.layout.activity_call_content, null); 

    Log.e("apkflow", "overlay call_content"); 

    timerValue = (TextView) view.findViewById(R.id.timerValue); 
    startTime = SystemClock.uptimeMillis(); 
    customHandler.postDelayed(updateTimerThread, 0); 

    if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 
     Log.e("apkflow", "Marshmello and above"); 
     WindowManager.LayoutParams params = new WindowManager.LayoutParams(400, WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.TYPE_TOAST, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN, PixelFormat.OPAQUE); 
     params.gravity = Gravity.LEFT | Gravity.TOP; 
     params.x = 0; 
     params.y = 0; 
     wm.addView(view, params); 
    } else { 
     Log.e("apkflow", "below Marshmello"); 
     WindowManager.LayoutParams params = new WindowManager.LayoutParams(400, WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.TYPE_SYSTEM_ALERT, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN, PixelFormat.TRANSLUCENT); 
     params.gravity = Gravity.LEFT | Gravity.TOP; 
     params.x = 0; 
     params.y = 0; 
     wm.addView(view, params); 
    } 

    end = (ImageButton) view.findViewById(R.id.endcall); 
    end.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      Log.e("apkflow", "endcall clicked"); 

      Toast.makeText(getApplicationContext(), "Call is ended", Toast.LENGTH_SHORT).show(); 
      try { 
       String serviceManagerName = "android.os.ServiceManager"; 
       String serviceManagerNativeName = "android.os.ServiceManagerNative"; 
       String telephonyName = "com.android.internal.telephony.ITelephony"; 
       Class<?> telephonyClass; 
       Class<?> telephonyStubClass; 
       Class<?> serviceManagerClass; 
       Class<?> serviceManagerNativeClass; 
       Method telephonyEndCall; 
       Object telephonyObject; 
       Object serviceManagerObject; 
       telephonyClass = Class.forName(telephonyName); 
       telephonyStubClass = telephonyClass.getClasses()[0]; 
       serviceManagerClass = Class.forName(serviceManagerName); 
       serviceManagerNativeClass = Class.forName(serviceManagerNativeName); 
       Method getService = serviceManagerClass.getMethod("getService", String.class); 
       Method tempInterfaceMethod = serviceManagerNativeClass.getMethod("asInterface", IBinder.class); 
       Binder tmpBinder = new Binder(); 
       tmpBinder.attachInterface(null, "fake"); 
       serviceManagerObject = tempInterfaceMethod.invoke(null, tmpBinder); 
       IBinder retbinder = (IBinder) getService.invoke(serviceManagerObject, "phone"); 
       Method serviceMethod = telephonyStubClass.getMethod("asInterface", IBinder.class); 
       telephonyObject = serviceMethod.invoke(null, retbinder); 
       telephonyEndCall = telephonyClass.getMethod("endCall"); 
       telephonyEndCall.invoke(telephonyObject); 

       sleep(1000); 
       askForPermission(Manifest.permission.WRITE_CALL_LOG, PERMISSION_ALL); 

       ((WindowManager) getSystemService(WINDOW_SERVICE)).removeView(view); 
       view = null; 

      } catch (Exception e) { 
       e.printStackTrace(); 
       Log.e("apkflow", 
         "FATAL ERROR: could not connect to telephony subsystem"); 
       Log.e("apkflow", "Exception object: " + e); 
      } 

     } 
    }); 

} 


private Runnable updateTimerThread = new Runnable() { 

    public void run() { 

     timeInMilliseconds = SystemClock.uptimeMillis() - startTime; 

     int secs = (int) (timeInMilliseconds/1000); 
     int mins = secs/60; 
     int hrs = mins/60; 
     secs = secs % 60; 
     timerValue.setText("" + hrs + ":" 
       + String.format("%02d", mins) + ":" 
       + String.format("%02d", secs)); 
     customHandler.postDelayed(this, 0); 
    } 

}; 

private void askForPermission(String permission, Integer requestCode) { 
    Log.e("apkflow", "askforpermission activated..1"); 

    if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && ContextCompat.checkSelfPermission(OverlayShowingService.this, permission) != PackageManager.PERMISSION_GRANTED) { 
     Log.e("apkflow", "askforpermission activated..2"); 

     // Should we show an explanation? 
     if (ActivityCompat.shouldShowRequestPermissionRationale(OverlayShowingService.this, permission)) { 
      Log.e("apkflow", "askforpermission activated..3"); 

      //This is called if user has denied the permission before 
      //In this case I am just asking the permission again 
      ActivityCompat.requestPermissions(OverlayShowingService.this, new String[]{permission}, requestCode); 

     } else { 
      Log.e("apkflow", "askforpermission activated..4"); 

      ActivityCompat.requestPermissions(OverlayShowingService.this, new String[]{permission}, requestCode); 
     } 
    } else { 
     Log.e("apkflow", "askforpermission activated..5"); 
     Toast.makeText(this, "" + permission + " is already granted.", Toast.LENGTH_SHORT).show(); 

     this.getContentResolver().delete(CallLog.Calls.CONTENT_URI, queryString, null); 
     returnhome(); 
    } 
} 

@Override 
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { 
    super.onRequestPermissionsResult(requestCode, permissions, grantResults); 
    Log.e("apkflow", "onRequestpermission activated..1"); 

    if (ActivityCompat.checkSelfPermission(this, permissions[0]) == PackageManager.PERMISSION_GRANTED) { 
     Log.e("apkflow", "onRequestpermission activated..2"); 

     this.getContentResolver().delete(CallLog.Calls.CONTENT_URI, queryString, null); 
     returnhome(); 

     Toast.makeText(this, "Permission granted", Toast.LENGTH_SHORT).show(); 
    } else { 
     Log.e("apkflow", "onRequestpermission activated..3"); 

     Toast.makeText(this, "Permission denied", Toast.LENGTH_SHORT).show(); 
    } 

} 

public void returnhome(){ 
    intent = new Intent(OverlayShowingService.this, MainActivity.class); 
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
    startActivity(intent); 
} 

P.S. 통화 버튼을 클릭하면 나는 또한 동일한 오버레이가 포함 된 800ms에 대한 서비스를 시작했습니다. 이것은 전화 프로세스가 시작되는 동안 다이얼러 응용 프로그램의 수를 숨기고 최대 800ms가 소요됩니다. OverlayShowingService가 시작된 후 실행됩니다.

답변

0

죄송합니다. 위의 의견 (게시 지점이 충분하지 않습니다 :)에 대한 의견보다는 게시해야했습니다.

SYSTEM_ALERT_WINDOW로 만들려고 했습니까? 여기처럼 : How to create always-top fullscreen overlay activity in Android

+1

가 클릭 내가 장치에 마시 멜로와 SYSTEM_ALERT_WINDOW 위의 장치에 TYPE_TOAST을 사용했다 ..so 이벤트 마시 멜로 노호을 허용하지 않았다 마시멜로 위의 장치에 SYSTEM_ALERT_WINDOW를 사용하여 ... 당신에 대한 감사 어쨌든 답장을 .. !! :) –

+0

죄송합니다, 당신도 오버레이에서 클릭 이벤트를보고 싶지 않습니다. – DanielSZ