어떤 기준으로 오버레이가 우선 순위가 높습니까? 호출 후 "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가 시작된 후 실행됩니다.
가 클릭 내가 장치에 마시 멜로와 SYSTEM_ALERT_WINDOW 위의 장치에 TYPE_TOAST을 사용했다 ..so 이벤트 마시 멜로 노호을 허용하지 않았다 마시멜로 위의 장치에 SYSTEM_ALERT_WINDOW를 사용하여 ... 당신에 대한 감사 어쨌든 답장을 .. !! :) –
죄송합니다, 당신도 오버레이에서 클릭 이벤트를보고 싶지 않습니다. – DanielSZ