I am fairly new to java and I have been trying to learn, so I made a webview app for my website that I have published and a few people have reported an error as listed below:
java.lang.NullPointerException
at com.alexriggs.android.mafiastreetwars.MafiaStreetWarsActivity$MyWebViewClient.shouldOverrideUrlLoading(MafiaStreetWarsActivity.java:87)
at android.webkit.CallbackProxy.uiOverrideUrlLoading(CallbackProxy.java:227)
at android.webkit.CallbackProxy.handleMessage(CallbackProxy.java:334)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:130)
at android.app.ActivityThread.main(ActivityThread.java:3704)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:875)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:633)
at dalvik.system.NativeStart.main(Native Method)
No I know enough to know that java.lang.NullPointerException means that a variable is empty but being used as not empty. And after looking back at my code, it should never be empty and I cannot reproduce it. So here is my code, can anyone figure out what is wrong? And please remember that I am new to Java, so please use as much detail as possible!
package com.alexriggs.android.mafiastreetwars;
import com.alexriggs.android.mafiastreetwars.R;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Toast;
public class MafiaStreetWarsActivity extends Activity {
/** Called when the activity is first created. */
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu, menu);
return true;
}
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.exit:{
Toast.makeText(this, "Thanks For playing Mafia Street Wars!", Toast.LENGTH_LONG).show();
finish();
break;
}
case R.id.select_and_copy:
{
Toast.makeText(getApplicationContext(), "Select Text by dragging over the text you want to copy.", Toast.LENGTH_LONG).show();
selectAndCopyText(myWebView);
return true;
}
}
return true;
}
private void selectAndCopyText(WebView view) {
try
{
KeyEvent shiftPressEvent = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN,
KeyEvent.KEYCODE_SHIFT_LEFT, 0, 0);
shiftPressEvent.dispatch(view);
}
catch (Exception e)
{
Log.e("dd", "Exception in emulateShiftHeld()", e);
}
}
final Activity activity = this;
WebView myWebView;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
AlertDialog alertDialog = new AlertDialog.Builder(this).create();
alertDialog.setTitle("Remember...");
alertDialog.setMessage("This app is just for mobile access. This game is meant to be played on the computer at MafiaStreetWars.com");
alertDialog.setButton("Thanks for the reminder!", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// here you can add functions
}
});
alertDialog.setIcon(R.drawable.icon);
alertDialog.show();
myWebView = (WebView) findViewById(R.id.webview);
myWebView.getSettings().setJavaScriptEnabled(true);
myWebView.setWebViewClient(new MyWebViewClient());
myWebView.getSettings().setBuiltInZoomControls(true);
myWebView.getSettings().setLoadWithOverviewMode(true);
myWebView.getSettings().setUseWideViewPort(true);
myWebView.getSettings().setPluginsEnabled(true);
Toast.makeText(getApplicationContext(), "Page is loading... Please wait!", Toast.LENGTH_LONG).show();
myWebView.loadUrl("http://mafiastreetwars.com/?pk_campaign=Android&pk_kwd=MainApp");
}
private class MyWebViewClient extends WebViewClient {
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (Uri.parse(url).getHost().equals("mafiastreetwars.com")) {
return false;
}
// Otherwise, give the default behavior (open in browser)
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(intent);
return true;
}
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_BACK) && myWebView.canGoBack()) {
myWebView.goBack();
return true;
}
return super.onKeyDown(keyCode, event);
}
}
It's probably due to Uri.parse(url).getHost() returning null. Check this before you call equals().
Line in question if (Uri.parse(url).getHost().equals("mafiastreetwars.com")) {
Looks like your url is null, or the parse result is null but that is less likely. Check to see if things are null before using them!
I suggest you to do it a little bit more nullsave:
if (url==null)
return false;
Uri lUri = Uri.parse(url);
if ("mafiastreetwars.com".equals(lUri.getHost())) {
return false;
}
that solves your technical problem but maybe not youre business case.
Related
I am working on a project in Android Studio. My MainActivity shows the Actionbar. I created a new empty activity named Teachers. It shows the Actionbar when it's empty. I then created a webview. But when I input this webview code on Teachers activity, the Actionbar is not shown in the app (even though the webview works properly).
package com.codepade.shohel.eee7brur;
import android.app.Activity;
import android.os.Bundle;
import android.view.KeyEvent;
import android.webkit.WebView;
import android.webkit.WebViewClient;
public class Teachers extends Activity {
private WebView webView;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_teachers);
webView = (WebView) findViewById(R.id.teachersweb);
webView.getSettings().setJavaScriptEnabled(true);
webView.loadUrl("file:///android_asset/teachers/index.html");
webView.setWebViewClient(new WebViewClient());
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if(event.getAction() == KeyEvent.ACTION_DOWN){
switch(keyCode)
{
case KeyEvent.KEYCODE_BACK:
if(webView.canGoBack() == true){
webView.goBack();
}else{
finish();
}
return true;
}
}
return super.onKeyDown(keyCode, event);
}
}
in your Activity you can try getActionBar().show();
I am trying to use webView to display an HTML file that is on the device and not the internet. I have my html files in the /Download folder. When I launch the application I get the following error:
Webpage not available
The webpage at file:///storage/sdcard0/Download/manuals/test/index4.html might be temporarily down or it may have been moved permanently to a new web address.
I know the file is there but it will not display it.
Here is my code:
package com.asstechmanuals.techmanual;
import java.io.File;
import android.net.Uri;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.Window;
import android.webkit.WebView;
import android.webkit.WebViewClient;
public class MainActivity extends Activity {
private WebView mWebView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mWebView = (WebView) findViewById(R.id.webview);
mWebView.getSettings().setJavaScriptEnabled(true);
File fileStandard = new File("/storage/sdcard0/Download/manuals/test/index4.html");
File fileNewStandard = new File("/storage/sdcard0/Download/manuals/test/index4.html");
File fileKitKat = new File("/storage/sdcard0/Download/manuals/test/index4.html");
if(fileStandard.exists())
mWebView.loadUrl("file:///storage/sdcard0/Download/manuals/test/index4.html");
else if(fileNewStandard.exists())
mWebView.loadUrl("file:///storage/sdcard0/Download/manuals/test/index4.html");
else if(fileKitKat.exists())
mWebView.loadUrl("file:///storage/sdcard0/Download/manuals/test/index4.html");
else
mWebView.loadUrl("file:///storage/sdcard0/Download/manuals/test/index4.html");
mWebView.setWebViewClient(new vwClient());
}
private class vwClient extends WebViewClient{
#Override
public boolean shouldOverrideUrlLoading(WebView webview, String url)
{
webview.loadUrl(url);
if (url.toLowerCase().contains(".pdf"))
{
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.parse(url), "application/pdf");
startActivity(intent);
}
return true;
}
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
if ((keyCode == KeyEvent.KEYCODE_BACK) && mWebView.canGoBack())
{
mWebView.goBack();
return true;
}
return super.onKeyDown(keyCode, event);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
In your manifest xml file, make sure you have permission to read that folder for your app and permission to use internet (even though you actually are not, it is still required).
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />
I'm very new to android. I want to create an application that turns off all sounds at the selected time. I created a service with some code and in Eclipse there's no errors, but when I press the button nothing happens. I can see in Application Manager that my program and the service SilentHours are running. Here's my code:
MainActivity.java
package com.example.silencecontrol;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
public class MainActivity extends Activity {
public final static String EXTRA_NAME = "sending silentHour value to service SilenceHours";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public void setSilenceHours(View view) {
EditText editText1 = (EditText)findViewById(R.id.editText1);
TextView textView1 = (TextView)findViewById(R.id.textView1);
if(editText1.length() > 0) {
Intent intent = new Intent(this, SilentHours.class);
String editText1String = editText1.getText().toString();
int silentHour = Integer.parseInt(editText1String);
intent.putExtra(EXTRA_NAME, silentHour);
this.startService(intent);
} else {
textView1.setText("Please enter the silence hour. ");
}
}
}
SilentHours.java
package com.example.silencecontrol;
import java.util.Calendar;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
import android.os.IBinder;
public class SilentHours extends Service {
public SilentHours() {
}
protected void onHandleIntent(Intent intent) {
int silentHour = Integer.parseInt(intent.getStringExtra(MainActivity.EXTRA_NAME));
Calendar calendar = Calendar.getInstance();
int currentTime = calendar.get(Calendar.HOUR_OF_DAY);
if(currentTime >= silentHour) {
AudioManager audioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
audioManager.setStreamVolume(AudioManager.STREAM_RING, 0, 0);
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, 0, 0);
}
}
#Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
}
And by the way I can't #Override the onHandleIntent method. If I put the #Override annotation I get error:
The method onHandleIntent(Intent) of type SilentHours must override or implement a supertype method.
Is that annotation necessary?
The method you are looking for is named onStartCommand, not onHandleIntent.
And no, it's not necessary to add this annotation to an overriden method, it's just a very good practice as you can get sure that you respected the signature of the super class.
Let you IDE help you when you code. Simply type "on" then ask for completion to see which method you can override.
Please help, I want to make the button visible only if the checkbox is checked. But the token "else" gives me a syntax error. What do you think it could be? For a while I thought it could be some bracket but I don't really know.
package com.example.holaamigos;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.EditText;
import android.widget.Toast;
public class MainActivity extends Activity {
public final static String EXTRA_SALUDO = "com.example.holaamigos.SALUDO";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final EditText txtNombre = (EditText)findViewById(R.id.TxtNombre);
final Button btnHola = (Button)findViewById(R.id.BtnHola);
final CheckBox checkbox1 =(CheckBox)findViewById(R.id.checkBox1);
checkbox1.setOnCheckedChangeListener(new OnCheckedChangeListener(){
#Override
public void onCheckedChanged(CompoundButton arg0,
boolean checked) {
if (checked)
Toast.makeText(checkbox1.getContext(), "Activo", Toast.LENGTH_LONG).show();
btnHola.setVisibility(0);
btnHola.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, ActivitySaludo.class);
String saludo = txtNombre.getText().toString();
intent.putExtra(EXTRA_SALUDO, saludo);
startActivity(intent);
else
Toast.makeText(checkbox1.getContext(), "Inactivo", Toast.LENGTH_SHORT).show();
}
});
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
When you have multiple instructions in an if else statement, you should use {} i.e :
if (checked){
//your code goes here
}
else {
//One instruction so you can leaves braces but it's better to put them
Toast.makeText(checkbox1.getContext(), "Inactivo", Toast.LENGTH_SHORT).show();
}
A good practice is too always englobe your instructions in {} even if you have only one.
Read this :
In addition, the opening and closing braces are optional, provided
that the "then" clause contains only one statement
Deciding when to omit the braces is a matter of personal taste.
Omitting them can make the code more brittle. If a second statement is
later added to the "then" clause, a common mistake would be forgetting
to add the newly required braces. The compiler cannot catch this sort
of error; you'll just get the wrong results.
Change it for
boolean checked) {
if (checked)
{
Toast.makeText(checkbox1.getContext(), "Activo", Toast.LENGTH_LONG).show();
btnHola.setVisibility(0);
btnHola.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, ActivitySaludo.class);
String saludo = txtNombre.getText().toString();
intent.putExtra(EXTRA_SALUDO, saludo);
startActivity(intent);
}
else
{
Toast.makeText(checkbox1.getContext(), "Inactivo" Toast.LENGTH_SHORT).show();
}
}
I have tried many things and keep receiving a crash error on my Android app. My app is a simple webwrapper app using the webview function. Basically, I have webview displaying a website that has a mobile site. What I am trying to do is make it so that
back button will take the user back to the previous screen
back button on the app (which I put in the layout), will also take the user to the previous screen.
I also want the home button on the phone to go back to the home screen and exit the app completely.
Lastly, the mobile app has external links that should be going into a browser and not staying within the app (example: visit full site).
Below is my code, any help for any of the 1-4 questions would be helpful! :-)! If you need to see my XML dont hesitate to ask.
package com.example.envision;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.webkit.DownloadListener;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.ImageView;
import android.widget.ProgressBar;
public class Envision extends Activity {
/** back button functionality NOT WORKING CAUSES A CRASH
WebView webview;
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if(event.getAction() == KeyEvent.ACTION_DOWN) {
switch(keyCode)
{
case KeyEvent.KEYCODE_BACK:
if(webview.canGoBack() == true){
webview.goBack();
} else {
finish();
}
return true;
}
}
return super.onKeyDown(keyCode, event);
} */
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_envision);
WebView webview = (WebView) findViewById(R.id.webView1);
WebSettings websettings = webview.getSettings();
websettings.setJavaScriptEnabled(true);
websettings.setSaveFormData(false);
websettings.setSavePassword(false);
webview.loadUrl("http://envisionfinancial.ca/m/");
webview.setHorizontalScrollBarEnabled(false);
webview.setScrollBarStyle(View.SCROLLBARS_OUTSIDE_OVERLAY);
webview.setBackgroundColor(128);
webview.setWebViewClient(new EnvisionWebViewClient());
webview.setDownloadListener(new DownloadListener() {
public void onDownloadStart(String url, String userAgent,
String contentDisposition, String mimetype,
long contentLength) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(url));
startActivity(intent);
}
});
}
public void visible(){
WebView webview = (WebView) findViewById(R.id.webView1);
ImageView logo = (ImageView) findViewById(R.id.imageView1);
ProgressBar bar = (ProgressBar) findViewById(R.id.progressBar1);
webview.setVisibility(10);
logo.setVisibility(0);
bar.setVisibility(0);
}
public void unvisible(){
WebView webview = (WebView) findViewById(R.id.webView1);
ImageView logo = (ImageView) findViewById(R.id.imageView1);
ProgressBar bar = (ProgressBar) findViewById(R.id.progressBar1);
webview.setVisibility(0);
logo.setVisibility(10);
bar.setVisibility(10);
}
private class EnvisionWebViewClient extends WebViewClient {
#Override
public boolean shouldOverrideUrlLoading(WebView webview, String url){
webview.loadUrl(url);
return true;
}
#Override
public void onReceivedError(WebView view, int errorCode,
String description, String failingUrl) {
// TODO Auto-generated method stub
view.loadUrl("http://envisionfinancial.ca/m/");
}
#Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
visible();
}
#Override
public void onPageFinished(WebView view, String url) {
unvisible();
}
}
/** exits the app?? review */
public void finishActivity(View v) {
finish();
}
}
Are you getting a NullPointerException in onKeyDown? That is because you do not assign the WebView to the instance variable:
webview = (WebView) findViewById(R.id.webView1);
The back functionality can be implemented like this:
public void onBackPressed() {
if (webview.canGoBack())
webview.goBack();
else
super.onBackPressed();
}
See this :
http://developer.android.com/guide/webapps/webview.html
Scroll to Binding JavaScript code to Android code
http://developer.android.com/reference/android/webkit/WebView.html#addJavascriptInterface(java.lang.Object, java.lang.String)