Wednesday, April 2, 2014

Android CursorLoader with Example

      A CursorLoader is normally used to interact with a ContentProvider asynchronously. It can query in the background against a ContentProvider so the UI thread can continuously interact with the user. This avoids the UI thread being un-responsive while querying ContentProvider. The CursorLoader will initiate the query in separate thread, retrieve the results from ContentProvider and reconnects to the Activity when it is finished.


How to use CursorLoader?

LoaderCallbacks<Cursor> interface is used to create a CursorLoader. This interface provides set of callback methods to initialize, run a CursorLoader.
The activity should implement this interface to use the CursorLoader.

Example:

Sample Project download

CursorLoader

public class MainActivity extends FragmentActivity implements
  LoaderManager.LoaderCallbacks<Cursor> {
    .
    .
}

To initialize a background query we have to use LoaderManager.initLoader() method. This will initiate the background tasks. To get LoaderManager in a FragmentActivity getSupportLoaderManager() is used.
Example:
getSupportLoaderManager().initLoader(1, null, this);

Once we initialize the query, onCreateLoader() method will be invoked by Android. In this method we can create our CursorLoader against the ContentProvider. We can provide Projections, Selection criteria, Sort order during the creation of CursorLoader.
Example:

@Override
public Loader<Cursor> onCreateLoader(int arg0, Bundle arg1) {
 Uri CONTENT_URI = ContactsContract.RawContacts.CONTENT_URI;
 return new CursorLoader(this, CONTENT_URI, null, null, null, null);
}

Once we are done with creation of CursorLoader, the ContentProvider URI specified in the CursorLoader object will be queried. All the projections, selections, sort order will be applied to query the ContentProvider (if specified any).
Once the background thread completes the query, onLoadFinished() method will be invoked.
onLoadFinished() is another callback method which will give us a Cursor with result data from the query. We can use this cursor to get the data and do some processing to display it to the user.

onLoaderReset() method is invoked when the cursor becomes stale/invalid. If the Cursor is being placed in a CursorAdapter, you should use the swapCursor(null) method to remove any references it has to the Loader's data.

Sample Application:

In this sample application we are using CursorLoader to query Contacts Content provider. To run this on emulator we are inserting a new contact from code and querying the same using CursorLoader. 
Note: To read contacts we need to have READ_CONTACTS permission. To write a new contact we need to haveWRITE_CONTACTS permission.

AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.cursorloaderexample"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="16" />

    <uses-permission android:name="android.permission.READ_CONTACTS" >
    </uses-permission>
    <uses-permission android:name="android.permission.WRITE_CONTACTS" >
    </uses-permission>

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.cursorloaderexample.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>


Layout xml file:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity" >

    <TextView
        android:id="@+id/res"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_marginLeft="34dp"
        android:layout_marginTop="22dp" />

</RelativeLayout>


Activity class:

package com.example.cursorloaderexample;

import java.util.ArrayList;

import android.content.ContentProviderOperation;
import android.content.OperationApplicationException;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.RemoteException;
import android.provider.ContactsContract;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.CommonDataKinds.StructuredName;
import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.RawContacts;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.view.Menu;
import android.widget.TextView;

public class MainActivity extends FragmentActivity implements
  LoaderManager.LoaderCallbacks<Cursor> {
 TextView resTextView = null;

 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  resTextView = (TextView) findViewById(R.id.res);
  ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
  int rawContactInsertIndex = ops.size();
  ops.add(ContentProviderOperation.newInsert(RawContacts.CONTENT_URI)
    .withValue(RawContacts.ACCOUNT_TYPE, "Test")
    .withValue(RawContacts.ACCOUNT_NAME, "CTE").build());

  ops.add(ContentProviderOperation
    .newInsert(Data.CONTENT_URI)
    .withValueBackReference(Data.RAW_CONTACT_ID,
      rawContactInsertIndex)
    .withValue(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE)
    .withValue(StructuredName.DISPLAY_NAME, "test name")
    .withValue(Phone.NUMBER, 1234567890).build());
  try {
     //Use below statement to insert a new contact
     //getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
  } catch (Exception e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
  }
  getSupportLoaderManager().initLoader(1, null, this);
 }

 @Override
 public boolean onCreateOptionsMenu(Menu menu) {
  // Inflate the menu; this adds items to the action bar if it is present.
  getMenuInflater().inflate(R.menu.activity_main, menu);
  return true;
 }

 @Override
 public Loader<Cursor> onCreateLoader(int arg0, Bundle arg1) {
  Uri CONTENT_URI = ContactsContract.RawContacts.CONTENT_URI;
  return new CursorLoader(this, CONTENT_URI, null, null, null, null);
 }

 @Override
 public void onLoadFinished(Loader<Cursor> arg0, Cursor cursor) {
  cursor.moveToFirst();
  StringBuilder res = new StringBuilder();
  while (!cursor.isAfterLast()) {
   res.append("\n" + cursor.getString(21) + "-" + cursor.getString(22));

   cursor.moveToNext();
  }
  resTextView.setText(res);

 }

 @Override
 public void onLoaderReset(Loader<Cursor> loader) {
  // If the Cursor is being placed in a CursorAdapter, you should use the
  // swapCursor(null) method to remove any references it has to the
  // Loader's data.
 }

 @Override
 protected void onDestroy() {
  // TODO Auto-generated method stub
  super.onDestroy();
 }

}

Phonegap and setting Android using command line on mac

It's work cordova Android for MAC 1000000000%. I fought solution and now i'm working try this . 
STEPS:
Open Your Terminal and followed by,
  1. touch ~/.bash_profile;
  2. open ~/.bash_profile
  3. PATH="/Users/System-Name/Documents/android-sdk-macosx/tools:/Development/android-sdk-macosx/platform-tools:$PATH" (This is Android SDK Location to stored in My system )
enter image description here
4.Save the file and quit the text editor.
5.Execute your .bash_profile to update your PATH.
6.source ~/.bash_profile
if You want to see your Environment path:
7.In your Terminal Type: set
After you can see like
enter image description here
8.As far as your made it very correct. After your enter command like cordova platform add android. you get following error. because Java SDK doesn't too set environment PATH.
enter image description here
9.open ~/.bash_profile. Add JAVA SDK PATH


Decompiling an Android App on MAC

If you have an apk, there are several tools for reverse engineering it.

First of all you know how to download apk file from play store. There are planty of ways to you can do it. here i tell you very simple and optimized way.

1. http://apps.evozi.com/apk-downloader/#guide

or 

2.  Chrome Extension - Download APK with your own account directly

This is more conventional, and goes back all the way to the java code . It’s works based on two tools:
  • dex2jar,  which converts Android’s Dalvik executables into a Java jar files.
  • JD-GUI,  which decompiles jar files into java source files (any jar, not just android stuff).
Download Tool from here

Tuesday, April 1, 2014

Android System Bar Tint

How to apply android status bar Tint color ?

You must first enable translucency in your Activity - either by using or inheriting from one of the various *.TranslucentDecor themes, by setting the android:windowTranslucentNavigation or android:windowTranslucentStatus theme attributes to true or by applying the FLAG_TRANSLUCENT_NAVIGATIONor FLAG_TRANSLUCENT_STATUS flags to your Activity window in code.

https://github.com/jgilfelt/SystemBarTint


Android Studio Gradle issue upgrading to new version


The most simple Android project has the following build.gradle:

    buildscript {
        repositories {
            mavenCentral()
        }
 
        dependencies {
            classpath 'com.android.tools.build:gradle:0.9.0'
        }
    }
 
    apply plugin: 'android'
 
    android {
        compileSdkVersion 19
        buildToolsVersion "19.0.0"
    }

There are 3 main areas to this Android build file:



Note:

Still the problem cannot solved after made changes above in the your project. Save the changes and close your project then again import to Android Studio 




Android webservcie with PHP code

Create a new project in your Android Studio by filling the required details.
Here the sample project was created by Eclipse IDE.


Facing issue on project import in Android Studio visit this Android Studio issues 

Step by Steps

1. Create new project in Eclipse IDE by going to File ⇒ New ⇒ Android Project and name the Activity class name as MainActivity.
2. Open your AndroidManifest.xml file and add following code. First i am adding all the classes i am creating to manifest file. Also i am adding INTERNET Connect permission. This connection is required must.

<!--  Internet Permissions -->
    <uses-permission android:name="android.permission.INTERNET" />

3. Now create a new xml file under res ⇒ layout folder and name it as main.xml This layout file contains two simple buttons to view all products and add a new product.

4. Open you main activity class which is MainActivity.java and write click events for two button which are mentioned in main.xml layout.

5. Now we need an Activity display all the products in list view format. As we know list view needs two xml files, one for listview and other is for single list row. Create two xml files under res ⇒ layout folder and name it as all_products.xml and list_item.xml


6. Create a new class file and name it as AllActivity.java. In the following code
    6.1 First a request is send to get_products.php file using a Background Async task thread.
    6.2 After getting JSON from get_all_products.php, i parsed it and displayed in a listview.
    6.3 If there are no products found AddNewAcivity is launched.

7. Create a new view and activity to add a new product into mysql database. Create a simple form which contains EditText for product name, price and description.
Create a new xml file and name it as add_product.xml and paste the following code to create a simple form.

8. Now create new Activity to insert a new product into mysql database. Create a class file and name it asNewtActivity.java and type the following code. In the following code
8.1 First new product data is read from the EditText form and formatted into a basic params.
8.2 A request is made to create_product.php to create a new product through HTTP post.
8.3 After getting json response from create_product.php, If success bit is 1 then list view is refreshed with newly added product.

Sample Project:

https://github.com/iDevAndroid/MySQLPHP