Always show zoom controls in WebView - java

Is there any way to always show zoom controls in webview?
I found this: Always show zoom controls on a MapView
but that's for the mapview.
I want them to always be visible.
super.onCreate(savedInstanceState);
super.loadUrl("file:///android_asset/www/index.html");
WebSettings ws = super.appView.getSettings();
ws.setSupportZoom(true);
ws.setBuiltInZoomControls(true);

setDisplayZoomControls() is only available from API 11 (Android 3). So you can't even consider using it until the vast majority of Android devices are 3 or above - which will not be for some years :(

Not sure if this will work as I never tried, but I checked the reference in developer.android.com
ws.setDisplayZoomControls(true);
If this worked dont forget to best answer this answer.
Also check this out:
http://www.tutorialforandroid.com/2009/02/webview-with-zoomcontrols-in-android.html
good tutorial. (Debunks my theory)

None of the above worked for my. Only when I start draging the webview content the controls show up the first time. So what I did as a "quick fix" is in onStart() of my Fragment that holds the Dialog with the webview I call:
webview.invokeZoomPicker();
Example:
#Override
public void onStart(){
super.onStart();
DialogFragment dialog = this;
//...stuff
if(dialog.getDialog()!= null && dialog.getDialog().getWindow()!=null){
//...more stuff
View v = dialog.getView();
if(v!=null){
//invoke controls on start once, they stay active a few seconds:
WebView webview =v.findViewById(R.id.frag_dlg_WebView);
webview.invokeZoomPicker();
}
}
}
The controls light up only for a few seconds until they disappear again, by then the user in my case should have dragged the webview already.

Related

Android O device blank screen after addView / setContentview

I recently decided to update my older apps and bring them a little more up to date. In doing so I noticed an odd problem when running them on my new handset (Android O / API Level 29).
My App is essentially a single Activity using OpenGL. This is basically what happens when the app is first loaded...
Create Layout, Create a Splashscreen View, create custom GLSurfaceView
Add GLSurfaceView to Layout
Add Splashscreen to Layout
Start AsyncTask to load resources and do setup ops
GLSurfaceView dismisses Splashscreen to reveal renderer...
So, it all works perfectly well on my older devices (3 x handsets, 1 x tablet all running various versions of Android no higher than Lollipop).
However, on my Android 10 handset, all I get is a blank screen while the app starts. Just to be clear, there are no errors, the app itself works perfectly fine. After the usual startup time, the blank screen is dismissed and the app continues, it's just that the 'splashscreen' has now become a "blankscreen".
But Android Studio Layout Inspector tells a different story
Indeed, if I open the Layout Inspector in Android Studio, oddly it shows exactly what I would expect... the splashscreen with its text/graphics, but not on the actual device...
Some test code
In the following test code I replaced the resource loading / setup with a simple Thread.sleep just to create a longer delay so I could more easily inspect the output in Android Studio. This does still exhibit the problem...
#Override
protected void onCreate(Bundle savedInstanceState) {
int[] deviceResolution = getDeviceResolution();
width = deviceResolution[0];
height = deviceResolution[1];
layout = new RelativeLayout(this);
splash = new Splash(getApplication(), width, height);
myGLView = new CustomGLSurfaceView(this.getApplication());
layout.addView(myGLView);
layout.addView(splash);
setContentView(layout);
loadResource = new LoadResources(newBundle);
loadResources.execute();
super.onCreate(savedInstanceState);
}
class LoadResources AsyncTask<Void, Void, Void> {
Bundle savedBundle;
LoadResources(Bundle savedBundle){
this.savedBundle=savedBundle;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... params) {
// Simulate some long-running task here. While this is happening, splashscreen should be visible. And on older devices, it is. Not on Android O handset (but OK in Android Studio Layout Inspector).
try {
Thread.sleep(30000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// Would typically make my calls here to load resources, and complete other setup tasks here
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
}
}
** Other observations **
I know that Async is now deprecated and I'm also aware of other Splashscreen tecnhiques such as using a dedicated Activity. However due to the setup/complexity of the apps and given that it doesn't 'break' them per-se, I don't want to have to refactor the entire codebase (just yet anyway) any new apps going forward will use a different system for the splashscreen. What I'm really trying to understand here is why this now doesn't work as it used to. Is this a bug? Or a behavioural change that happened in an Android version somewhere down the line? Or maybe it's just me doing something wrong. If anyone has come across it, I'd be really interested to know of a fix/workaround.
** Other things I've tried **
In the above example, if I simply don't add 'myGLView' then the splashscreen shows, but of course the app then won't work. So I though about adding it in onPostExecute and then bringing the splashscreen view back to the front with splash.bringToFront(). This kind of works, but is messy. The splashscreen only shows for a brief second, and on devices that show it correctly there is a 'glitch' as the correctly displayed splashscreen is overlayed with the GL Renderer and then bought back to the front.
You are adding a view to an object which is not currently set in an Activity.
The better approach would be calling setContentView() first as well as the super method, then adding the multiple views in it.
So in your case, it'll be like:
super.onCreate(savedInstanceState);
setContentView(layout);
layout = new RelativeLayout(this);
int[] deviceResolution = getDeviceResolution();
width = deviceResolution[0];
height = deviceResolution[1];
layout = new RelativeLayout(this);
splash = new Splash(getApplication(), width, height);
myGLView = new CustomGLSurfaceView(this.getApplication());
layout.addView(myGLView);
layout.addView(splash);
loadResource = new LoadResources(newBundle);
loadResources.execute();

Prevent Android from showing sensible information on multi tasking view

I need to hide the content of my application when it goes to the background so sensitive information are not showing up on the android multitasking view.
It's been suggested to use the following line to hide the screen
getWindow().setFlags(LayoutParams.FLAG_SECURE, LayoutParams.FLAG_SECURE);
It works fine.
However, this prevents the user from taking screenshot as well which is not an expected behavior for me. I want to let the user take screenshot of the app if they need to. What I don't want is Android to display the latest screen on the multitasking view.
Would it be possible to set the FLAG_SECURE only when the app goes in the background?
We've ended up with this solution which worked the best for us:
#Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (!hasFocus) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);
} else {
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_SECURE);
}
}
You can use Activity Lifecycle Callbacks. Just call setVisiblity(View.INVISIBLE) on the views that you want to hide in the onPause() Callback and setVisiblity(View.VISIBLE) in onResume() Callback.

ProgressDialog spinner doesn't appear while the dialog do (no spinner at all)

I am new to android development and stuff. Working on an existing android application and tried to use progressDialogue the spinner one.
I have declared the progressdialog kinda globally. showing and dismissing them in separate methods both of which run on ui thread.
private void progressShow()
{
runOnUiThread(new Runnable() {
#Override
public void run() {
//progress_layout.setVisibility(View.VISIBLE);
progressDialog = new ProgressDialog(LoginActivity.this,R.style.Theme_IAPTheme);
progressDialog.setIndeterminate(true);
progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
progressDialog.setMessage("Authenticating...");
progressDialog.show();
login_button.setEnabled(false);
register_button.setEnabled(false);
user_name_edit_text.setEnabled(false);
}
});
}
The code above is working fine but the style of the progressdialog is very dumb. When I don't mention R.style.Theme_IAPTheme the style is a good one but there is no spinner there.
How would I get some other style?(I am learning from this link:http://sourcey.com/beautiful-android-login-and-signup-screens-with-material-design/). This guy used R.style.AppTheme_Dark_Dialog which becomes red for me when I use it. :DDDD
One of the great things about android is availability of so many open source libraries. If you're not satisfied by the style of progress dialog you can use a custom one. Refer to this URL, a list of few fancy progress dialogs you might like.
Are transitions turned off in developer options on the device.
This can cause certain animations from the system to not display. Unfortunately, that includes the progress dialog spinner.

SearchView and Activity Title in ActionBar

Very simple question that doesn't need much code:
I'm using Android's default ActionBar (no Sherlock) in which I have a couple of MenuItems. One of them is a collapsible Action View (android:showAsAction="collapseActionView|always") for your typical search scenario: user clicks on the icon → a search box expands → when the user types anything onQueryTextChange does its magic).
SearchView sv = new SearchView(this);
sv.setLayoutParams(new ActionBar.LayoutParams(Gravity.RIGHT));
// Yada, yada...
sv.setOnQueryTextListener(new OnQueryTextListener() {
// The methods for onQueryTextSubmit and onQueryTextChange ... they apply filtering on the activity's list adapter and apparently work fine
}
menuItem.setActionView(sv); // menuItem is the item for the search action
searchAnswers.setOnActionExpandListener(new OnActionExpandListener() {
// The listener's methods for expand/collapse as I need some business logic behind them
}
All of the above works fine.
When the device is on portrait mode and has limited screen space, the SearchView occupies pretty much the whole action bar, hiding the other MenuItems (which have android:showAsAction="ifRoom") as well as the Activity's title, which is OK by me.
The problem is that if the device is on landscape mode (so that there's still free ActionBar space), the SearchView doesn't occupy the whole ActionBar (again, fine by me) but the Activity's title disappears (even though there's plenty of space where it could be displayed!). So my problem is that I get this empty space where the Activity's title could be shown.
Before expanding:
After expanding:
(Both screenshots are from a phone in landscape mode. Tested with Android 4.0.4 and 4.3.)
Any tips on how to keep the Activity's title when there's enough space?
Not sure if you found an answer to this problem yet. But I found an answer on this thread that may help - it certainly helped me.
ActionBar SearchView not fully expanding in landscape mode
Code copied from link:
searchView.setOnSearchClickListener(new OnClickListener() {
private boolean extended = false;
#Override
public void onClick(View v) {
if (!extended) {
extended = true;
LayoutParams lp = v.getLayoutParams();
lp.width = LayoutParams.MATCH_PARENT;
}
}
});
searchView.setMaxWidth(Integer.MAX_VALUE);
Building on CoolMind answer, it worked for me to set max width to a smaller value:
searchView.setMaxWidth(375);
setMaxWidth() interprets its parameter as pixels.

Disabling Android Button depending on Permissions

I have an android app that uses the permission "CALL_PHONE". This simple app would just contain a button that would use the call intent to call a specific number. I would like to install this app on both tablets and phone but when it is installed on the tablet, I would like the button to be disabled during runtime so errors wouldn't show when the user tries to call using the tablet without a call function.
At the moment, I am using the setEnabled() and setClickable() method in my MainActivity.java and setting it to false when the user clicks on the button the first time. My question is whether the button can be disabled and the text changed during runtime or when the app is first opened (in a tablet) so the user wouldn't have to click the button first for it to show that the "call" button should be disabled and unclickable?
Refer to this
That will help you in identifying that your application is running on tablet. Now as for disabling your button, I would suggest something like this:
onCreate()
{
setContentView(R.layout.main);
boolean isTablet = checkDevice();
callBtn = (Button) findViewById(R.id.call);
if (isTablet)
{
callBtn.setEnabled(false);
callBtn.setText("Not allowed to make a call");
}
callBtn.setOnClickListener( new onClickListener(){
//Make a call
});
}
public boolean isTablet()
{
//Code for identifying. Return true if application is running on tablet
//return false otherwise
}
So you won't have to wait for user's click on Call button to disable it in tablet.
Hope that helps.
Use button.setEnabled(false); to make visible but user cant click and
button.setVisibility(View.GONE); to make button invisible.and button.setText("YOUR_NEW_TEXT"); to change the button text runtime
And this is not depend on the size of the screen.
Is this you wanted?? OR be more specific with your queston.
... the text changed during runtime?
You can use the setText(); method.
About the other part of your question, you need first to define "What is a tablet?". Is it a 7", 8", 10" screen? Is it a mdpi, hdpi, xhdpi screen? Is it a device which is able to do phone calls? What is a tablet for you or your project? Depending on your answer, you can filter your code (or xml in folders) to make them work the way you want.

Categories

Resources