WebView scrolling doesn't work in WindowManager - java

Code snippet:
WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_FULLSCREEN,
PixelFormat.TRANSLUCENT);
windowManager.addView(webView, params);
It works fine: browser displays, links clicking works, but web page scrolling doesn't work.
What could be the reason?
Thanks.

Following Zoom Control properties should work.
WebSettings l_webviewSetting = webview.getSettings();
l_webviewSetting.setAllowFileAccess(true);
l_webviewSetting.setAppCacheEnabled(true);
l_webviewSetting.setBlockNetworkImage(false);
l_webviewSetting.setBlockNetworkLoads(false);
l_webviewSetting.setBuiltInZoomControls(true);
l_webviewSetting.setLoadsImagesAutomatically(true);
l_webviewSetting.setJavaScriptCanOpenWindowsAutomatically(true);
l_webviewSetting.setJavaScriptEnabled(true);
l_webviewSetting.setUseWideViewPort(true);
l_webviewSetting.setLoadWithOverviewMode(true);
l_webviewSetting.setDomStorageEnabled(true);
l_webviewSetting.getBuiltInZoomControls();

Related

Activity not attached to windows manager

I have a floating widget (that draws over all the apps) that on long click (mouse hold) will show a relative layout (remove_relativelayout) from the bottom so that the user can close the widget and the service will be destroyed.
On most Samsung phones I get this crash:
Fatal Exception: java.lang.IllegalArgumentException: View=android.widget.RelativeLayout{762db5 G.E...... ......ID 0,0-160,160 #7f09022d app:id/remove_relativelayout} not attached to window manager
at android.view.WindowManagerGlobal.findViewLocked(WindowManagerGlobal.java:569)
at android.view.WindowManagerGlobal.updateViewLayout(WindowManagerGlobal.java:463)
at android.view.WindowManagerImpl.updateViewLayout(WindowManagerImpl.java:101)
at com.xxxx.dev.floatingwidget.services.FloatingWidgetServices.lambda$widgetLongClick$0(FloatingWidgetServices.java:20)
at com.xxxxx.dev.floatingwidget.services.FloatingWidgetServices.lambda$widgetLongClick$0$FloatingWidgetServices(FloatingWidgetServices.java)
at com.xxxxxx.dev.floatingwidget.services.-$$Lambda$FloatingWidgetServices$DhV3rKQxnQ9oEEnb70PNAJKR8NQ.onAnimationUpdate(-.java:4)
at android.animation.ValueAnimator.animateValue(ValueAnimator.java:1558)
at android.animation.ValueAnimator.animateBasedOnTime(ValueAnimator.java:1349)
at android.animation.ValueAnimator.doAnimationFrame(ValueAnimator.java:1481)
at android.animation.AnimationHandler.doAnimationFrame(AnimationHandler.java:146)
at android.animation.AnimationHandler.access$100(AnimationHandler.java:37)
at android.animation.AnimationHandler$1.doFrame(AnimationHandler.java:54)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:994)
at android.view.Choreographer.doCallbacks(Choreographer.java:794)
at android.view.Choreographer.doFrame(Choreographer.java:725)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:981)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:237)
at android.app.ActivityThread.main(ActivityThread.java:7857)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1068)
Here is on start:
WindowManager.LayoutParams paramRemove = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
windowType,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH |
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
PixelFormat.TRANSLUCENT);
paramRemove.gravity = Gravity.TOP | Gravity.LEFT;
removeView.setVisibility(View.GONE);
removeImg = removeView.findViewById(R.id.remove_img);
windowManager.addView(removeView, paramRemove);
I think its coming from this function but I'm not sure:
private void widgetLongClick() {
GlobalFunctions.printLn(">>>>>>>>>>>>Into FloatingWidgetService.chathead_longclick() ");
WindowManager.LayoutParams param_remove = (WindowManager.LayoutParams) removeView.getLayoutParams();
int x_cord_remove = (szWindow.x - removeView.getWidth()) / 2;
int y_cord_remove = szWindow.y - (removeView.getHeight() + getStatusBarHeight());
param_remove.x = x_cord_remove;
param_remove.y = y_cord_remove;
ValueAnimator va = ValueAnimator.ofFloat(szWindow.y, y_cord_remove);
int mDuration = 100;
if(removeView.isAttachedToWindow()){
if(param_remove != null){
if(windowManager !=null){
va.setDuration(mDuration);
va.addUpdateListener(animation -> {
param_remove.y = Math.round((Float) animation.getAnimatedValue());
windowManager.updateViewLayout(removeView, param_remove);
});
va.start();
}
}
}
}
I would recommend you add this removable layout into your XML file and have it be View.GONE until you require it, this way you don't have to be worried about adding it programmatically and settings the correct layout parameters (this is probably what's failing in your current code).
Once you receive the longClick on the other View, you can toggle the removable layout to be View.VISIBLE and perhaps even add combine that with a quick animation to make it seem more 'friendly' to the user.
I find the solution for my problem,
the problem was that I'm closing the activity before the view is loaded,
so what I did is to wait for 1 sec before closing the activity,
using simply:
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
//close the activity after 1 sec
}
},1000);

How to open new video in locked screen

I have a video watch app. I want to watch video in locked screen, and it is working. but some Api version i can watch but can't change video, can't open in rotated screen in some Api version. My code is belove
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
setShowWhenLocked(true);
setTurnScreenOn(true);
KeyguardManager keyguardManager = (KeyguardManager)getSystemService(Context.KEYGUARD_SERVICE);
keyguardManager.requestDismissKeyguard(this, null);
}
WindowManager wm= (WindowManager) getSystemService(WINDOW_SERVICE);
Display dp= wm.getDefaultDisplay();
if (dp.getHeight()<dp.getWidth())
{
if (Build.VERSION.SDK_INT < 16) {
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
else {
View decorView = getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN;
decorView.setSystemUiVisibility(uiOptions);
}
setContentView(R.layout.activity_watch_landscape);
}
else {
setContentView(R.layout.activity_watch);}
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON|
WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD|
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED|
WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
}
When ı delete this code line, problem solved
KeyguardManager keyguardManager = (KeyguardManager)getSystemService(Context.KEYGUARD_SERVICE);
keyguardManager.requestDismissKeyguard(this, null);

How to show dialog in service on android

In my application I want to use service and in this service I should show layout.
I want when click on button show dialog, I write below codes!
But after click on button, show this dialog back of layout and not show any dialog!
My service codes :
public class FloatingLayoutService extends Service implements StepperFormListener {
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
//Inflate the layout using LayoutInflater
layoutInflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
floatingLayout = (ConstraintLayout) layoutInflater.inflate(R.layout.service_floating_layout, null);
floatingLay_root = floatingLayout.findViewById(R.id.floatingLay_root);
floatingLay_main = floatingLayout.findViewById(R.id.floatingLay_main);
floatingLay_emptyImg = floatingLayout.findViewById(R.id.floatingLay_emptyImg);
...
//Set layout params to display the controls over any screen.
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;
}
final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT,
LAYOUT_FLAG,
0,
PixelFormat.TRANSLUCENT);
// From API26, TYPE_PHONE deprecated. Use TYPE_APPLICATION_OVERLAY for O
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O)
params.type = WindowManager.LayoutParams.TYPE_PHONE;
//Initial position of the floating controls
params.gravity = Gravity.BOTTOM | Gravity.START;
params.x = 0;
params.y = 0;
//Add the controls view to windowManager
windowManager.addView(floatingLayout, params);
//Task page btn
floatingLay_infoContentNextPage.setOnClickListener(v -> {
AlertDialog alertDialog = new AlertDialog.Builder(this)
.setTitle("Title")
.setMessage("Are you sure?")
.create();
alertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
alertDialog.show();
});
return START_STICKY;
}
How can I show dialog, front of layout ?
You can make an activity without a layout just to show the Alert dialog.
public class MyAlertDialog extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
new AlertDialog.Builder(this)
.setTitle("Title")
.setMessage("Message")
...
...
.show()
}
}
Remember to finish the activity.
You can set the title and message dynamically by passing them through intent.
Service
Intent intent = new Intent(this, MyAlertDialog.class);
intent.putExtra("titleKey", "title");
intent.putExtra("messageKey", "messge");
startActivity(intent);
And inside the activity, read it as:
getIntent().getStringExtra("titleKey")
getIntent().getStringExtra("messageKey")

How to draw an overlay from a service

My app is supposed to draw an overlay (blue light filter) at a certain time. Now I have a method called
private void drawOverlay()
Which under normal circumstances works perfectly fine. However, I want to use this method from a service, that runs in the background and is already running, so that I can draw the overlay at a certain time. In some cases this works, but sometimes I get a the following error.:-
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
I understand this has something to do with the UI thread, and I am supposed to use a Looper and a handler and I have read the documentation, but I cannot fully work out how I am supposed to do this.
Can someone please clarify this.
private void drawOverlay() {
log("drawing overlay");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
log("overlay >m checking permission");
wm = (WindowManager) getSystemService(WINDOW_SERVICE);
if (permissionGranted) {
log("permission granted");
LayoutInflater inflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.screen_dimmer, null);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_FULLSCREEN
| WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
| WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
| WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION,
PixelFormat.TRANSLUCENT);
wm = (WindowManager) getSystemService(WINDOW_SERVICE);
wm.addView(view, params);
overlayDrawn = true;
} else {
log("no permission");
}
} else {
log("overlay drawing no permission needed (<m)");
wm = (WindowManager) getSystemService(WINDOW_SERVICE);
if (permissionGranted) {
LayoutInflater inflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.screen_dimmer, null);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_FULLSCREEN
| WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
| WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
| WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION,
PixelFormat.TRANSLUCENT);
wm = (WindowManager) getSystemService(WINDOW_SERVICE);
wm.addView(view, params);
}
}
}
Before the service is started the app checks if it has permission to draw an overlay, that is where the permissionGranted boolean comes from, this is only needed if the SDK version is higher than M.

Show AdMob ad on surface view

I just started writing my first Android game and now I also want to try out AdMob. But I cant get it to show ads...
I followed this tutorial to create the game: http://www.kilobolt.com/day-7-creating-an-android-game-from-start-to-finish.html
It uses a canvas to draw everything.
This is the important code I guess:
public abstract class AndroidGame extends Activity implements Game {
AndroidFastRenderView renderView;
Graphics graphics;
Audio audio;
Input input;
FileIO fileIO;
Screen screen;
WakeLock wakeLock;
AdView adView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
boolean isPortrait = getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT;
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int frameBufferWidth = metrics.widthPixels;
int frameBufferHeight = metrics.heightPixels;
Bitmap frameBuffer = Bitmap.createBitmap(frameBufferWidth,
frameBufferHeight, Config.RGB_565);
float scaleX = (float) frameBufferWidth
/ getWindowManager().getDefaultDisplay().getWidth();
float scaleY = (float) frameBufferHeight
/ getWindowManager().getDefaultDisplay().getHeight();
renderView = new AndroidFastRenderView(this, frameBuffer);
graphics = new AndroidGraphics(getAssets(), frameBuffer);
fileIO = new AndroidFileIO(this);
audio = new AndroidAudio(this);
input = new AndroidInput(this, renderView, scaleX, scaleY);
screen = getInitScreen();
//setContentView(renderView);
PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
wakeLock = powerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK, "MyGame");
RelativeLayout layout = new RelativeLayout(this);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.MATCH_PARENT,
RelativeLayout.LayoutParams.MATCH_PARENT);
layout.setLayoutParams(params);
adView = createAdView();
layout.addView(adView);
View gameView =renderView;
layout.addView(gameView);
setContentView(layout);
startAdvertising(adView);
}
private AdView createAdView() {
adView = new AdView(this);
adView.setAdSize(AdSize.BANNER);
adView.setAdUnitId("ca-app-pub-number/number");
adView.setId(12345);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE);
params.addRule(RelativeLayout.CENTER_HORIZONTAL, RelativeLayout.TRUE);
adView.setLayoutParams(params);
adView.setBackgroundColor(Color.BLACK);
return adView;
}
private void startAdvertising(AdView adView) {
AdRequest adRequest = new AdRequest.Builder().build();
adView.loadAd(adRequest);
}
What am I doing wrong?
Update:
Use "Ads" as a filter in logcat.
You need to use a test device like this:
private void startAdvertising(AdView adView) {
AdRequest adRequest = new AdRequest.Builder()
.addTestDevice("your ID")
.build();
adView.loadAd(adRequest);
}
Further more I changed the adUnitId to the one given here: https://developers.google.com/admob/android/quick-start
And then I changed the order in which the Views get added (it seemed like the gameView was overlaying the adView):
View gameView =renderView;
layout.addView(gameView);
adView = createAdView();
layout.addView(adView);
With these changes it worked.

Categories

Resources