I would like to open app with splashscreen activity and download homepage of my website. When download complete I'd like to start MainActivity, pass webssite to webview and display it.
I tried some different methods but nothing works..
My current version load webview when MainActivity starts and that not looks good when website is loading.
Do you have any ideas?
public class SplashScreen extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash_screen_layout);
try {
url = new URL(link);
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
new WczytywaczUrl().execute(url);
}
//asynctask class and methods
#Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
Log.d(TAG, result.toString());
Intent intent = new Intent(SplashScreen.this, MainActivity.class);
intent.putExtra("strona", result);
startActivity(intent);
finish();
}
public class MainActivity extends Activity implements OnClickListener{
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG, "metoda onCreate");
setContentView(R.layout.activity_main);
webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setLoadWithOverviewMode(true);
webSettings.setUseWideViewPort(true);
Intent i = getIntent();
String strona = i.getStringExtra("strona");
Log.d(TAG, "strona: " + strona.toString());
webView.loadDataWithBaseURL(link, strona, "text/html", "UTF-8", null);
}
}
What about replacing "Activity" with just another layout?
<FrameLayout>
android:layout_width="match_parent"
android:layout_height="match_parent">
<Layout1
android:layout_width="match_parent"
android:layout_height="match_parent">
// Layout contents that origin from your splash activity layout
</Layout1>
<Layout2
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="invisible">
// Layout contents that origin from your main activity layout
</Layout2>
</FrameLayout>
WebViewClient has "public void onPageFinished(WebView view, String url)" callback.
If you implement code that change visibility of Layout1 and Layout2 in that callback,
then the webview may be shown after it finished loading.
Related
I'm searching for a while how to run my WebView forever. When the android function onPause() / onResume() is called. My WebView starts again.
I want the WebView to go on. Maybe the best to explane by an simple HTML example:
<html><head><title>Webview test Android</title></head>
<body>
<h1><div id="counter"></div></h1>
<script>
var counter = 0;
document.getElementById("counter").innerHTML = counter;
setTimeout(function(){ count(); }, 1000);
function count() {
counter++;
document.getElementById("counter").innerHTML = counter;
console.log("counter: " + counter);
setTimeout(function(){ count(); }, 1000);
}
</script>
</body>
</html>
What I want in the app behaviour is:
> Open the app
+ Html page starts counting
> Press the home button / multitask button
+ Html page is still counting (or doing other stuff)
> Get back to the app
+ Html page is still counting and dont reload.
First I uses my own code for WebView. But with a lot of android versions, I used a chromium-webview example from github
I looked into android WebView methods, but I cant figure a solution. I tried also mWebView.onPause(), mWebView.onResume()... With no results. Maybe someone can bring me in the right direction.
This is are the main functions:
private WebView mWebView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.v("main"," create ");
setContentView(R.layout.activity_main);
mWebView = (WebView) findViewById(R.id.activity_main_webview);
mWebView.addJavascriptInterface(new NotificationBindObject(getApplicationContext()), "NotificationBind");
mWebView.getSettings().setDomStorageEnabled(true); // use localstorage
setUpWebViewDefaults(mWebView);
if (savedInstanceState != null) {
mWebView.restoreState(savedInstanceState);
}
if(mWebView.getUrl() == null) {
mWebView.loadUrl("file:///android_asset/www/index.html");
}
}
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
// Save the WebView state (including history stack)
mWebView.saveState(savedInstanceState);
// Always call the superclass so it can save the view hierarchy state
super.onSaveInstanceState(savedInstanceState);
}
Update
Almost there... I made a Service that runs the WebView.
public class TestService extends Service {
private static WebView w;
private static MainActivity ma;
#Override
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
}
public static void setMain(MainActivity a) {
ma = a;
Log.e("main", " setData " );
setView();
}
private static void setView() {
w = (WebView) ma.findViewById(R.id.webView);
Log.e("main", " setData ");
w.getSettings().setDomStorageEnabled(true); // use localstorage
w.getSettings().setJavaScriptEnabled(true);
//ma.setUpWebViewDefaults(w);
w.loadUrl("file:///android_asset/www/index.html");
}
}
MainActivity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.v("main"," create ");
if (savedInstanceState == null) {
setContentView(R.layout.activity_main);
Intent i = new Intent(MainActivity.this, TestService.class);
TestService.setMain(this);
MainActivity.this.startService(i);
} else {
...
}
...
}
Now when I see the console.log("counter" + counter); logging in Eclipse. The only problem is that the WebView in the layout is gone now when I'm back...
I am developing an application in which I would like to create different webViews in some conditions. Despite having more than one webView, the idea is to show only one of them.
I have seen that the best way is create a new class which extends Activity.
This is the main class
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Intent intent = new Intent(this, WebScreen.class);
startActivity(intent);
}
This is the second class I have done to create new Webviews
public class WebScreen extends Activity {
private WebView myWebView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_PROGRESS);
}
public void onClick(View arg0) {
return;
}
#Override
protected void onPause() {
myWebView = null;
super.onPause();
}
#Override
protected void onStart(){
}
#Override
protected void onResume() {
super.onResume();
myWebView = new WebView(this);
myWebView.getSettings().setJavaScriptEnabled(true);
myWebView.loadUrl("myURL");
setContentView(myWebView);
}
#Override
public void onBackPressed() {
super.onBackPressed();
myWebView = null;
}
In the same way you have used a layout on your first activity setContentView(R.layout.main);. You have to set another layout on the WebScreen.onCreate. p.e.
myweblayout.xml
<?xml version="1.0" encoding="utf-8"?>
<WebView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/webview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
Set it at onCreate
setContentView(R.layout.myweblayout)
And get the tag from the activity using
WebView myWebView = (WebView) findViewById(R.id.webview);
myWebView.loadUrl("http://www.example.com");
I suggest you to read Building Web Apps in WebView
You can create two webviews in the same activity and same xml file,just keep the visibility of one of the views as gone and one as visible .You can always switch between the views by changing the visibilities.
Android: someone help:
I notice this kind of question has been asked before by other people but the answers have not been useful to my my case; I need to launch a new activity from an inner
class but all I get is the error bellow:
04-05 15:00:43.851: E/AndroidRuntime(3288): Caused by: java.lang.InstantiationException: com.school.School$StudentProfile
Here is my code snippet:
public class School extends Activity{
ProgressDialogue progressDialogue;
protected WebViewTask _webTask;
String path = "http://www.school.com/student/";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.school);
progressDialogue = new ProgressDialogue(School.this);
_webTask = new WebViewTask();
_webTask.execute();
}
//rest of the code
/** The inner class */
public class StudentProfile {
Context context;
/** Instantiate the interface and set the context */
public StudentProfile(Context c) {
context=c;
}
/** launch student activity */
public void lauchProfile() {
School.this.startActivity(new Intent(School.this, StudentProfile.class));
//Intent intent = new Intent(School.this, StudentProfile.class);
//startActivity(intent);
}
}
void webView(){
String url = path +"student.php";
WebView wv = (WebView) findViewById(R.id.trivia_webview);
WebSettings webSettings = wv.getSettings();
webSettings.setJavaScriptEnabled(true);
wv.addJavascriptInterface(new StudentProfile (this), "Student");
wv.loadUrl(url);
wv.setWebViewClient(new WebViewClient() {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// open URL in the web view itself
if (url.contains(url))
return super.shouldOverrideUrlLoading(view, url);
// open URL in an external web browser
else {
return true;
}
}
});
}
// rest of the code
NOTE: there is a 'student' button on the web view that is supposed to launch the StudentProfile activity.
Your StudentProfile is not an Activity, so you can not start it that way. It needs to be a separate class, and declared in AndroidManifest.xml.
I am new to android.
I am trying to build a simple android application: User clicks the button and a progress dialog appears for 5 seconds.
I used ProgressDialog.show() and got a problem with the context parameter.
Here is my xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<Button
android:id="#+id/btnDialog2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/btnDialog2" />
</LinearLayout>
And here is my code:
public class Dialog22Activity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button btnDialog2 = (Button)findViewById(R.id.btnDialog2);
btnDialog2.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
final ProgressDialog dialog = ProgressDialog.show(getBaseContext(),
"Progress dialog", "Loading...", true);
new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(5000);
dialog.dismiss();
} catch (InterruptedException e) {
}
}
}).start();
}
});
}
}
If i change the context parameter of ProgressDialog.show() from getBaseContext() to v.getContext() my program run normally.
So I wanna ask what is the meanning of context parameter here?
Thanks for your helps.
Just use Dialog22Activity.this instead of getContext() or WhatEverContextFunction() you want, when ever you are within this class and you'll be cool :)
You can refer the android docs for these explanations please see this
http://developer.android.com/reference/android/content/Context.html
getContext() is not defined in an Activity. It's used in a View (or View subclass) to get a reference to the enclosing context (an Activity).
The context in ProgressDialog.show(context) refers to the parent context of this ProgressDialog.
BaseContext effectively returns which ever context is being wrapped by ContextWrapper.
By looking at the code, I can say that this is likely an Activity or Application however ContextWrapper has over 40 known direct and indirect children.
The problem is that this means that what the method returns may be ambiguous and I would rather use getContext() or the Activity, FragmentActivity, ActionBarActivity etc. directly, so that I know what I’m holding on to and that I’m holding a reference to something that can cause a memory leak. Also, I have the additional benefit of being able to take advantage of methods that are provided by these classes.
In case you want to use a ProgressDialog in an external class to an activity, you would create an instance of a Context inside this class and ProgressDialog would use its context:
public class DownloadTask extends AsyncTask<URL, Integer, Void>{
ProgressDialog progressDialog;
private Context context;
#Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog = new ProgressDialog(context);
}
If you are showing the progress dialog on current Activity, use classname.class or 'this' keyword for context.
import androidx.appcompat.app.AppCompatActivity;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.webkit.WebView;
import android.view.View;
import android.webkit.WebViewClient;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.JsResult;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private WebView webView;
private ProgressDialog progressDialog;
startWebView("http://.../mobile/");
}
private void startWebView(String url) {
WebSettings settings = webView.getSettings();
settings.setJavaScriptEnabled(true);
webView.setScrollBarStyle(View.SCROLLBARS_OUTSIDE_OVERLAY);
webView.getSettings().setBuiltInZoomControls(true);
webView.getSettings().setUseWideViewPort(true);
webView.getSettings().setLoadWithOverviewMode(true);
progressDialog = new ProgressDialog(this);
progressDialog.setTitle("Loading...");
progressDialog.setMessage("Wait while loading...");
progressDialog.setCancelable(false); // disable dismiss by tapping outside of the dialog
progressDialog.show();
webView.setWebViewClient(new WebViewClient() {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
#Override
public void onPageFinished(WebView view, String url) {
if (progressDialog.isShowing()) {
progressDialog.dismiss();
}
}
#Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
Toast.makeText(getApplicationContext(), "Error:" + description, Toast.LENGTH_SHORT).show();
}
});
webView.loadUrl(url);
}
}
its the activity context. use:
public class Dialog22Activity extends Activity {
private Activity activity;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
activity = this;
Button btnDialog2 = (Button)findViewById(R.id.btnDialog2);
btnDialog2.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
final ProgressDialog dialog = ProgressDialog.show(activity,
"Progress dialog", "Loading...", true);
new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(5000);
dialog.dismiss();
} catch (InterruptedException e) {
}
}
}).start();
}
});
}
}
information about context: What is 'Context' on Android?
I have looked around on the API and through a few questions on here, and I think I am on the right path. My app is based on a webView object and the initial load has quite a few cached pages so I want progressDialog on the initial start up instead of the blank black screen. Right now the app just crashes but I believe it is because I am creating and calling the AsyncTask object in the wrong place. Right now it is being called in the onCreate() method. I’m not new to Java but I am new to Android and this idea of not working with a main() function is confusing to me.
So where should I call the execute() function if I only want the ProgressDialog shown on the initial launch? And is my AsyncTask object even set up correctly?
public class site extends Activity {
private WebView engine;
private String urlSave;
private WebViewClient yourWebClient;
private ProgressDialog initLoadDialog;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
yourWebClient = new WebViewClient() {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (url.contains("tel:") == true) {
Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse(url));
startActivity(intent);
}
else if(url.contains(“blah") == true && url.contains(“blah2") == false) {
view.loadUrl(url);
}
else if(url.contains(“blah3") == true) {
double[] loc = getGPS();
url += "&cLat=" + loc[0] + "&cLong=" + loc[1];
view.loadUrl(url);
}
else {
/*Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("url"));
startActivity(browserIntent);*/
}
return true;
}
};
}
#Override
public void onStart() {
progressSetup();
setContentView(R.layout.main);
}
public void progressSetup () {
initLoadDialog = new ProgressDialog(site.this);
initLoadDialog.setMessage("A message");
initLoadDialog.setIndeterminate(false);
initLoadDialog.setMax(100);
initLoadDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
urlLoad loading = new urlLoad();
loading.execute();
}
private class urlLoad extends AsyncTask<String, Integer, String>{
#Override
protected String doInBackground(String... url) {
try {
engine = (WebView) findViewById(R.id.web_engine);
engine.getSettings().setJavaScriptEnabled(true);
engine.getSettings().setBuiltInZoomControls(true);
engine.getSettings().setSupportZoom(true);
engine.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
engine.getSettings().setGeolocationEnabled(true);
engine.setWebViewClient(yourWebClient);
engine.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);
engine.loadUrl(“albhal");
} catch (Exception e) {}
return null;
}
protected void onProgressUpdate(Integer... progress) {
initLoadDialog.setProgress(engine.getProgress());
}
}
}
Check your adb log, the error will pretty much explain to you what you didn't do right.
There's a lot of bad practice in your code. For example you call setContentView() in two Methods with different Layouts. The Flow of a android application is to call "onCreate", then "onStart". There is no reason to distinguish between those methods for you. Merge them and decide which layout to populate.
Also it is recommended to change the user-interface (this means also the dialogs) through the managing activity. In your case you are creating a ProgressDialog in the activity which then gets modified by the task. This is something you should avoid.