私は他のアプリケーションの上にあるビューを作成しようとしています:
WindowManager.LayoutParams paramsDirectorView = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
私は他の回答を見て、「アプリケーションの描画」について次のことを見つけました。
まだ「-ウィンドウタイプ2038の許可が拒否されました」エラーが表示されます。現時点ではTYPE_PHONEを使用していますが、動作しますが、廃止され、TYPE_APPLICATION_OVERLAYを使用するように言われています。 TYPE_PHONEの答えは真の解決策ではなく、Android O.
私はAndroid 7.1.2で実行しています
Android.view.WindowManager $ BadTokenException:ウィンドウAndroid.view.ViewRootImpl$W@1f47e89を追加できません-Android.app.ActivityThread.handleServiceArgs(ActivityThread.Java:3344)でウィンドウタイプ2038の許可がAndroid.app.ActivityThreadで拒否されました.-wrap21(ActivityThread.Java)at Android.app.ActivityThread $ H.handleMessage(ActivityThread.Java:1583)at Android.os.Handler.dispatchMessage(Handler.Java:102)at Android.os.Looper.loop(Looper .Java:154)at Android.app.ActivityThread.main(ActivityThread.Java:6121)at Java.lang.reflect.Method.invoke(Native Method)at com.Android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit .Java:889)at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:779)原因:Android.view.WindowManager $ BadTokenException:ウィンドウAndroid.view.ViewRootImpl$W@1f47e89を追加できません- Android.view.WindowManagerGlobal.addView(WindowManagerGlobal.Java:342)のAndroid.view.ViewRootImpl.setView(ViewRootImpl.Java:703)でウィンドウタイプ2038のアクセス許可が拒否されましたAndroid.view.WindowManagerImpl.addView(WindowManagerImpl.Java:93)at HeadService.TwoViewManager。(TwoViewManager.Java:99)at HeadService.UIHeadService.onStartCommand(UIHeadService.Java:65)at Android.app.ActivityThread.handleServiceArgs(ActivityThread。 Java:3327)Android.app.ActivityThread.-wrap21(ActivityThread.Java)at Android.app.ActivityThread $ H.handleMessage(ActivityThread.Java:1583)at Android.os.Handler.dispatchMessage(Handler.Java:102) Android.os.Looper.loop(Looper.Java:154)at Android.app.ActivityThread.main(ActivityThread.Java:6121)at Java.lang.reflect.Method.invoke(Native Method)at com.Android.internal .os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.Java:889)at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:779)
私はまったく同じ問題を抱えていました。ターゲットを区別する必要があると思います(Oreoの前後)
int LAYOUT_FLAG;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
} else {
LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_PHONE;
}
params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
LAYOUT_FLAG,
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
<uses-permission Android:name="Android.permission.SYSTEM_ALERT_WINDOW" />
サービスクラス(マシュマロの前後)でまったく同じ問題がありました。
if (Build.VERSION.SDK_INT >= 23) {
if (!Settings.canDrawOverlays(this)) {
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, 1234);
}
} else {
startService(new Intent(SplashActivity.this,
CheckServicesForApps.class));
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 1234) {
startService(new Intent(SplashActivity.this,
CheckServicesForApps.class));
}
}
public class CheckServicesForApps extends Service {
private Context context = null;
@Override
public void onCreate() {
super.onCreate();
ImageView imageView = new ImageView(context);
imageView.setVisibility(View.GONE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
try {
windowManager = (WindowManager)getSystemService(WINDOW_SERVICE);
//here is all the science of params
final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager. LayoutParams.TYPE_SYSTEM_ERROR,
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON,
PixelFormat.TRANSLUCENT
);
windowManager.addView(imageView, params);
hand=new Handler();
} catch (Exception e) {
hand=new Handler();
e.printStackTrace();
}
}else{
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.TOP | Gravity.CENTER;
params.x = ((getApplicationContext().getResources().getDisplayMetrics().widthPixels) / 2);
params.y = ((getApplicationContext().getResources().getDisplayMetrics().heightPixels) / 2);
windowManager.addView(imageView, params);
}
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
/* We want this service to continue running until it is explicitly
* stopped, so return sticky.
*/
return START_STICKY;
}
@Override
public void onDestroy() {
super.onDestroy();
if (imageView != null) {
try {
windowManager.removeView(imageView);
} catch (Exception e) {
e.printStackTrace();
}
}
/**** added to fix the bug of view not attached to window manager ****/
}
}
次のインテントを呼び出して、実行時のアクセス許可をリクエストしましたか?
private void requestOverlayPermission() {
if (Android.os.Build.VERSION.SDK_INT < Android.os.Build.VERSION_CODES.M) {
return;
}
Intent myIntent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
myIntent.setData(Uri.parse("package:" + getPackageName()));
startActivityForResult(myIntent, APP_PERMISSIONS);
}
次に、onActivityResult()でSettings.canDrawOverlays(this)がtrueであるかどうかを確認します。そうでない場合は、上記のメソッドを呼び出して許可を再度要求します。
ソース SYSTEM_ALERT_WINDOW文字列SYSTEM_ALERT_WINDOW他のすべてのアプリの上に表示されるタイプTYPE_APPLICATION_OVERLAYを使用してウィンドウを作成することをアプリに許可します。この許可を使用するアプリはほとんどありません。これらのウィンドウは、ユーザーとのシステムレベルの対話を目的としています。
注:アプリがAPIレベル23以上をターゲットとする場合、アプリユーザーは、権限管理画面を通じてこの権限をアプリに明示的に付与する必要があります。アプリは、アクションACTION_MANAGE_OVERLAY_PERMISSIONでインテントを送信して、ユーザーの承認を要求します。アプリは、Settings.canDrawOverlays()を呼び出すことにより、この承認があるかどうかを確認できます。
変更してみてくださいWindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
からWindowManager.LayoutParams.TYPE_PHONE
?