I'm sharing some variables accross activities by using a class like this :
public class Globals {
static Boolean hint1_graph_type_switcher;
static Boolean hint2_stockview_valuation;
other variables ...
}
then I'm using these variables anywhere across my multiple activites with ...
if (Globals.hint2_stockview_valuation == false) {
....
}
pretty basic and it was working fine untill ...
I introduced some webview stuff like this:
//-----------------------------------------------------------
// open a webview with the NEWS when the more_arrow is clicked :
mNews.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String news_URL = "http://us.m.yahoo.com/w/yfinance/symbolheadlines/"+ ticker + "/?.intl=us&.lang=en";
Intent news_Webview_intent = new Intent(Chart_View.this, News_Webview.class);
news_Webview_intent.putExtra("NEWS_URL", news_URL);
startActivity(news_Webview_intent);
}
});
//-----------------------------------------------------------
and here's the News_Webview.class:
public class News_Webview extends Activity {
//
// http://www.chrisdanielson.com/tag/progressdialog/
//
String news_URL;
private WebView webview;
private ProgressDialog progressBar;
private static final String TAG = "Hub";
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.webview_news);
this.webview = (WebView)findViewById(R.id.webView);
Bundle extras = getIntent().getExtras();
if (this.getIntent().getExtras()!=null){
news_URL = extras.getString("NEWS_URL");
}
WebSettings settings = webview.getSettings();
settings.setJavaScriptEnabled(true);
webview.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);
final AlertDialog alertDialog = new AlertDialog.Builder(this).create();
progressBar = ProgressDialog.show(News_Webview.this, "", "Loading...");
webview.setWebViewClient(new WebViewClient() {
public boolean shouldOverrideUrlLoading(WebView view, String url) {
//Log.i(TAG, "Processing webview url click...");
Intent viewIntent = new Intent("android.intent.action.VIEW", Uri.parse(url));
startActivity(viewIntent);
return true;
}
public void onPageFinished(WebView view, String url) {
//Log.i(TAG, "Finished loading URL: " +url);
if (progressBar.isShowing()) {
progressBar.dismiss();
}
}
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
Log.e(TAG, "Error: " + description);
Toast.makeText(News_Webview.this, "Oh no! " + description, Toast.LENGTH_SHORT).show();
alertDialog.setTitle("Error");
alertDialog.setMessage(description);
alertDialog.setButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
return;
}
});
alertDialog.show();
}
});
webview.loadUrl(news_URL);
}
}
the problem now is that, when it "comes back" from this Activity, it looks like my Globals variables have disappeared ???
if (Globals.hint2_stockview_valuation == false) {
fires an error :
06-23 12:14:03.443:
ERROR/AndroidRuntime(2611): Caused by:
java.lang.NullPointerException
2 questions then :
Should I use something else than this "Global" class to share variables across activities ? Is it just bad practice to do this ?? I know that I can use the preferences but I thought it was quicker to do it this way (no need to "read" the preferences everytime I start a new activity ...
Any idea on WHY this is happening ? Should I "get back" my savedInstanceState in some way when my activity returns from the News_Webview.class ???
As always, thank you for your help.
H.
U could use intent.putExtra() for inter-activity interaction...
One thing(just for diagnostics) i would suggest is initializing the static variables to some value and then run the App... i suppose your global class is getting re-initialized when the intent started activity returns back...
I have used global variables, but in my case i kept them in an activity which never died. All other activities came after it and it worked perfectly fine...
The NullPointerException is bubbling up from the android runtime and has nothing to do with your Globals type.
Related
I need to collect browser cookies from a WebView and return them to another Activity. Collecting the cookies works already but happens within a class that extends WebViewClient, and I don't know how to return the data from there.
There are 2 Activities; MainActivity and LoginActivity, respectively. MainActivity has a single button that creates an Intent and starts LoginActivity, which has a single WebView. OnCreate(), the WebView is directed to the login page of a website. When the user successfully logs into this site, it stores data in the browser cookies - data that I need for an API call later. How can I return this data to MainActivity?
The WebView has a custom WebViewClient with an overridden OnPageFinished() method, which if the URL is the one expected, will collect the browser cookies, as shown below.
class TempWebViewClient extends WebViewClient {
#Override
public void onPageFinished(WebView view, String url) {
// If page URL is the Home page (ie., you logged in successfully), collect cookies.
if (url.equals("https://slate.sheridancollege.ca/d2l/m/home")) {
String cookies = CookieManager.getInstance().getCookie(url);
String[] cookies2 = cookies.split(";");
String key1 = "";
String key2 = "";
// Find Keys placed in browser cookies.
for (String c : cookies2) {
String[] c2 = c.split("=");
if (c2[0].equals(" phrase1")) {
key1 = c2[1];
}
if (c2[0].equals(" phrase2")) {
key = c2[1];
}
}
}
}
}
LoginActivity should not call finish() (returning to MainActivity) until I've received the keys from the cookies. How can I achieve this, given what I have already? I don't know how LoginActivity can hold off returning to MainActivity until it has the data from its WebView.
public class LoginActivty extends Activity {
WebView webview;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
setupViews();
setContentView(webview);
}
public void setupViews() {
StrictMode.ThreadPolicy policy = new
StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
CookieManager.getInstance().setAcceptCookie(true);
webview = new WebView(this);
webview.setWebViewClient(new TempWebViewClient());
webview.getSettings().setJavaScriptEnabled(true);
webview.loadUrl("website");
}
}
Create reference of login activity in TempWebclient to pass the result once you get your cookie.
class TempWebViewClient extends WebViewClient {
LoginActivty mDelegate;
public TempWebViewClient(LoginActivty ref) {
this.mDelegate = ref;
}
#Override
public void onPageFinished(WebView view, String url) {
// perform task
String cookie;// get from CookieManager
mDelegate.sendCookieAndFinish(cookie);
}
}
Create function in your login activity
public class LoginActivty extends Activity {
WebView webview;
#Override
protected void onCreate(Bundle savedInstanceState) {
....
}
public void setupViews() {
....
// send activity reference to webclient
webview.setWebViewClient(new TempWebViewClient(this));
}
public void sendCookieAndFinish(String cookie){
setResult(ResultCode,ResultIntent); // set result for your main activity
// store cookie to storage
finish();
}
}
From Main Activity start your LoginActivity for result
I am trying to my send data from second activity to third activity it working
fine when I click back arrow in tool back I am getting this error please any one help me how to resolve this one
here my second activity code
pos=Integer.parseInt((getIntent().getExtras()).getString("pos"));
webviewurl=NewsMainFregmant_List.listData.get(pos).getNewsSourceUrl();
webviewurl2=NewsMainFregmant_List.listData.get(pos).getNewsSourceUrl2();
news_site_link_one=(TextView)findViewById(R.id.news_SourceLink_text_one_t_webview);
news_site_like_two= (TextView)findViewById(R.id.news_SourceLink_text_two_t_webview);
news_site_link_one.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent webviewintent = new Intent(getApplicationContext(), News_WebView.class);
webviewintent.putExtra("webviewurl", webviewurl);
startActivity(webviewintent);
}
});
here below my webview
String SourceURL;
WebView webview;
final Activity activity = this;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.getWindow().requestFeature(Window.FEATURE_PROGRESS);
setContentView(R.layout.activity_news__web_view);
Intent intent =getIntent();
SourceURL = intent.getStringExtra("webviewurl");
webview=(WebView)findViewById(R.id.webView);
webview.getSettings().setJavaScriptEnabled(true);
webview.setWebChromeClient(new WebChromeClient() {
public void onProgressChanged(WebView view, int progress)
{
activity.setTitle("Loading...");
activity.setProgress(progress * 100);
if(progress == 100)
activity.setTitle(R.string.app_name);
}
});
webview.setWebViewClient(new WebViewClient() {
#Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
// Handle the error
}
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
});
webview.loadUrl(SourceURL);
}
#Override
public void onBackPressed() {
if (webview.canGoBack()) {
webview.goBack();
} else {
super.onBackPressed();
overridePendingTransition(R.transition.slide_in_down, R.transition.slide_out_down);
}
}
Here below my error code
Attempt to invoke virtual method 'java.lang.String android.os.Bundle.getString(java.lang.String)' on a null object reference
It means that this line :
pos=Integer.parseInt((getIntent().getExtras()).getString("pos"));
points to nothing, getString("pos") does not exist.
There can be many reasons for that. Probably your not filling the intent with Extras when you press back in your Toolbar.
You can do a null check :
if(getIntent().getExtras() != null)
pos=Integer.parseInt((getIntent().getExtras()).getString("pos"));
But better take care of it in your Toolbar back ClickListener and make sure it is not null.
By the way :
Integer.parseInt((getIntent().getExtras()).getString("pos"))
is not good practice. If you want to get a single Integer from an intent you use :
getIntent().getIntExtra("pos", 0); // will be 0 if null
You put it in the intent extra like this :
intent.putExtra("pos", 666);
Now your intent Extra "pos" is assigned the value 666.
It looks like error is in below line
pos=Integer.parseInt((getIntent().getExtras()).getString("pos"));
So you can do 2 things here.
Method1
if(getIntent().getExtras() != null)
pos=Integer.parseInt((getIntent().getExtras()).getString("pos"));
or
Method2
Change your back pressed method
#Override
public void onBackPressed()
{
if (webview.canGoBack())
{
webview.goBack();
} else {
Intent backIntent = new Intent(getApplicationContext(), PreviousClass.class);
backIntent.putExtra("pos",pos);
startActivity(webviewintent);
overridePendingTransition(R.transition.slide_in_down, R.transition.slide_out_down);
}
}
but for this u need to pass pos variable on moving from second activity to third also.
According to the Android reference guide, getExtras():
returns the map of all extras previously added with putExtra(), or null if none have been added.
So it looks like you never called putExtra() or didn't use it correctly.
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 have 3 pages, my webview takes me to page 1, in page 1 you can go to page 2 or 3, I'm trying to identify if you go to page 2 or 3 from page 1. I'm trying to perform an action type, Toast or Intent in my WebView by clicking on a link, but in method to make the Toast onLoadResource send me the error "The method Maketext (Context, CharSequence, int) in the type Toast is not applicable for the arguments (Class , String, int)"
I can do about it to fix this?
public class WebViewTest extends Activity{
WebView site;
String webUrl;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.coursetest);
site = (WebView) findViewById(R.id.wvcurse);
site.loadUrl("http://wstest.comuf.com/test/webviewtest.html");
site.getSettings().setJavaScriptEnabled(true);
site.getSettings().setLoadWithOverviewMode(true);
site.getSettings().setUseWideViewPort(false);
site.setWebViewClient(new ViewClient());}}
my ViewClient.java class is;
public class ViewClient extends WebViewClient {
#Override
public boolean shouldOverrideUrlLoading(WebView v, String url){
super.shouldOverrideUrlLoading(v, url);
v.loadUrl(url);
return true;
}
#Override
public void onLoadResource(WebView v, String url){
super.onLoadResource(v, url);
if( url.equals("http://www.wstest.comuf.com/test/page_two.html") ){
Toast t=Toast.makeText(WebViewTest.class,"passed", Toast.LENGTH_LONG);
t.show();
// Intent i = new Intent("com.mariposatraining.courses.lay_main");
//startActivity(i); here too i have the error "The method startActivity(Intent) is undefined for the type ViewClient"
}
if( url.equals("http://www.wstest.comuf.com/test/page_three.html") ){
Toast t=Toast.makeText(WebViewTest.class,"failed", Toast.LENGTH_LONG);
t.show();
}
}}
How should I make toast or other activity work here?
Really would appreciate your help.
The method signature of Toast.makeText that you're trying to use is:
public static Toast makeText (Context context, CharSequence text, int duration)
WebViewTest.class is not a Context.
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.