Fancy Gradient Buttons for Android

Design elements for android is some what complex task in the beginning, but as you explore the internet you will find
Default buttons for android code not so cool so I decided to use the image button instead of regular buttons, then too for some low end devices that is not looking good

After searching for internet I got concept to use the Stylesheet properties for buttons HERE

Its pretty simple and straight forward

First you need to define the xml for color gradient effect. I choose Red color first

File 1 res/drawable/btn_red.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true" >
        <shape>
            <solid
                android:color="#ef4444" />
            <stroke
                android:width="1dp"
                android:color="#992f2f" />
            <corners
                android:radius="3dp" />
            <padding
                android:left="10dp"
                android:top="10dp"
                android:right="10dp"
                android:bottom="10dp" />
        </shape>
    </item>
    <item>
        <shape>
            <gradient
                android:startColor="#ef4444"
                android:endColor="#992f2f"
                android:angle="270" />
            <stroke
                android:width="1dp"
                android:color="#992f2f" />
            <corners
                android:radius="3dp" />
            <padding
                android:left="10dp"
                android:top="10dp"
                android:right="10dp"
                android:bottom="10dp" />
        </shape>
    </item>
</selector>

After this file you need to define the style resources for button text

Include following style tag in res/values/strings.xml

<style name="ButtonText">
 <item name="android:layout_width">fill_parent</item>
 <item name="android:layout_height">wrap_content</item>
 <item name="android:textColor">#ffffff</item>
 <item name="android:gravity">center</item>
 <item name="android:layout_margin">3dp</item>
 <item name="android:textSize">30dp</item>
 <item name="android:textStyle">bold</item>
 <item name="android:shadowColor">#000000</item>
 <item name="android:shadowDx">1</item>
 <item name="android:shadowDy">1</item>
 <item name="android:shadowRadius">2</item>
</style>

Finally Include the button code where you want the fancy gradient button to appear as follows

<Button
 android:id="@+id/button1"
 style="@style/ButtonText"
 android:layout_width="match_parent"
 android:background="@drawable/btn_red"
 android:text="RedButton" >
</Button>

Note the background attribute and style attribute .

Advertisements

How to connect your Android app to local instance of Google APP Engine on Android Emulator

Couple of days I am searching for the solution to get the local instance of google app engine to my android app on emulator. This is required as every time you cant deploy the GAE app version to check as its time consuming and not advisable.

To set up this its assumed that you have setup google app engine local instance and your android application

If you are trying, from your Android application through the Android emulator, to access an external service on the same computer (such as your own Google App Engine site) by using the host name localhost or the IP-address 127.0.0.1, you might get a java.net.ConnectException: localhost/127.0.0.1:8888 – Connection refused error – even though you can perfectly well access the service outside the Android application.

 

The reason why a ConnectException occurs is because localhost or 127.0.0.1 inside the Android emulator is the emulator’s own loopback interface, meaning all request sent to the destination will be looped backed to the emulator and won’t actually be sent to your local machine.
To by pass this, simply replace localhost with the IP-address 10.0.2.2as this is a special address towards the real local host.
thats it  and you can now access the your local GAE instance with Android app.

Android Simple Activity Animation

In this post i will explain in simple steps how to add some animation while switching between activities.

To start with first have a look at android developers animation resources HERE

After this lets start with actual code

File 1 left_to_right.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" android:shareInterpolator="true">
<translate android:fromXDelta="-100%" android:toXDelta="0%"
 android:fromYDelta="0%" android:toYDelta="0%"
 android:duration="500"/>
 </set>

File 2 right_to_left.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" android:shareInterpolator="true">
<translate android:fromXDelta="100%" android:toXDelta="0%"
 android:fromYDelta="0%" android:toYDelta="0%"
 android:duration="500"/>
</set>

Place these two files in res/anim folder

After this override the default activity transition by calling the following way

startActivity(new Intent(TestActivity.this,TestActivity.class));     TestActivity.this.finish();     overridePendingTransition(R.anim.left_to_right, R.anim.right_to_left);
 

You can change the animation properties to have some different transitions say bottom to top or fade in fade out etc

Enjoy the stuff.

Helper class to manage HTTP POST requests in ANDROID

Its sometime needed to post certain data to the remote url via get or post method to send data for that we wrote some helper class to make that task easy

public class ServerCommunication { 
public static final String Logger = ServerCommunication.class.getName();
private static String slurp(InputStream in) throws IOException {
    StringBuffer out = new StringBuffer();
       byte[] b = new byte[4096];
        for (int n; (n = in.read(b)) != -1;) {
          out.append(new String(b, 0, n));
       }
     return out.toString();
 }
public static String post_string(String url, String urlParameters) throws IOException {
HttpURLConnection conn = null;
   try {
     conn = (HttpURLConnection) new URL(url).openConnection();
    } catch (MalformedURLException e) {
   Log.e(Logger, "MalformedURLException While Creating URL Connection - " + e.getMessage());
   throw e;
  } catch (IOException e) {
    Log.e(Logger, "IOException While Creating URL Connection - " + e.getMessage());
    throw e;
 }
  conn.setDoOutput(true);
  conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
  conn.setRequestProperty("Content-Length", Integer.toString(urlParameters.length()));
  OutputStream os = null; 
  try {
      os = conn.getOutputStream();
  } catch (IOException e) {
     Log.e(Logger, "IOException While Creating URL OutputStream - " + e.getMessage());
     throw e;
  } 
  try { 
       os.write(urlParameters.toString().getBytes());
    } catch (IOException e) {
  Log.e(Logger, "IOException While writting URL OutputStream - " + e.getMessage());
  throw e; 
   }
  InputStream in = null; 
   try {
      in = conn.getInputStream();
   } catch (IOException e) {
     Log.e(Logger, "IOException While Creating URL InputStream - " + e.getMessage());
     throw e;
   }
    String output = null;
    try {
        output = slurp(in);
    } catch (IOException e) { 
      Log.e(Logger, "IOException While Reading URL OutputStream - " + e.getMessage());
      throw e;
    } finally {
     try {
      os.close();
      in.close();
      } catch (IOException e) {
      Log.e(Logger, "IOException While Closing URL Output and Input Stream - " + e.getMessage());
    }
  }
 conn.disconnect();return output;
}
}

Calling this method is easy

String url ="http://example.com/post/url/to/remote/server.php"
 Log.i(Logger, "URL : - " + url);
 TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
 String parameter = "userid=" + telephonyManager.getDeviceId(); // construct the parameter string
 String data = ServerCommunication.post_string(url, parameter);
 Log.i(Logger, "URL Result: - " + data);

It will return the url result as output so you can decide on server side which data to output, whether json or string or xml etc and proceed with reset things.

Enjoy the stuff

 

Android Save SD Card file to Remote server using PHP

In the previous post I explained about listing the specific extension files in Android list view. Now lets have a look to upload the file to remote server using a server side coding in PHP

private String SaveFileToServer() {
    String serverurl ="http://example.com/uploadfile.php"; // this is your server url to which you post the file contents
    String fileurl = "absolute_path_to_file_stored_on_sd_card"; // the path should be absoulute starting with /mnt/sdcard/filename.doc etc
  
    try {
      FileInputStream fis = new FileInputStream(new File(fileurl));
      ByteArrayOutputStream bos = new ByteArrayOutputStream();
      byte[] buf = new byte[1024];
      try {
        for (int readNum; (readNum = fis.read(buf)) != -1;) {
        bos.write(buf, 0, readNum); // no doubt here is 0
      }
   } catch (IOException ex) {
      ex.printStackTrace();
 }
 byte[] bytes = bos.toByteArray();
 byte[] filetosend = Base64.encode(bytes, Base64.DEFAULT);
 String fts = new String(filetosend);
 this.user.setBase_64_encoded_filestring(fts);
 String parameters = this.user.tofileString();
 try {
   this.message = ServerCommunication.post_string(serverurl, parameters); // this is custom function to post the data to post the remote url
  } catch (IOException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
 }
} catch (FileNotFoundException e) {
 // TODO Auto-generated catch block
 e.printStackTrace();
 }
return this.message;
 }
}

After this lets have a look at server side php code that will accept the data save on server and in return give you full path for the file saved

<?php 
if(isset($_POST['filedata'])) $filedata=$_POST['filedata']; else $filedata=""; // check for filedata to save
if(isset($_POST['file_url'])) $filename=$_POST['file_url']; else $filename=""; // check for filename not empty
$filename=date("ymdhis")."-".$fname;// change the filename to append the timestamp to avoid overwrite
$location="../../files/".$filename;// decide the location
//now write the file
 $filedata1=base64_decode($filedata);
 $ftw=fopen($location,'wb');
 if(fwrite($ftw,$filedata1)) {
 $fileurl="http://www.example.com/files/".$filename;
 echo $fileurl;
 } 
 
 fclose($ftw);
 ?>

So on success it will give you full path as output which you can save in your ANDROID code for future refecence

The code was simple but I have done some modifications as per the requirement. Hope you find this useful, ENJOY the stuff.

Android List documents with Specific extension from SD Card

In previous application we had functionality to attach the document or file from SD card, to let user choose from number of available files and also in folders with specific extension is a challenging task,

So here is snippet of code that we used to list the documents matching with specific extension and too look into directory and sub directory, so at any place you place the document under any folder and this code will list it for you

First declare a ArrayList for the file list to hold and one SD card object to traverse through

private File sdcardObj=new File(Environment.getExternalStorageDirectory().getAbsolutePath());
private ArrayList<String> filelist=new ArrayList<String>();

Now after this prepare one function that will recursively traverse through the folder and file list and list only the specific extension files for you, if you dont need that then you can remove and it will list all the items on your SD card

private void listFiles(File sdcard,ArrayList<String> filelist) {
         if(sdcard.isDirectory()){
             File[] files = sdcard.listFiles();

                     try {
                         for (File f : files){
                            if(!f.isDirectory()) {
                                 if(f.getName().endsWith(".doc")||  f.getName().endsWith(".txt")|| f.getName().endsWith(".docx")||f.getName().endsWith(".rtf")) {
                                     // Log.d(" FILES",f.getName());
                                    this.filelist.add(f.getAbsolutePath());

                                }
                              }
                            else {
                                 this.listFiles(f,this.filelist);
                             }
                     }
               } catch (Exception e) {
                      // TODO Auto-generated catch block
                     //e.printStackTrace();
            } 
      }
  }

You need to call this function in async task as it may take some more time if you SD card is more crowded with documents

When done you can pass on the arraylist you just filled with the valid extension files to display to view so it will look as

 

 

 

 

 

 

 

 

 

 

 

 

And you are done… thats it

The Gmail Public Labels API | Android Developers Blog

[This post is by Nadav Aharony, a product manager on the Android team — Tim Bray]

We’re rolling out new developer features for the Gmail Android app: It now includes a public ContentProvider that you can use to retrieve label data. You can use this to access up-to-date unread counts for specific accounts’ inboxes and labels.

To use the API, the Gmail app needs to be at version 2.3.6 or higher on Froyo or Gingerbread; 4.0.5 or higher on Honeycomb and ICS. Before using it, be sure you first check the Gmail app version; we’ve provided a handy GmailContract.canReadLabels(Context) method to help with this. Your app will need the com.google.android.gm.permission.READ_CONTENT_PROVIDER permission.

Finding the Gmail accounts set up on the device

The Labels API needs a valid Gmail account to build a query for per-label information. Assuming the GET_ACCOUNTS permission, the AccountManager can be used to fetch this information:

// Get the account list, and pick the first one
final String ACCOUNT_TYPE_GOOGLE = "com.google";
final String[] FEATURES_MAIL = {
"service_mail"
};
AccountManager.get(this).getAccountsByTypeAndFeatures(ACCOUNT_TYPE_GOOGLE, FEATURES_MAIL,
new AccountManagerCallback() {
@Override
public void run(AccountManagerFuture future) {
Account[] accounts = null;
try {
accounts = future.getResult();
if (accounts != null && accounts.length > 0) {
String selectedAccount = accounts[0].name;
queryLabels(selectedAccount);
}
} catch (OperationCanceledException oce) {
// TODO: handle exception
} catch (IOException ioe) {
// TODO: handle exception
} catch (AuthenticatorException ae) {
// TODO: handle exception
}
}
}, null /* handler */);

Getting and accessing existing labels

Once you’ve got the email account, you can get a ContentProvider URI to query against. We’ve provided a simple support class called GmailContract.java for constructing the URI and defining the columns and relevant constants.

You can access any label, predefined or user-defined. The predefined labels include (you have to use symbolic constants rather than these strings, see below):

Priority Inbox

Starred

Chats

Sent

Drafts

All mail

Spam

Trash

To obtain a Cursor with information for all labels in an account, your app can either query this URI directly or use a CursorLoader. Here’s an example:

Cursor c =
getContentResolver().query(GmailContract.Labels.getLabelsUri(selectedAccount),
null, null, null, null);
You can query and watch for changes on a single label by storing the URI value in the GmailContract.Labels.URI column from the cursor data.
The NAME value for pre-defined labels can vary by locale, so don’t use GmailContract.Labels.NAME. Instead, identify pre-defined labels like Inbox, Sent or Drafts using the String value in the GmailContract.Labels.CANONICAL_NAME column. Here’s an example:
// loop through the cursor and find the Inbox
if (c != null) {
final String inboxCanonicalName = GmailContract.Labels.LabelCanonicalName.CANONICAL_NAME_INBOX;
final int canonicalNameIndex = c.getColumnIndexOrThrow(GmailContract.Labels.CANONICAL_NAME);
while (c.moveToNext()) {
if (inboxCanonicalName.equals(c.getString(canonicalNameIndex))) {
// this row corresponds to the Inbox
}
}
}

If you choose to use a CursorLoader, it will keep the label counts up to date as they change over time.

Sample App

You can find a sample app that makes use of the new API here. The app provides a basic readout of label and message-count information.

People care about their incoming mail; we’re looking forward to seeing what you do with access to this information. We’re also open to suggestions as to how to improve and extend this new API.

via The Gmail Public Labels API | Android Developers Blog.