mytechead

Android & Wordpress Help center

Archive for the category “Android”

Android: Enable local cookies in Phonegap webview

Have been creating Phonegap and Android hybrid app with mixed native and Phonegap specific UI components lately. Yesterday I came across a scenario where I was not able to get the cookie information. After hours of exploration found that a single missing line of code was all I needed to correctly retrieve my saved cookies. So here it goes:-

Inside your Activity which should extend CordovaActivity you should write:-

CookieManager.setAcceptFileSchemeCookies(true);

Just above the line:-

super.loadUrl(URL_TO_LOAD);

that is just before loading the webpage.

This will allow cookies to be accepted for file scheme URLs.

Hope it saves your time!
Advertisements

Android: Share via installed email clients ONLY!

Came across this very easy and clean way of showing users ONLY email clients to choose from while sharing anything via email.

So here goes the code:-

/**
* Displays a dialog to share via email
*
* @param mailTo
* @param mailSubject
* @param mailBody
* @param context
*/
private void shareViaEmail(String mailTo, String mailSubject,
String mailBody, Context context) {
// To ensure that only email clients show up in the chooser menu, we are using mailto string
StringBuilder builder = new StringBuilder("mailto:" + Uri.encode(mailTo));
if (mailSubject != null) {
builder.append("?subject=" + Uri.encode(Uri.encode(mailSubject)));
}
if (mailBody != null) {
builder.append("&body=" + Uri.encode(Uri.encode(mailBody)));
}
String uri = builder.toString();
Intent intent = new Intent(Intent.ACTION_SENDTO, Uri.parse(uri));
context.startActivity(intent);

}

Android: WebView, enable / disable navigation buttons

A very convenient way of changing the state of navigation buttons [forward / back button] of a webview as enabled and disabled as per the availability of next and previous pages is to add this function in your code, and call it from onPageFinished() method of your WebViewClient class.

Code snippet:

mWebView.setWebViewClient(new MyWebViewClient());

public class MyWebViewClient extends WebViewClient{
   @Override
   public void onPageFinished(WebView view, String url) {
         super.onPageFinished(view, url);

         enableDisableNavigationButtons();
   }

   @Override
   public void onPageStarted(WebView view, String url, Bitmap favicon) {
     super.onPageStarted(view, url, favicon);
   }

   @Override
   public void onReceivedError(WebView view, int errorCode,
     String description, String failingUrl) {
     super.onReceivedError(view, errorCode, description, failingUrl);
   }

    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
      return super.shouldOverrideUrlLoading(view, url);
    }
}

 

/**
* Changes state of navigation buttons – Disable / Enable as per
* the availability of previous / next pages.
*/
public void enableDisableNavigationButtons(WebView mWebView) {
// if has previous page, enable the back button

if(mWebView.canGoBack()){
  backButton.setImageDrawable(getResources().getDrawable(R.drawable.back));
}else{
  backButton.setImageDrawable(getResources().getDrawable(R.drawable.back_disabled));
}
// if has next page, enable the next button

if(mWebView.canGoForward()){
  forwardButton.setImageDrawable(getResources().getDrawable(R.drawable.forward));
}else{
  forwardButton.setImageDrawable(getResources().getDrawable(R.drawable.forward_disabled));
}
}

Android: WebView quick settings

A very quick code fragment to load a webview with almost all the required settings, users can skip / edit any of the settings as per their needs

mWebView = (WebView) findViewById(R.id.webview);
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.getSettings().setDatabaseEnabled(true);
mWebView.getSettings().setAppCacheEnabled(false);
mWebView.getSettings().setDomStorageEnabled(true);
mWebView.getSettings().setPluginState(WebSettings.PluginState.ON);
mWebView.setWebViewClient(new MyWebViewClient());
mWebChromeClient = new MyWebChromeClient();
mWebView.setWebChromeClient(mWebChromeClient);

mWebView.getSettings().setRenderPriority(WebSettings.RenderPriority.HIGH);
mWebView.getSettings().setPluginState(android.webkit.WebSettings.PluginState.ON_DEMAND);

mWebView.getSettings().setBuiltInZoomControls(true);
mWebView.getSettings().setUseWideViewPort(true);
mWebView.getSettings().setLoadWithOverviewMode(true); //load url completely zoomed out

Android: Set device orientation

Android has introduced two more orientation modes for devices with API 8+: ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT & ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE. You can set the screen orientation to these modes by using the following code in you Activity class:

try {
    if(Integer.valueOf(android.os.Build.VERSION.SDK_INT) >= 8){
        if(getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT){
            // setting the orientation as per the device orientation for API level 8+
            if(getWindowManager().getDefaultDisplay().getRotation() == Surface.ROTATION_0){
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
       }else if(getWindowManager().getDefaultDisplay().getRotation() == Surface.ROTATION_180){
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT);
       }else if(getWindowManager().getDefaultDisplay().getRotation() == Surface.ROTATION_90){
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT);
       }else if(getWindowManager().getDefaultDisplay().getRotation() == Surface.ROTATION_270){
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
       }
     }else if(getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE){
          if(getWindowManager().getDefaultDisplay().getRotation() == Surface.ROTATION_0){
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
          }else if(getWindowManager().getDefaultDisplay().getRotation() == Surface.ROTATION_180){
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
          }else if(getWindowManager().getDefaultDisplay().getRotation() == Surface.ROTATION_90){
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
          }else if(getWindowManager().getDefaultDisplay().getRotation() == Surface.ROTATION_270){
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
          }
    }
}else if(Integer.valueOf(android.os.Build.VERSION.SDK_INT) < 8){
      // setting the orientation as per the device orientation for API level below 8
      if(getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
      }else {
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
      }

}
} catch (Exception e1) {
e1.printStackTrace();
}

Please note that the above code will set you in infinite loop of orientation changes if we don’t add few more pieces of code:-
1) In android manifest file:- 
<activity android:name=”activity_name” android:label=”@string/app_name” android:configChanges=”orientation|screenSize”>
…………
…………
</activity>

2) Add following code to catch orientation changes:-
@Override

public void onConfigurationChanged(Configuration newConfig){
     super.onConfigurationChanged(newConfig);
}

The entry in manifest file tells the system that I will handle the orientation changes myself and OnCreate should not be called. onConfigurationChanged method is called instead when orientation changes and we can add in here any code we want to execute when the orientation changes.

Android: Updates to handling screen orientation changes

Beginning with Android 3.2 (API level 13), the “screen size” also changes when the device switches between portrait and landscape orientation. Thus, if you want to prevent runtime restarts due to orientation change when developing for API level 13 or higher (as declared by the minSdkVersion and targetSdkVersion attributes), you must include the “screenSize” value in addition to the “orientation” value. That is, you must decalare android:configChanges=”orientation|screenSize” in your android manifest file.

However, if your application targets API level 12 or lower, then your activity always handles this configuration change itself (this configuration change does not restart your activity, even when running on an Android 3.2 or higher device).

Android: Gracefully handle nested scrollbars

Since the time I started android development, having nested scrollbars intercept their touch listeners for a smooth, even and intended scrolling has always been a pain in my ass. But thank god, finally I got the courage to face this and developed a listener which can handle nested scrollbars gracefully.

So here is the source code of my nested scroll listener class:

import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;

/**
* Class enables touch events of a double nested scrollviews / scrollbars
*
* Usage: Set this touchlistener to childview of the nested scrollviews
*
* e.g.
*
* NestedScrollHelper nestedScrollHelper = new NestedScrollHelper();
*
* public boolean onTouch(View v, MotionEvent event){
* // Touch listener of child view
* // Do all the stuff you want to do in this touchlistener of child view
* // Additionally…..
* // Add the listener to handle nested scrollviews
* nestedScrollHelper.onTouch(v, event);
* return false;
* }
*
* @author shoaib
*
*/
public class NestedScrollHelper implements OnTouchListener{

@Override
public boolean onTouch(View v, MotionEvent event) {

// get the event action
int action = event.getAction();

// For each of the action DOWN/UP/MOVE
// disallow touch intercept to parent
switch (action) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_MOVE:
// Disallow ScrollView to intercept touch events.
v.getParent().requestDisallowInterceptTouchEvent(true);
}

// Handle childview’s touch events.
v.onTouchEvent(event);
return true;
}
}

Now once you have this class, inside your Activity you can add this listener something like this:

public class MainActivity extends Activity implements OnTouchListener{

ListView myListView;
NestedScrollHelper nestedScrollHelper = new NestedScrollHelper();

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

myListView = (ListView) findViewById(R.id.listview_id);
myListView.setOnTouchListener(this);

}

public boolean onTouch(View v, MotionEvent event){
// Touch listener of child view
// Do all the stuff you want to do in this touchlistener of child view
// Additionally…..
// Add the listener to handle nested scrollviews
nestedScrollHelper.onTouch(v, event);
return false;
}

}

This is it. You can handle the touch event how ever you want inside this onTouch method and by just calling the nestedScrollHelper.onTouch(v, event); inside this method [onTouch] scrolling will work perfectly smooth.

Hope it helps!

 

PS: Special thanks to my office colleague who helped me in this.

Android: Create a file and write to external storage

Here’s a quick tutorial on how to create a file and write it’s content to external storage:

Let’s first write a code that checks if external storage is available for READ / WRITE operations

/**

* Method to check if user has permissions to write on external storage or not

*/

public static boolean canWriteOnExternalStorage() {
   // get the state of your external storage
   String state = Environment.getExternalStorageState();
   if (Environment.MEDIA_MOUNTED.equals(state)) {
    // if storage is mounted return true
      Log.v(“sTag”, “Yes, can write to external storage.”);
      return true;
   }
   return false;
}

and then let’s use this code to actually write to the external storage:

// get the path to sdcard
File sdcard = Environment.getExternalStorageDirectory();
// to this path add a new directory path
File dir = new File(sdcard.getAbsolutePath() + “/your-dir-name/”);
// create this directory if not already created
dir.mkdir();
// create the file in which we will write the contents
File file = new File(dir, “My-File-Name.txt”);
FileOutputStream os = outStream = new FileOutputStream(file);
String data = “This is the content of my file”;
os.write(data.getBytes());
os.close();

 

And this is it. If now you visit your /sdcard/your-dir-name/ folder you will see a file named – My-File-Name.txt with the content as specified in the code.

PS:- You need the following permission –

<uses-permission android:name=”android.permission.WRITE_EXTERNAL_STORAGE” />

How to remove white spaces between images stacked vertically in a linear layout?

Pressing after a long time. But this one will be helpful!

In android system there is a bug [I would call it a bug, make your own choices 😛 ]; If you have a linear layout and you stack two images vertically on the top of each other. The android system gives a gap between the two images. This is quite irritating and I have spent almost 6 hours getting rid of this.

The solution is:

Add the attribute:

android:adjustViewBounds=”true” in the ImageView you are using.

This will alleviate all the pain!

(whew)

 

PS Thanks to the author of this post and the person who answered this :- http://stackoverflow.com/a/3899702/900732

How to get Height/Width of android screen?

The code snippet below helps you to determine the Height and Width of android screen:

Code before API 13

WindowManager wm = (WindowManager) .getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
Point size = new Point();
this.width = display.getWidth();
this.height = display.getHeight();

Code for API 13+

Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
int height = size.y;

This code will give you height of the window along with the status bar. If you want to exclude the height of status bar you can simply deduct it from the height of the entire window. Following code helps you determine the height of status bar:

Code to get height of status bar

public int getStatusBarHeight() {
int height = 0;
int resourceId = getResources().getIdentifier(“status_bar_height”, “dimen”, “android”);
if (resourceId > 0) {
height = getResources().getDimensionPixelSize(resourceId);
}

return height;
}

Post Navigation