Crosswalk 13: Set Cache Mode - android

I've recently migrated from android webview to Crosswalk 13. The only issue i've run into is telling the XWalkView to load content from the app cache.
In my android webview implementation i had implmemented as this
//check connection on a loop
public void CheckConnectivityTask(){
new AsyncTask<Void, Void, Void>() {
#Override
protected Void doInBackground(Void... params) {
//runs every 0.5s
try {
Thread.sleep(500);
} catch (InterruptedException e) {
}
return null;
}
#Override
protected void onPostExecute(Void result) {
CheckConnectivity(true);
}
}.execute();
}
public void CheckConnectivity(boolean recursiveTask){
cm = (ConnectivityManager) getSystemService(Activity.CONNECTIVITY_SERVICE);
if(cm != null && cm.getActiveNetworkInfo() != null && cm.getActiveNetworkInfo().isConnected()){
Log.v("ConnectivityGG", "IS CONNECTED");
mainWebView.getSettings().setCacheMode(WebSettings.LOAD_DEFAULT);
}
else{
mainWebView.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
}
if(recursiveTask){
CheckConnectivityTask();
}
}
As getSettings() has now been removed from XWalk 13, I've been trying to set this using XWalkSettings
inside OnCreate in MainActivity
xWalkSettings = new XWalkSettings(mainWebView.getContext(), null , false);
xWalkSettings.setAppCacheEnabled(true);
and then modifying my looped task
public void CheckConnectivity(boolean recursiveTask){
cm = (ConnectivityManager) getSystemService(Activity.CONNECTIVITY_SERVICE);
if(cm != null && cm.getActiveNetworkInfo() != null && cm.getActiveNetworkInfo().isConnected()){
xWalkSettings.setCacheMode(WebSettings.LOAD_DEFAULT);
}
else{
xWalkSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
}
if(recursiveTask){
CheckConnectivityTask();
}
}
However any attempt to load cached pages fails with "Internet connection has been lost" alert dialogue. Am I instantiating the XWalkSettings instance incorrectly, or is there another way of achieving this?

I found a way from this link. And changed it slightly. Basically need to use reflection to get access to a non public (afaik) method.
Method ___getBridge;
try {
___getBridge = XWalkView.class.getDeclaredMethod("getBridge");
___getBridge.setAccessible(true);
XWalkViewBridge xWalkViewBridge = null;
xWalkViewBridge = (XWalkViewBridge)___getBridge.invoke(mainWebView);
xWalkSettings = xWalkViewBridge.getSettings();
xWalkSettings.setAppCacheEnabled(true);
} catch (NoSuchMethodException e1) {
// TODO Auto-generated catch block
//e1.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
//e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
//e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
//e.printStackTrace();
}
If there's a nicer, cleaner way of doing this I'd love to know :)

Crosswalk didn't expose setCacheMode API before, but it has been exposed recently, please see this JIRA, https://crosswalk-project.org/jira/browse/XWALK-6832
It should be available in Crosswalk 21, you can use it like below:
mXWalkView.getSettings().setCacheMode(XWalkSettings.LOAD_NO_CACHE);
So, enjoy it.. :)

Related

How to get Advertising id in android?

I used this code it's working when i called from activity and fragment
import com.google.android.gms.ads.identifier.AdvertisingIdClient.Info;
Info adInfo = null;
try {
adInfo = AdvertisingIdClient.getAdvertisingIdInfo(mContext);
} catch (IOException e) {
e.printStackTrace();
} catch (GooglePlayServicesAvailabilityException e) {
e.printStackTrace();
} catch (GooglePlayServicesNotAvailableException e) {
e.printStackTrace();
}
String AdId = adInfo.getId();
But when i called from pending intent like Package Removed then i want to call the web service at that time i need advertising id but i got null.if you people had done previously please suggest me.thanks in advance.
try use app context
as receivers could use activity context or app context - depends who&how started the receiver
AdvertisingIdClient.getAdvertisingIdInfo(context.getApplicationContext());
You can try this code and call the bellow method on onCreate
public void getAAID()
{
AsyncTask.execute(new Runnable() {
#Override
public void run() {
try {
AdvertisingIdClient.Info adInfo = AdvertisingIdClient.getAdvertisingIdInfo(MyActivity.this);
String myId = adInfo != null ? adInfo.getId() : null;
Log.i("UIDMY",myId);
} catch (Exception e) {
Log.e("error", e);
}
}
});
}
Check complete post: how to get AAID programmatically

Async Task Network Error

I am creating an android application that uses async task to login and send data(HTTP Post Request. The application works fine when internet connection is good but when logging and it takes too long to post data due to slow connection the application force closes. i would like to display a toast "Error in Connection" when this happens. Please Help
Your application probably crashes, because you are trying to show Toast not in a UI Thread. That is you always should make any changes to UI by using Handler, or within onPostExecute() method, which also runs in UI Thread.
How to catch exceptions in doInBackground's thread and represent them in UI Thread is another question, I can suggest you this solution:
private class LoginTask extends
AsyncTask<Void, Integer, JSONArray[]> {
private static final int NETWORK_NO_ERROR = -1;
private static final int NETWORK_HOST_UNREACHABLE = 1;
private static final int NETWORK_NO_ACCESS_TO_INTERNET = 2;
private static final int NETWORK_TIME_OUT = 3;
// You can continue this list...
Integer serverError = NETWORK_NO_ERROR;
#Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog.show(); // Don't forget to create it before
}
#Override
protected JSONArray[] doInBackground(Void... v) {
JSONArray[] result = null;
try {
result = NetworkManager.login(/* All params you need */);
} catch (JSONException e) {
return null;
} catch (ConnectException e) {
serverError = NETWORK_NO_ACCESS_TO_INTERNET;
return null;
} catch (UnknownHostException e) {
serverError = NETWORK_HOST_UNREACHABLE;
return null;
} catch (SocketTimeoutException e) {
serverError = NETWORK_TIME_OUT;
return null;
} catch (URISyntaxException e) {
// ..
return null;
} catch (ClientProtocolException e) {
// ..
return null;
} catch (Exception e) {
// ..
return null;
}
return result;
}
#Override
protected void onPostExecute(JSONArray[] result) {
progressDialog.dismiss();
if (result != null) {
processAndShowResult(result);
} else {
switch (serverError) {
case NETWORK_NO_ERROR:
Toast.makeText(YourActivity.this, "Probably, invalid response from server", Toast.LENGTH_LONG).show();
break;
case NETWORK_NO_ACCESS_TO_INTERNET:
// You can customize error message (or behavior) for different type of error
case NETWORK_TIME_OUT:
case NETWORK_HOST_UNREACHABLE:
Toast.makeText(YourActivity.this, "Error in Connection", Toast.LENGTH_LONG).show();
break;
}
}
}
}
By this means, you can flexibly control network errors and undertake appropriate actions, according to these errors.

Trouble using reflection with setOverScrollMode

I want to be able to turn off overscroll (the glowing effect when reaching the top or bottom of a page in 2.3+) however I also want my code to run in older versions of android that don't even have overscroll functionality. As per the documentation here: Android Backwards Compatibility I am using reflection in my custom webview class to call setOverScrollMode however everytime I call this on a device running 2.3.4, I get a NoSuchMethodException. Any idea why I can't retrieve this method?
Strangely, if I just call setOverScrollMode without any reflection, it works, so the method is definitely there.
public class MyWebView extends WebView{
public void compatibilitySetOverScroll(){
try {
Method mWebview_SetOverScroll = WebView.class.getMethod("setOverScrollMode", new Class[] { Integer.class } );
/* success, this is a 2.3+ */
if (mWebview_SetOverScroll != null) {
try {
mWebview_SetOverScroll.invoke(this, 2);
} catch (InvocationTargetException ite) {
throw new RuntimeException(ite.getCause());
} catch (IllegalAccessException ie) {
System.err.println("unexpected " + ie);
}
}
} catch (NoSuchMethodException nsme) {
/* failure, must be older device */
}
}
}
Try Integer.TYPE instead of Integer.class
More correct version:
public static void disableOverscroll(View view) {
Class<?> viewCls = view.getClass();
try {
Method m = viewCls.getMethod("setOverScrollMode",
new Class[] { int.class });
int OVER_SCROLL_NEVER = (Integer) viewCls.getField(
"OVER_SCROLL_NEVER").get(view);
m.invoke(view, OVER_SCROLL_NEVER);
} catch (Exception e) {
// swallow
}
}
another way :
try
{
Class<?> myTarget = Class.forName("android.widget.HorizontalScrollView");
Method myMethod = myTarget.getDeclaredMethod("setOverScrollMode", Integer.TYPE);
myMethod.invoke(scrollView, 2);
}
catch (Exception e)
{
e.printStackTrace();
}

How to retrieve the 'last sync' time for an account?

Is it possible to retrieve the time an account was last synchronized, like the system Settings->Accounts&Sync app does? I'm using Android 2.2.
Looking at the 2.2 source for AccountSyncSettings.java, I see the status is retrieved using:
SyncStatusInfo status = ContentResolver.getSyncStatus(account, authority);
but SyncStatusInfo and getSyncStatus don't seem to be part of the public API (marked with #hide). Is there some other way to get at this info?
You can use reflection to achieve this purpose.Here is my code to implement this
private long getLasySyncTime() {
long result = 0;
try {
Method getSyncStatus = ContentResolver.class.getMethod(
"getSyncStatus", Account.class, String.class);
if (mAccount != null && mSyncAdapter != null) {
Object status = getSyncStatus.invoke(null, mAccount,
mSyncAdapter.authority);
Class<?> statusClass = Class
.forName("android.content.SyncStatusInfo");
boolean isStatusObject = statusClass.isInstance(status);
if (isStatusObject) {
Field successTime = statusClass.getField("lastSuccessTime");
result = successTime.getLong(status);
TLog.d(WeixinSetting.class, "get last sync time %d", result);
}
}
} catch (NoSuchMethodException e) {
} catch (IllegalAccessException e) {
} catch (InvocationTargetException e) {
TLog.d(WeixinSetting.class, e.getMessage() + e.getCause().getMessage());
} catch (IllegalArgumentException e) {
} catch (ClassNotFoundException e) {
} catch (NoSuchFieldException e) {
} catch (NullPointerException e) {
}
return result;
}
The Settings app uses ContentResolver.getSyncStatus(account, authority). However, this is not part of the public API. You can use it, but it could break with any future release.

Start / stop built-in Wi-Fi / USB tethering from code?

How can I start or stop the built-in tethering in Android 2.2 from my application?
There is a non-public Tethering API in the ConnectivityManager. As shown above you can use reflection to access it. I tried this on a number of Android 2.2 phones, and it works on all of them (my HTC turns on tethering but does NOT show this in the status bar..., so check from the other end). Below is some rough code which emits debugging stuff and turns on tethering on usb0.
ConnectivityManager cman = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
Method[] methods = cman.getClass().getDeclaredMethods();
for (Method method : methods) {
if (method.getName().equals("getTetherableIfaces")) {
try {
String[] ifaces = (String[]) method.invoke(cman);
for (String iface : ifaces) {
Log.d("TETHER", "Tether available on " + iface);
}
} catch (Exception e) {
e.printStackTrace();
}
}
if (method.getName().equals("isTetheringSupported")) {
try {
boolean supported = (Boolean) method.invoke(cman);
Log.d("TETHER", "Tether is supported: " + (supported ? "yes" : "no"));
} catch (Exception e) {
e.printStackTrace();
}
}
if (method.getName().equals("tether")) {
Log.d("TETHER", "Starting tether usb0");
try {
int result = (Integer) method.invoke(cman, "usb0");
Log.d("TETHER", "Tether usb0 result: " + result);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Please note: this code requires the following permissions to work:
android.permission.ACCESS_NETWORK_STATE
android.permission.CHANGE_NETWORK_STATE
I answered this question here. In short, it is possible, here is the code:
private void setWifiTetheringEnabled(boolean enable) {
WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
Method[] methods = wifiManager.getClass().getDeclaredMethods();
for (Method method : methods) {
if (method.getName().equals("setWifiApEnabled")) {
try {
method.invoke(wifiManager, null, enable);
} catch (Exception ex) {
}
break;
}
}
}
Your app should have the following permission:
android.permission.CHANGE_WIFI_STATE
There are no public APIs in the Android SDK for managing the tethering -- sorry!
I used the code from Android How to turn on hotspot in Android Programmatically! and I enable the portable hotspot for android 4.2. Here's the code.
WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
// TODO Auto-generated method stub
WifiConfiguration wifi_configuration = null;
wifiManager.setWifiEnabled(false);
try
{
//USE REFLECTION TO GET METHOD "SetWifiAPEnabled"
Method method=wifiManager.getClass().getMethod("setWifiApEnabled", WifiConfiguration.class, boolean.class);
method.invoke(wifiManager, wifi_configuration, true);
}
catch (NoSuchMethodException e){
// TODO Auto-generated catch block
e.printStackTrace();
}catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

Categories

Resources