in my app I have a permissions method that checks and asks for permissions if build codes are >= 23, I have implemented AlertDialog to achieve this and show rationale if needed. The problem is when I test on lollipop a dialog window with the app's name pops up every time the app is started, I have fully protected all methods involved to not do anything if build codes are less than 23, so how and why is this dialog box still showing? Here's an image of the rouge dialog box:
And here is all the related code:
public void GMASInit() {
linkGms = RunnerActivity.CurrentActivity;
linkGms.startActivity(new Intent(linkGms, AudioSave.class));
}
protected void onStart() {//RunnerJNILib.ms_context
super.onStart();
if (Build.VERSION.SDK_INT >= 23) {
getPerms();
}
//other unrelated code.....
}
public void getPerms() {
if (Build.VERSION.SDK_INT >= 23) {
try { // Determine weather developer included optional WRITE_SETTINGS permission in the manifest
PackageInfo info = getPackageManager().getPackageInfo(linkGms.getPackageName(), PackageManager.GET_PERMISSIONS);
if (info.requestedPermissions != null) {
for (String p : info.requestedPermissions) {
if (p.contains("WRITE_SETTINGS")) {
perms = 3;
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
final List<String> permissionsList = new ArrayList<String>();
if(!addPermission(permissionsList, Manifest.permission.RECORD_AUDIO)) {permissionsNeeded.add("Record Audio");}
if(!addPermission(permissionsList, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {permissionsNeeded.add("Write storage");}
Log.i("yoyo","Number of permissions in manifest: " + String.valueOf(perms));
if (permissionsList.size() > 0) {
if (permissionsNeeded.size() > 0) {
if (perms == 2) {
message = message + " " + msg1 + " and " + msg2 + " " + "to save and load data and record audio.";
}
if (perms == 3) {
message = message + " " + msg1 + ", " + msg2 + " and " + msg3 + " " + "to save and load data, record audio and change ringtone.";
}
Log.i("yoyo","Message to be shown: " + message);
showMessageOKCancel(message, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface arg0, int arg1) {
if (Build.VERSION.SDK_INT >= 23) {
if (!Settings.System.canWrite(linkGms) && perms == 3) {
Intent writeset = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS);
writeset.setData(Uri.parse("package:" + linkGms.getPackageName()));
linkGms.startActivity(writeset);
}
linkGms.requestPermissions(permissionsList.toArray(new String[permissionsList.size()]), Get_Permission);
finish();
}
}
});
return;
}
}
finish();
}
}
private boolean addPermission(List<String> permissionsList, String permission) {
if (Build.VERSION.SDK_INT >= 23) {
if (linkGms.checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {
permissionsList.add(permission);
if (!linkGms.shouldShowRequestPermissionRationale(permission))
return false;
}
}
return true;
}
private void showMessageOKCancel(String message, DialogInterface.OnClickListener okListener) {
if (Build.VERSION.SDK_INT >= 23) {
new AlertDialog.Builder(linkGms).setTitle(msg0).setMessage(message).setPositiveButton("OK", okListener).setNegativeButton("Cancel", null).create().show();
}
}
As you can see I've gone overkill in trying to prevent this problem, Also note that it's only this dialog box showing (the one in the picture), the permissions dialog box does not show (which is expected). Also more info that might be helpfull/related is when testing android os 23 and up the dialog box I showed you shows above the permissions dialog box, and you have to click outside of it to dismiss it so the actual permissions dialog box can be accessed. please tell me where I've gone wrong and how to fix it, thanks.
I figured it out, it was a strange situation indeed, it had nothing to do with the permissions or alert dialog builder at all, if fact I discovered it by removing all those methods and the alert dialog imports and it still happened, so instead the problem was related to my manifest activity level style code statement. I have this activity statement in my manifest:
<activity android:name=".AudioSave"
android:theme="#android:style/Theme.Holo.Dialog" >
</activity>
So this was causing a conflict with how I have to call the onStart method, but I need the theme for my app, so all I had to do to fix it was to add finish(); before the last closing curly bracket at the end of my onStart method. problem solved, like this:
protected void onStart() {
super.onStart();
//bla bla bla...
finish();
}
Related
To display sensible data users can enable authentication in my app. I am using the android in-build authentication.
However, if the user did not secure his device using any pattern, pin, password or biometric authentication, I would like to open the android settings, where he can setup his authentication. Is there any Intent/ way to go there? I did not find it.
Some code so far:
To determine, if the user did not setup any authentication method:
androidx.biometric.BiometricPrompt biometricPrompt = new BiometricPrompt((FragmentActivity) activity, executor, new BiometricPrompt.AuthenticationCallback() {
#Override
public void onAuthenticationError(int errorCode, #NonNull CharSequence errString) {
super.onAuthenticationError(errorCode, errString);
// Determine, if the user has no device password set.
boolean errorCodeIsBeingHandledSeparately = false;
// HERE WE DETERMINE THAT CREDENTIALS HAVE NOT BEEN SETUP
if (errorCode == BiometricPrompt.ERROR_NO_DEVICE_CREDENTIAL) {
if (authenticationInterface != null) {
errorCodeIsBeingHandledSeparately = true;
authenticationInterface.onUserHasNoDevicePassWordSet();
}
}
// Display error message, only if the error code is not being handled seperately.
if (!errorCodeIsBeingHandledSeparately) {
Toast.makeText(activity, "Authentication error\n" + errString, Toast.LENGTH_LONG).show();
}
}
#Override
public void onAuthenticationSucceeded(#NonNull BiometricPrompt.AuthenticationResult result) {
super.onAuthenticationSucceeded(result);
if (authenticationInterface == null) {
Toast.makeText(activity, "Success", Toast.LENGTH_LONG).show();
}
else {
authenticationInterface.onUserSuccessfullyAuthenticated();
}
}
#Override
public void onAuthenticationFailed() {
super.onAuthenticationFailed();
Toast.makeText(activity, "Authentication failed", Toast.LENGTH_LONG).show();
}
});
The interface to receive authentication return.
/**
* Interface to receive authentication return.
*/
private AuthenticationUtils.AuthenticationInterface authenticationInterface;
public interface AuthenticationInterface {
public void onUserSuccessfullyAuthenticated();
public void onUserHasNoDevicePassWordSet();
}
The dialog where I want to lead the user to go to the device setup credentials.
public void displayNoDeviceCredentialsSetDialog() {
MaterialAlertDialogBuilder noDeviceCredentialsDialog = new MaterialAlertDialogBuilder(activity, R.style.AlertDialogTheme);
String noDeviceCredentials_goToSettings_dialogMessage = activity.getString(R.string.authentication_noDeviceCredentials_goToSettings_dialogMessage);
noDeviceCredentialsDialog.setMessage(noDeviceCredentials_goToSettings_dialogMessage);
noDeviceCredentialsDialog.setPositiveButton(
R.string.DialogConfirmationOK,
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// HERE I WOULD LIKE TO OPEN THE ANDROID SETTING WHERE HE CAN SETUP HIS CREDENTIALS
}
}
);
noDeviceCredentialsDialog.setNegativeButton(
R.string.DialogConfirmationNegativeAnswerText,
null
);
noDeviceCredentialsDialog.show();
}
I would like to go here:
You can get there from settings here:
What i am looking for is something like this: Here we navigate the user to some other android settings.
Intent intent2 = new Intent();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
intent2.setAction(android.provider.Settings.ACTION_APPLICATION_SETTINGS);
intent2.putExtra(android.provider.Settings.EXTRA_APP_PACKAGE, getPackageName());
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){
intent2.setAction(android.provider.Settings.ACTION_APPLICATION_SETTINGS);
intent2.putExtra("app_package", getPackageName());
intent2.putExtra("app_uid", getApplicationInfo().uid);
} else {
intent2.setAction(android.provider.Settings.ACTION_APPLICATION_SETTINGS);
intent2.addCategory(Intent.CATEGORY_DEFAULT);
intent2.setData(Uri.parse("package:" + getPackageName()));
}
startActivity(intent2);
Just figured it out.
There are 3 viable options to use: Settings.ACTION_BIOMETRIC_ENROLL, Settings.ACTION_FINGERPRINT_ENROLL and Settings.ACTION_SECURITY_SETTINGS.
Final implementation I use is:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
activity.startActivity(new Intent(Settings.ACTION_BIOMETRIC_ENROLL));
}
else {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
activity.startActivity(new Intent(Settings.ACTION_FINGERPRINT_ENROLL));
}
else {
activity.startActivity(new Intent(Settings.ACTION_SECURITY_SETTINGS));
}
}
Settings.ACTION_FINGERPRINT_ENROLL opens this: After chosing backup lock screen method and setup the chosen method, the device will ask you to register a fingerprint.
Settings.ACTION_SECURITY_SETTINGS opens this:
In lack of a device higher than Android Build "R" I could not test ACTION_BIOMETRIC_ENROLL, but I presume it will be similar to ACTION_FINGERPRINT_ENROLL.
If you want to see what options there are to open android settings. You can just use "CTRL" + "mouse click" on any Settings.XXX (ACTION_SECURITY_SETTINGS, ACTION_FINGERPRINT_ENROLL, ...) in Android Studio.
You will then see "..\android\platforms\android-31\android.jar!\android\provider\Settings.class"
In case you struggle to figure out which API version is described with "Build.VERSION_CODES.P" you can also click "CTRL" + "Mose Click" on the Build version (P, O, ...).
You will then see this:
This question already has answers here:
Volley Not making request on latest version of Android
(4 answers)
Closed 3 years ago.
I am calling the android API in the same way as for other versions of phone and its working fine till Oreo version i.e. 8. But the API is not getting called in android 9 i.e. pie version and above. If there are some changes in pie, do let me know. Thanks in advance.
private void getLoginAPI(String username, String password, String compnaycoce) {
if (NetworkStatus.isNetworkConnected(this)) {
LoginReqBean bean = new LoginReqBean();
bean.UserId = username;
bean.Password = password;
bean.Company = compnaycoce;
NetworkService serviceCall = new NetworkService(Constants.loginPost(), Constants.TAG_POST, this);
serviceCall.call(bean);
} else
Toast.makeText(this, "Please check Internet connection", Toast.LENGTH_SHORT).show();
}
#Override
public void onNetworkCallInitiated(String service) {
progressDialog = ProgressDialog.show(LoginActivity.this, "Info", "Validating Credentials, Please wait...");
progressDialog.show();
}
#Override
public void onNetworkCallCompleted(String service, String response) {
Log.e("LOGIN JSON ", "login " + response);
if (progressDialog != null && progressDialog.isShowing())
progressDialog.dismiss();
LoginParentBean parentBean = LoginParentBean.fromJson(response);
if (parentBean != null && parentBean.status) {
LoginBean loginBean = parentBean.result;
Toast.makeText(getApplicationContext(), "You Are logged in Successfully!", Toast.LENGTH_LONG).show();
AppPreferences.INSTANCE.setUserID(loginBean.user_id);
AppPreferences.INSTANCE.setUserRole(loginBean.userRole);
AppPreferences.INSTANCE.setUserLocation(loginBean.location);
AppPreferences.INSTANCE.setUserLocationID(loginBean.locationId);
AppPreferences.INSTANCE.setIsPostGres(loginBean.isPostgres);
AppPreferences.INSTANCE.setUserName(loginBean.username);
AppPreferences.INSTANCE.setAccessToken(loginBean.tokenValue);
AppPreferences.INSTANCE.setLogin(true);
Intent intent = new Intent(getApplicationContext(), DashBoardActivity.class);
startActivity(intent);
finish();
} else
Toast.makeText(getApplicationContext(), "Please check your username and password again!", Toast.LENGTH_LONG).show();
}
#Override
public void onNetworkCallError(String service, String errorMessage) {
if (progressDialog != null && progressDialog.isShowing())
progressDialog.dismiss();
MessageDialog msg = new MessageDialog(LoginActivity.this);
msg.setButtonText("Ok");
msg.show(getResources().getString(R.string.error_somethingwent), getResources().getString(R.string.app_name));
}
}
Android 6.0 introduced the useCleartextTraffic attribute under the application element in the android manifest. The default value in Android P is “false”. Setting this to true indicates that the app intends to use clear network traffic.
<application
android:usesCleartextTraffic="true"
</application>
However, this may appear to fix the problem but it opens a threat to data integrity. A better solution is offered in Android 7.0 through network security configuration file
Add below lines in your project's AndroidManifest.xml file
<application
android:usesCleartextTraffic="true">
...
</application>
I am following the example of Pokemon Go app to show a window message likes
You need to [Location, Camera,...] access to use this application. Please allow access in this application [Setting]. Click [Cancel] to exit from this application
When I click the Setting, the application will go to Setting window of this application and I can accept all Permissions.
The Setting window can access by using the code
public void gotoSetting(){
final Intent i = new Intent();
i.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
i.addCategory(Intent.CATEGORY_DEFAULT);
i.setData(Uri.parse("package:" + getApplicationContext().getPackageName()));
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
i.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
startActivity(i);
}
There are my permisions which are stored in a String array
String[] PERMISSIONS = {Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.CAMERA}
I used this code to check if all permission are checked, otherwise it returns false
public static boolean hasAllPermissions(Context context, String... permissions) {
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && context != null && permissions != null) {
for (String permission : permissions) {
if (ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) {
return false;
}
}
}
return true;
}
However, I got an issue that event I did not check all permissions, but the application did not go to Setting again. In additions, I can show an window message to notify if the user did not check all permission. Finally, This is my code
private AlertDialog buildNotificationServiceAlertDialog(){
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
alertDialogBuilder.setTitle("Pemissions Setting");
alertDialogBuilder.setMessage("You need to [Location, Camera,...] access to use this application. Please allow access in this application [Setting]. Click [Cancel] to exit from this application");
alertDialogBuilder.setPositiveButton("Setting",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
gotoSetting();
}
});
alertDialogBuilder.setNegativeButton("Cancel",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// If you choose to not enable the notification listener
// the app. will not work as expected
}
});
return(alertDialogBuilder.create());
}
In onCreate I have
private AlertDialog enableNotificationListenerAlertDialog;
if(!hasAllPermissions(this, PERMISSIONS)){
enableNotificationListenerAlertDialog = buildNotificationServiceAlertDialog();
enableNotificationListenerAlertDialog.show();
}
Update: Solved:. I was missing to call the hasAllPermissions in the onResume() function. Finally, my solution is
#Override
protected void onResume() {
super.onResume();
if(hasAllPermissions(this, PERMISSIONS)==false){
enableNotificationListenerAlertDialog = buildNotificationServiceAlertDialog();
enableNotificationListenerAlertDialog.show();
}
}
I read your question carefully and i notice one mistake in your first line of code.As your code start with "public voide gotoSetting()",The mistake is in the keyword spelling.By correcting, it can be written as "public void gotoSetting()".
I hope this will help you.
I am building an android app that saves a place ID retrieved from the PlaceAutocomplete API. At a later point, I am trying to get the details of the place using the getPlaceById() API. I see that the callback is never getting called.
I have set the following permission:
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>
I have also added the API_KEY:
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value=<API KEY>/>
However, I am unable to retrieve the place details. "onResult" never seems to be getting called. Can anyone please help me with where I might be going wrong?
Thanks!
Below is the code snippet that I am using. Have hardcoded the PlaceId here for simplicity :
PendingResult<PlaceBuffer> placeResult = Places.GeoDataApi.getPlaceById(mGoogleApiClient, "ChIJi-t8KwUWrjsRlp-L9ykb2_k");
placeResult.setResultCallback(new ResultCallback<PlaceBuffer>() {
#Override
public void onResult(PlaceBuffer places) {
Log.i(TAG, "Testing");
if (places.getStatus().isSuccess() && places.getCount() > 0) {
final Place myPlace = places.get(0);
Log.i(TAG, "Place found: " + myPlace.getName());
} else {
Log.e(TAG, "Place not found");
}
places.release();
}
});
I just found out what I was missing out. I missed out the call to mGoogleApiClient.connect(); in the onStart() of the activity. Works like a charm now! :)
The comment in the onCreate() in the below link states that we need to call connect() and disconnect() explicitly if the activity does not extend FragmentActivity.
https://github.com/tangqi92/MyGooglePlaces/blob/master/app/src/main/java/itangqi/me/mygoogleplaces/MainActivity.java
I got the same problem. And actually it's not "not getting invoked" but "haven't run yet".
Here is my wrong code.
public void onClick(View v) {
hideSoftKeyboard();
Log.i("Search Click", "getting Place: " + mMyLocation.id);
if(mMyLocation.id != null) {
Places.GeoDataApi.getPlaceById(mGoogleApiClient, mMyLocation.id)
.setResultCallback(new ResultCallback<PlaceBuffer>() {
#Override
public void onResult(PlaceBuffer places) {
if (places.getStatus().isSuccess() && places.getCount() > 0) {
LatLng coord = places.get(0).getLatLng();
mMyLocation.setLatLng(coord.latitude, coord.longitude);
Log.i("Place by id", "Place found: " + mMyLocation.coordinateString);
} else {
Log.e("Place by id", "Place not found");
}
places.release();
}
});
searchNearby();
}
}
The searchNearby()function uses mMyLocation that should have been changed in onResult. And it hasn't been changed yet, which means onResult hasn't been called before the searchNearby() run.
Then I put the function searchNearby() into onResult and it worked.
So my suggestion would be: put anything you want to run after onResult into it.
I'm using user's geolocation via phonegap.The exapmle is shown below. (ANDROID)
// onSuccess Callback
// This method accepts a Position object, which contains the
// current GPS coordinates
//
var onSuccess = function(position) {
var element = document.getElementById('geolocation');
element.innerHTML = 'Latitude: '+ position.coords.latitude +'<br/>' +
'Longitude: ' + position.coords.longitude +<br/>' +
'Altitude: ' + position.coords.altitude +'<br/>' +
'Accuracy: ' + position.coords.accuracy +<br/>' +
'Altitude Accuracy: ' + position.coords.altitudeAccuracy +'<br/>' +
'Heading: ' + position.coords.heading +<br/>' +
'timestamp: ' + position.timestamp +<br/>';
};
// onError Callback receives a PositionError object
//
function onError(error) {
alert('code: ' + error.code + '\n' +
'message: ' + error.message + '\n');
}
navigator.geolocation.getCurrentPosition(onSuccess, onError);
Is it possible (using phonegap) on error function to open dialog which will lead us to location settings (where user will be able to give me access to his location) instead of alert, as it's done in google maps android application (screenshot below) ?
I'd do just what you are saying, create the dialog, and send them to settings; I'm assuming you have managed to get the onError fcn called at the apropos time, so then
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(getString(R.string.loc_man));
builder.setMessage(getString(R.string.ask_for_gps));
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which)
{
Intent i = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(i);
}
});
builder.setNegativeButton("No", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which)
{
Toast.makeText(getBaseContext(), getString(R.string.gps_no), Toast.LENGTH_SHORT).show();
finish();
}
});
builder.create().show();
what you also need to do is call this function from your javascript... Oh, this is fun, b/c you'll be using a lot of pretty cool java concepts all at once and I've only worked with Cordova, but this should all work the same =] Keep in mind that if you see some variable undefined in my code, you should probably assume it's a feild.
so let's say you are sure this code hits on error, let's make up an interface name; 'Android' is a pretty logical one
function onError(error) {
alert('code: ' + error.code + '\n' +
'message: ' + error.message + '\n');
Android.TurnOnTuneIn();
}
now back in your Java, grep around your phonegap app to find wherever it has 'WebView'; if it's anything like my cordova implementations, it'll have webview.loadUrl() in it somewhere. Open the file that defines this class; this is the one to edit/place all the java we are working on in this question. After something like 'public class PhoneGapActivity extends Activity', insert 'implements CordovaInterface' ( I think not PhoneGapInterface ); if your IDE gives you an error with the option to implement abstract methods, pound that.
Make sure the WebView is a feild in the class, not a variable in a method, then
//CordovaWebView should work, but maybe it needs to be PhoneGapWebView, you're smart, you'll figure it out =]
webView = (CordovaWebView) findViewById(R.id.data_window);
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setBuiltInZoomControls(false);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED, WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED); //this always seemed like a good idea to me
webView.addJavascriptInterface(new JSInterface(this), "Android"); //see the interface name? =]
//this line should already be in this class, just re-use it
webView.loadUrl("file:///"+getContext().getFilesDir().toString()+"/index.html");
now make that interface:
public class JSInterface {
// these fcns are exposed to the WebView
private Context context;
public JSInterface(Context context)
{
context = context;
}
#JavascriptInterface
public void doEchoTest(String echo)
{
//A useful test; I usually use it in a webViewClient that runs the function that calls this in my javascript with this:
//webView.loadUrl("javascript:echo('"echo!!!"');"); //this exact formatting
//but webViewClient is outside the scope of your question and would just confuse the
//issue; however, you may need to implement
//webViewClient with an delaying asynctask to seperatly run the js you loaded with the webpage,
//again, I used to do this ground-up, and phoneGap Might Just Work.
Toast.makeText(context, echo, Toast.LENGTH_SHORT).show();
}
#JavascriptInterface
public void TurnOnTuneIn
{
aMethodThatHasThatFirstBitOfCodeIPublished();
}
}
I love interfaces =]
The rest is fairly boilerplate for your purposes ( but fun to play with nevertheless! ) and you might not need much if any of it. If you notice the method I put up top is not returning the way you want it to, you can use the startActivityForResult method to do the same and I'll bet it'll work nicely; Note the 'super.' call that the Override makes; you only need the Intent ( like I showed you up top ) and some reference number for receiving the result... again, out of the scope of the question. ALso, I included support for the ResultCallback b/c a guy I was working with used it, but I don't use it myself.
#Override
public Activity getActivity(){
return this;
}
#Override
public void setActivityResultCallback(CordovaPlugin plugin) {
this.activityResultCallback = plugin;
}
public void startActivityForResult(CordovaPlugin command, Intent intent, int requestCode) {
this.activityResultCallback = command;
this.activityResultKeepRunning = this.keepRunning;
// If multitasking turned on, then disable it for activities that return results
if (command != null) {
this.keepRunning = false;
}
// Start activity
super.startActivityForResult(intent, requestCode);
}
#Override
public void cancelLoadUrl(){
// no op
}
#Override
public Object onMessage(String id, Object data) {
LOG.d("is", "onMessage(" + id + "," + data + ")");
if ("exit".equals(id)) {
super.finish();
}
return null;
}
#Override
public void onPause() {
Method pause = null; // Pauses the webview.
try {
pause = WebView.class.getMethod("onPause");
}
catch (SecurityException e) { }
catch (NoSuchMethodException e) { }
if (pause != null) {
try { pause.invoke(webView);
}
catch (InvocationTargetException e) { }
catch (IllegalAccessException e) { }
}
else {
// No such method. Stores the current URL.
suspendUrl = webView.getUrl(); // And loads a URL without any processing.
webView.loadUrl("file:///android_asset/nothing.html");
}
super.onPause();
}
#Override
public void onResume() {
super.onResume();
Method resume = null; // Resumes the webview.
try {
resume = WebView.class.getMethod("onResume");
}
catch (SecurityException e) { }
catch (NoSuchMethodException e) { }
if (resume != null) {
try {
resume.invoke(webView);
}
catch (InvocationTargetException e) { }
catch (IllegalAccessException e) { }
}
else if (webView != null) { // No such method. Restores the suspended URL.
if (suspendUrl == null) {
//this should be wherever you have your page; you can probably copy it from what is there now.
webView.loadUrl("file:///"+getContext().getFilesDir().toString()+"/index.html");
}
else {
webView.loadUrl(suspendUrl);
}
}
}
Hope that gets you further along; if you don't use it already, remember to use version control, so you can be reckless with your edits!
gl hf
I share with you, this phonegap plugin, that lets you do that. I added that functionality to that plugin as a contribuitor.
https://github.com/BastienL/GPSDetector