I'm developing an android app using HTML & JS, (will use PhoneGap after successful development) and I want the app to alert the user if his device is not connected to WiFi or Mobile data, and the app should close after the alert.
I tried this for reference:
How to alert the user when there's no internet connection
However, it doesn't seem to work for me.. Please suggest some other alternative for the same.
Sorry because I don't have enough repulation to comment.
To close the app, you could use:
navigator.app.exitApp();
public void onCreate(Bundle obj)
{
super.onCreate(obj)
setContextView(layout);
if (isOnline())
//do your task
else
{
try {
AlertDialog alertDialog = new AlertDialog.Builder(con).create();
alertDialog.setTitle("Info");
alertDialog.setMessage("Internet not available,try again later.");
alertDialog.setIcon(android.R.drawable.ic_dialog_alert);
alertDialog.setButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
finish();
}
});
alertDialog.show();
}
catch(Exception e)
{
Log.d(Constants.TAG, "Show Dialog: "+e.getMessage());
}
}
}
Related
I have a WinForm application that using cefsharp web browser. From what I learnt about cefsharp, the events MouseDown, Click cannot trigger in WinForm. So I decided to use javascript to send a message to the console, and trigger ChromiumWebBrowser.ConsoleMessage event instead. But that did not work well. Did I mess up the javascript code or execute the code wrongly?
Here are the codes, please noted that UI.cs is a Form object. A panel object pn_Browser already created in the design view. What I tried to do is, click any element and send "success" to the console. Then the Background show the received message if the message in console.log is "success".
Background.cs
public ChromiumWebBrowser browser;
public Background()
{
browser = new ChromiumWebBrowser("https://www.google.com");
browser.ConsoleMessage += browser_ConsoleMessage;
browser.FrameLoadEnd += browser_FrameLoadEnd;
}
public void browser_ConsoleMessage(object sender, ConsoleMessageEventArgs e)
{
if (e.Message == "success")
{
System.Windows.Forms.MessageBox.Show("Received message.");
}
}
public void browser_FrameLoadEnd(object sender, FrameLoadEndEventArgs e)
{
Chromium.ExecuteScriptAsync("document.addEventListener(\"click\", function() {alert('Detect a click.');});");
}
UI.cs
public UI()
{
InitializeComponent();
Background background = new Background();
pn_Browser.Controls.Add(background.browser);
background.browser.JavascriptMessageReceived += browser_JavascriptMessageReceived;
background.browser.ExecuteScriptAsyncWhenPageLoaded(
"function test() {console.log(\"success\")}" +
"document.addEventListener(\"click\", test);"
);
}
delegate void JavascriptReceivedCallback(object sender, JavascriptMessageReceivedEventArgs e);
private void browser_JavascriptMessageReceived(object sender, JavascriptMessageReceivedEventArgs e)
{
if (InvokeRequired)
{
JavascriptReceivedCallback callback = new JavascriptReceivedCallback(Browser_JavascriptMessageReceived);
Invoke(callback, new object[] { sender, e };
}
else
{
MessageBox.Show(e.Message.ToString());
}
}
I have a cordova (android) app with window popout using window.open javascript that override with cordova inAppBrowser when device is ready refer to the code below:
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
window.open = cordova.InAppBrowser.open;
}
Then i want to set an event when user press phone back button or press "x" button to close the popout a dialog will pop out and asked "Are you sure? Y/N" before closing window popout. The code look like this:
var newwindow;
newwindow = window.open('something', '_self ', 'location=no');
newwindow.addEventListener('exit', function(event){ Exit() });
function Exit(){
navigator.notification.confirm(
'Are you sure?',
function(i){
if(i==2)
{
//exit the window popout
}
},
'App Name',
'Cancel,Exit'
);
But it doesn't work as i wanted, the popout window closed then dialog is prompt to user...How can i show a dialog and decides whether to close popout window.
Note: Sorry for bad grammar, i try my best to explain my problem.
I have found a fairly easy solution (android) for simple prompt like "Are you sure" "yes/no?" by editing the inappbrowser.dialog.java file. This solution is only prompting for confirmation before closing inappbrowser, which is suitable for my case.
Modify the java file InAppBrowserDialog.java in this location:
[your cordova project]/platforms/android/src/org/apache/cordova/inappbrowser/
ADD REQUIRED IMPORTS:
import android.content.DialogInterface;
MODIFY THE onBackPressed() FUNCTION
FROM:
public void onBackPressed () {
if (this.inAppBrowser == null) {
this.dismiss();
} else {
// better to go through the in inAppBrowser
// because it does a clean up
if (this.inAppBrowser.hardwareBack() && this.inAppBrowser.canGoBack()) {
this.inAppBrowser.goBack();
} else {
this.inAppBrowser.closeDialog();
}
}
}
TO:
public void onBackPressed() {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context)
.setTitle("Exit")
.setMessage("You are about to exit, are you sure?")
.setPositiveButton("Exit", new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog, int which){
if (inAppBrowser == null) {
dismiss();
}
else {
// better to go through the in inAppBrowser
// because it does a clean up
if (inAppBrowser.hardwareBack() && inAppBrowser.canGoBack()) {
inAppBrowser.goBack();
} else {
inAppBrowser.closeDialog();
}
}
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog,int which){
dialog.cancel();
}
});
alertDialogBuilder.create();
alertDialogBuilder.show();
}
I basically just create an alert dialog on top of checking for inappbrowser when back button is pressed.
I am trying to load local HTML content in my webview. But sometimes it failed to load the content instead shows blank screen. It happens ones in every 5 times of loading.
NOTE My HTML content, I am trying to load is Official 2048 Source code.
Below is my Activity source code
public class GameActivity extends AppCompatActivity {
private WebView mWebView;
#SuppressWarnings("ConstantConditions")
#SuppressLint({ "SetJavaScriptEnabled", "NewApi", "ShowToast"})
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
setContentView(R.layout.activity_game);
Toolbar toolbar = (Toolbar) findViewById(R.id.game_toolbar);
if (toolbar != null) {
setSupportActionBar(toolbar);
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true);
}
}
// Load webview with game
mWebView = (WebView) findViewById(R.id.mainWebView);
WebSettings settings = mWebView.getSettings();
String packageName = getPackageName();
settings.setJavaScriptEnabled(true);
settings.setDomStorageEnabled(true);
settings.setDatabaseEnabled(true);
settings.setRenderPriority(WebSettings.RenderPriority.HIGH);
if (Build.VERSION.SDK_INT >= 19) {
// chromium, enable hardware acceleration
mWebView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
} else {
// older android version, disable hardware acceleration
mWebView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
// Since the database path is automatically handled by Chromium Webkit,
// we should not mention the db path for greater than KitKat version
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
settings.setDatabasePath("/data/data/" + packageName + "/databases");
}
mWebView.addJavascriptInterface(new WebInterface2048(this), "Android");
// If there is a previous instance restore it in the webview
if (savedInstanceState != null) {
mWebView.restoreState(savedInstanceState);
} else {
mWebView.loadUrl("file:///android_asset/2048/index.html");
}
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
finish();
break;
}
return super.onOptionsItemSelected(item);
}
public class WebInterface2048 {
Context mContext;
public WebInterface2048(Context context) {
mContext = context;
}
#JavascriptInterface
public void showToast(String toast) {
Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show();
}
}
}
Till now I have tried the below things to solve the problem:
Put Hardware Acceleration on the of Manifest file.
Enabled and Disabled Hardware Acceleration inside Activity.
Reloaded the same URL inside shouldOverrideUrlLoading
Tried to load the URL inside onStart() instead of onCreate()
But nothing seems to be working for me.
My Logs:
D/OpenGLRenderer: endAllActiveAnimators on 0xb7d7e248 (RippleDrawable) with handle 0xb76b0cf0
I/AppCompatViewInflater: app:theme is now deprecated. Please move to using android:theme instead.
D/cr_Ime: [InputMethodManagerWrapper.java:30] Constructor
W/cr_AwContents: onDetachedFromWindow called when already detached. Ignoring
D/cr_Ime: [InputMethodManagerWrapper.java:59] isActive: false
I/cr_Ime: ImeThread is not enabled.
W/cr_BindingManager: Cannot call determinedVisibility() - never saw a connection for the pid: 18631
D/cr_Ime: [InputMethodManagerWrapper.java:59] isActive: true
D/cr_Ime: [InputMethodManagerWrapper.java:68] hideSoftInputFromWindow
D/OpenGLRenderer: endAllActiveAnimators on 0xb7a893f8 (RippleDrawable) with handle 0xb7ec8810
I/AppCompatViewInflater: app:theme is now deprecated. Please move to using android:theme instead.
D/cr_Ime: [InputMethodManagerWrapper.java:30] Constructor
W/cr_AwContents: onDetachedFromWindow called when already detached. Ignoring
D/cr_Ime: [InputMethodManagerWrapper.java:59] isActive: false
I/cr_Ime: ImeThread is not enabled.
W/cr_BindingManager: Cannot call determinedVisibility() - never saw a connection for the pid: 18631
D/cr_Ime: [InputMethodManagerWrapper.java:59] isActive: true
D/cr_Ime: [InputMethodManagerWrapper.java:68] hideSoftInputFromWindow
Additional Info: My Device is Moto G3 (Android 6.0.1)
Never understood why this is happening. But as a workaround, I came out of this problem using below code:
mWebView.postDelayed(new Runnable() {
#Override
public void run() {
mWebView.loadUrl("file:///android_asset/2048/index.html");
}
}, 500);
Instead of loading the URL in main thread, if I am running in a different thread, it worked for me.
The above work around can be helpful for those, who are facing problem, where their webview shows blank when loads first time and on reloading, it loads the content.
May be its not a prob=per solution, but it worked. If anybody is finding a better solution, please do post.
I solved the issue by manual adding WebView into the layout within onCreate method:
LinearLayout ll = findViewById(R.id.content);
WebView help = new WebView(this);
ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
help.setLayoutParams(lp);
ll.addView(help);
Then load html as usual:
try {
String base64 = Base64.encodeToString(sampleHtml.getBytes("UTF-8"), Base64.DEFAULT);
help.loadData(base64, "text/html; charset=utf-8", "base64");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (Exception ex){
ex.printStackTrace();
}
Try this isolate from the rest of the code. Put it in oncreate by itself to test. saveinstancestate is not always null so it doesn't load.
mWebView.loadUrl("file:///android_asset/2048/index.html");
I have created an android application with simple webview function. In my html page which webview loads, I am using following script.
var message="!!YOU CANNOT COPY ANY TEXT OR IMAGE FROM THIS APP!";
function clickIE4()
{
if (event.button==2)
{
alert(message);
return false;
}
}
function clickNS4(e)
{
if (document.layers||document.getElementById&&!document.all)
{
if (e.which==2||e.which==3)
{
alert(message);
return false;
}
}
}
if (document.layers)
{
document.captureEvents(Event.MOUSEDOWN);
document.onmousedown=clickNS4;
}
else if (document.all&&!document.getElementById)
{
document.onmousedown=clickIE4;
}
document.oncontextmenu=new Function("alert(message);return false")
//for disable select option
//document.onselectstart = new Function("alert(message);return false");
When I open this in android webview application, it does not show the alert message. It works fine when I open it in normal browser.
You need to create WebChromeClient and set to WebiView. Also override onJsAlert method.
WebChromeClient webChromeClient = new WebChromeClient() {
#Override
public boolean onJsAlert(WebView view, String url, String message, final JsResult result) {
new AlertDialog.Builder(context)
.setMessage(message)
.setPositiveButton(android.R.string.ok,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
result.confirm();
}
})
.create()
.show();
return true;
}
}
webView.setWebChromeClient(webChromeClient);
I have an Android app that uses a web view. The web view works well, except for the JS that uses getCurrentPosition to locate the user. I have read about this issue and understand that I need to have the right permissions, and that I also have to set setJavaScriptEnabled(true);. I have done these things, but am still having a lot of trouble with my Android app. Sometimes the prompt that requests permission to obtain the user's location doesn't even come up. Can anyone help me fix this? I have included the relevant Java file, the permissions from my manifest.xml, and the JS that gets the user's location. Any help would be wonderful!
Here is my Java file:
package com.website.appname;
import android.app.Activity;
//OTHER IMPORTS HERE
class MyClient extends WebChromeClient {
#Override
public void onGeolocationPermissionsShowPrompt(String origin,
Callback callback) {
callback.invoke(origin, true, false);
}
}
public class locationPage extends Activity {
WebView webView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.embed);
webView = (WebView) findViewById(R.id.webview);
webView.setWebViewClient(new WebViewClient());
webView.getSettings().setJavaScriptEnabled(true);
webView.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
webView.requestFocus(View.FOCUS_DOWN);
webView.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
return false;
}
});
webView.loadUrl("http://www.website/page.php");
webView.setWebChromeClient(new MyClient());
#SuppressWarnings("unused")
class HelloWebViewClient extends WebViewClient {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
}
}
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_BACK) && webView.canGoBack()) {
webView.goBack();
return true;
}
return super.onKeyDown(keyCode, event);
}
}
Here are the permissions in my manifest:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
And here is the webpage that is loaded by the web view:
<script>
if( navigator.geolocation ) {
// Call getCurrentPosition with success and failure callbacks
navigator.geolocation.getCurrentPosition( success, fail );
}
else {
alert("Sorry, your browser does not support geolocation services.");
}
function success(position) {
// GeoPosition Object
window.location = "another_page.php?user_lat=" + position.coords.latitude
+ "&user_lon=" + position.coords.longitude + "&accuracy=" +
position.coords.accuracy;
}
function fail() {
// Could not obtain location
}
</script>
<script src="http://code.jquery.com/jquery-1.8.2.min.js"></script>
P.S. I have also tried looking at things like android webview geolocation, which were helpful, but my issue still persists. Thank you!
It looks like geolocation is timing out before a position i generated. Try setting a timeout period to delay the default timeout period.
navigator.geolocation.getCurrentPosition(success,
fail,
{timeout:60000});