Почему во время исходящих вызовов поверх оверлея моего приложения работает оверлей истинных абонентов?
На каком основании оверлеи получают более высокий приоритет, т.е. быть на вершине? Когда мое наложение приложения, использующее "WindowManager.LayoutParams ", выполняется после выполнения вызова, оба наложения выполняются, но наложения приложения истинного вызывающего всегда находятся сверху. Мое намерение состоит в том, чтобы покрыть весь экран моим оверлеем, чтобы пользователь мог знать номер, по которому он звонит. Все работает нормально, удаление журнала вызовов после завершения вызова в порядке. Но настоящее наложение вызывающего абонента создает большую проблему. Я тоже попытался запустить свое наложение после того, как начал работать наложение настоящих приложений вызывающего абонента. Но мое наложение начало работать за этим наложением. Может кто-нибудь помочь мне с этим, пожалуйста. Я много колебался. Что делает это наложение поверх моего наложения
PS ширина наложения составляет 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);
}
PS, когда нажата кнопка вызова, я также запустил службу на 800 мс, которая тоже содержит тот же оверлей. Он запускает, чтобы скрыть номер приложения для набора номера, пока начинается процесс вызова, который занимает максимум 800 мс. После этого запускается OverlayShowingService.