どのような基準でオーバーレイの優先順位が上がる、つまり上になるのですか?呼び出し後に "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クリックイベントは、あなたがとにかく返信用マシュマロ..おかげで怒鳴ることはできませんでした..! :) –
申し訳ありません;あなたはオーバーレイのクリックイベントも欲しかったです。 – DanielSZ