Thursday, November 6, 2014

Get my phone number from device


1. Add plugin
D:\mobile\hello>cordova plugin add https://github.com/macdonst/TelephoneNumberPlugin


2. Copy telephonenumber.js
- Copy telephonenumber.js to www/js directory of my project.

3. Prepare page
<html>
    <head>
<link rel="stylesheet" href="css/jquery.mobile-1.4.4.min.css" />
<script src="js/jquery-1.11.1.min.js"></script>
<script src="js/jquery.mobile-1.4.4.min.js"></script>
<script type="text/javascript" src="cordova.js"></script>
<!-- import telephonenumber.js -->
<script type="text/javascript" charset="utf-8" src="js/telephonenumber.js"></script>
    </head>

<div data-role="page" id="phonenumber-page" data-url="phonenumber-page">
<div data-role="header">
<h1>Get telephone number from device</h1>
</div>
<div  data-role="main" class="ui-content">
<a href="#" class="ui-btn" id="showmynumber">Show</a>
</div>
</div>

</html>

4. Add script
<script>
$( "#showmynumber" ).click(function() {
           var telephoneNumber = cordova.require("cordova/plugin/telephonenumber");
           telephoneNumber.get(function(result) {
                 alert("result = " + result);
          }, function() {
                 alert("error");
          });
});
</script>

5. Edit config.xml
- Add this line to config.xml of my project.

<plugin name="TelephoneNumber" value="com.simonmacdonald.cordova.plugins.TelephoneNumber"/>

6. Run...
D:\mobile\hello>cordova run android


Monday, November 3, 2014

Apache Cordova - gettting started

1. Site
Apache cordova - http://cordova.apache.org/

2. Download and istall...
It is recommended that the cordova CLI be installed from npm rather than downloading this .zip version. For more information on installing the npm version see the Command-Line Interface section of the documentation.

<< The Command-Line Infterface >> 
http://cordova.apache.org/docs/en/3.6.0//guide_cli_index.md.html#The%20Command-Line%20Interface
To install the cordova command-line tool, follow these steps:
step 1>> Download and install Node.js. Following installation, you should be able to invoke node and npm on your command line. If desired, you may optionally use a tool such as nvm or nave to manage your Node.js installation.
Node.js® is a platform built on Chrome's JavaScript runtime for easily building fast, scalable network applications. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient, perfect for data-intensive real-time applications that run across distributed devices.

step 2 >> Download and install a git client, if you don't already have one. Following installation, you should be able to invoke giton your command line. Even though you won't be using git manually, the CLI does use it behind-the-scenes to download some assets when creating a new project.
Git is a free and open source distributed version control system designed to handle everything from small to very large projects with speed and efficiency.

step 3>> Install the cordova module using npm utility of Node.js. The cordova module will automatically be downloaded by the npm utility.
  • I'm working on Windows:
    C:\>npm install -g cordova
3. Install required packages
- Install android sdk.
Please see Android Platform Guide for android sdk. => http://cordova.apache.org/docs/en/3.2.0/guide_platforms_android_index.md.html#Android%20Platform%20Guide_requirements_and_support

- Install Apache Ant.
http://ant.apache.org/index.html

- Update path 
- android-sdks\platform-tools
- android-sdks\tools
- apache-ant\bin




















4. Create Hello World application
Go to the directory where you maintain your source code, and run a command such as the following:
    $ cordova create hello com.example.hello HelloWorld
5. Add Platforms
All subsequent commands need to be run within the project's directory, or any subdirectories within its scope:
    $ cd hello
Before you can build the project, you need to specify a set of target platforms. Your ability to run these commands depends on whether your machine supports each SDK, and whether you have already installed each SDK. Run any of these from a Mac:
Please see Android Platform Guide for android sdk. => http://cordova.apache.org/docs/en/3.2.0/guide_platforms_android_index.md.html#Android%20Platform%20Guide_requirements_and_support
You don't need to install all of these platforms. 
For android, JAVA_HOME is specified as a system variables.
    $ cordova platform add ios
    $ cordova platform add amazon-fireos
    $ cordova platform add android
    $ cordova platform add blackberry10
    $ cordova platform add firefoxos
Run any of these from a Windows machine, where wp refers to different versions of the Windows Phone operating system:
    $ cordova platform add wp8
    $ cordova platform add windows
    $ cordova platform add amazon-fireos
    $ cordova platform add android
    $ cordova platform add blackberry10
    $ cordova platform add firefoxos
Run this to check your current set of platforms:
    $ cordova platforms ls
(Note the platform and platforms commands are synonymous.)
Run either of the following synonymous commands to remove a platform:
    $ cordova platform remove blackberry10
    $ cordova platform rm amazon-fireos
    $ cordova platform rm android

6. Build the App

By default, the cordova create script generates a skeletal web-based application whose home page is the project's www/index.html file. Edit this application however you want, but any initialization should be specified as part of the deviceready event handler, referenced by default from www/js/index.js.
Run the following command to iteratively build the project:
    $ cordova build
This generates platform-specific code within the project's platforms subdirectory. You can optionally limit the scope of each build to specific platforms:
    $ cordova build ios
The cordova build command is a shorthand for the following, which in this example is also targeted to a single platform:
    $ cordova prepare ios
    $ cordova compile ios

7. Test the App on an Emulator or Device

SDKs for mobile platforms often come bundled with emulators that execute a device image, so that you can launch the app from the home screen and see how it interacts with many platform features. Run a command such as the following to rebuild the app and view it within a specific platform's emulator:
    $ cordova emulate android

Alternately, you can plug the handset into your computer and test the app directly:
    $ cordova run android





Saturday, June 14, 2014

[CodeIgniter] Remove the index.php in the URL and using sub folders for controller.

1. Edit .htacess file in www root folder.
This is what I have...

<IfModule mod_rewrite.c>
  Options +FollowSymLinks
  RewriteEngine On
  RewriteBase /
  # If your default controller is something other than 'welcome' you should probably change this.
  RewriteRule ^(welcome(/index)?|index(\.php)?)/?$ / [L,R=301]
  RewriteRule ^(.*)/index/?$ $1 [L,R=301]
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteRule ^(.*)$ /index.php/$1 [L]
  SetEnvIfNoCase X-Forwarded-For .+ proxy=yes
  SetEnvIfNoCase X-moz prefetch no_access=yes
  
  # Block pre-fetch requests with X-moz headers.
  RewriteCond %{ENV:no_access} yes
  RewriteRule .* - [F,L]
  # Fix for infinite redirect loops.
  RewriteCond %{ENV:REDIRECT_STATUS} 200
  RewriteRule .* - [L]
</IfModule>

2. Make mod_rewrite enabled in apache configuration file(httpd.conf)
Just uncoment this line.
LoadModule rewrite_module modules/mod_rewrite.so

Make sure AllowOverride is set to All.
AllowOverride All

3. Extend the core Router class of CodeIgniter(for using controller sub folder)
You can obtain the MY_Router.php file at this link and save it to application/core/ folder.
https://degreesofzero.com/article/controllers-in-sub-sub-folders-in-codeigniter.html

4. Restart WAMP server.

5. Tips - If you want to add port based virtual hosts ....

Listen 8080
NameVirtualHost *:8080

<Directory />
#    Require all denied
    Options Indexes FollowSymLinks Includes ExecCGI
    AllowOverride All
    Order deny,allow
    Allow from all
</Directory>

<VirtualHost *:8080>
    ServerName localhost
    DocumentRoot "D:/admin"
</VirtualHost>



Monday, April 21, 2014

To do recursive works in Androd

1.  Create Notification service...

public class NotificationService extends Service{

public static boolean registered = false;

@Override

public int onStartCommand(Intent intent, int flags, int startId) {

   Log.i("NotificationService", "Service Started!!!@@@@@@@@@@@@@@@@@@@@@@@");

   // TODO Add your jobs here

   return Service.START_STICKY; // .START_NOT_STICKY;
}

@Override

public IBinder onBind(Intent intent) {
     Log.i("NotificationService", "Service binded!!!@@@@@@@@@@@@@@@@@@@@@@@");
     // TODO Auto-generated method stub
     return null;
}

public static void startMe(final Context ctx, final long secs, boolean force){

     if(registered && !force) return;

     Log.i("NotificationService", "startMe!!!@@@@@@@@@@@@@@@@@@@@@@@");

     (new Thread(){

      public void run(){

       try {
          sleep(secs * 1000); // you can remove this code, if you don't want to have initial delay...
      } catch (InterruptedException e) {
      }

       Calendar cal = Calendar.getInstance();
      Intent intent = new Intent(ctx, NotificationService.class);
      PendingIntent pintent = PendingIntent.getService(ctx, 0, intent, 0);
      AlarmManager alarm = (AlarmManager)ctx.getSystemService(Context.ALARM_SERVICE);

       // Start every secs seconds
      alarm.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), secs*1000, pintent);

       // alarm.cancel(operation);
      registered = true;
   }
}).start();
}
}

2. Update manifest xml.

<application

... >
....

<service android:name="com.examples.NotificationService"
android:enabled="true" />

3. Start service
In your activity or some where...

@Override
protected void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   setContentView(R.layout.activity_test);
   NotificationService.startMe(getBaseContext(), 30); // starts every 30 secs.
}

Google Cloud Messaging(GCM) for Android. (Part 2/2)

6. Implement GCM receiver code.(Client)
<< Broadcast Receiver class>>

public class GCMBroadcastReceiver extends WakefulBroadcastReceiver{
public static final String Key_Type = "Type";
public static final String Key_Command = "CMD";
public static final String Key_Msg = "MSG";

@Override
public void onReceive(Context context, Intent intent) {
    Log.i("GCMBroadcastReceiver.onReceive","new message is received.");


    Bundle extras = intent.getExtras();
    String action = intent.getAction();
    if(extras != null){
        GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(context);
        String messageType = gcm.getMessageType(intent);
        // read data from gcm

        String type = intent.getStringExtra(Key_Type);
        String command = intent.getStringExtra(Key_Command);
        String msg = intent.getStringExtra(Key_Msg);

        // TODO you can add some specific code to do....
        // You can start new service to do some works.
        // startWakefulService(context, (intent.setComponent(comp)));
        // see the artical in google developer's guide http://developer.android.com/google/gcm/client.html#sample-receive

    }
}
}


7. Setup in AndroidManifast.xml file.(Client)
The instuction under ... http://developer.android.com/google/gcm/client.html#manifest

<manifest package="com.example.gcm" ...>
    <uses-permission android:name="android.permission.INTERNET" />

    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    <uses-permission android:name="android.permission.WAKE_LOCK" /> <!-- I didn't add this permission -->
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />

    <permission android:name="com.example.gcm.permission.C2D_MESSAGE"

android:protectionLevel="signature" />

    <uses-permission android:name="com.example.gcm.permission.C2D_MESSAGE" />


<application ...>
            <receiver
android:name=".GcmBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
                <intent-filter>
                    <action android:name="com.google.android.c2dm.intent.RECEIVE" />
                    <category android:name="com.example.gcm" />
                </intent-filter>
            </receiver>
            <service android:name=".GcmIntentService" /> <!-- if you created service to handle gcm messages you should add this service-->
</application>


8. Implement GCM message sender.(Server)
  • This is the PHP function to send gcm message to GCM connecton server.
  • You can also send gcm message to GCM connection server from you android app.
  • As you may not need it if you have a server to send the message, I will not add the codes. :-)
  • I used Curl... and you can use the lib with comment off this extesion in php.ini, if you installed latest WAMP server.
  • extension=php_curl.dll

function sendGCMMessage_($data, $registrationIDs)
{   $apiKey = 'GsfgaSFc13-2reIDSD4qK_3_dfghspVWDSxEAA'; // this is the brower key you generated in 3. Creating a Google API project and obtaining an API Key.

    $senderId = "153023456724"; // this is the project code you generated in 3. Creating a Google API project and obtaining an API Key.

    $url = 'https://android.googleapis.com/gcm/send';

 

   $fields = array(

   'delay_while_idle' => False, // If you want to receive message when the phone is idle, you have to set this 'False'. You can set this 'True' to save the battery.
   'time_to_live' => 108,
   'collapse_key' => 'score_update',
   'registration_ids' => $registrationIDs,
   'data' => $data,

   );

   $headers = array(

   'Authorization: key=' . $apiKey,
   'Sender: id=' . $senderId,
   'Content-Type: application/json'

   );

   // Open connection
   $ch = curl_init();
   // Set the URL, number of POST vars, POST data

   curl_setopt( $ch, CURLOPT_URL, $url);

   curl_setopt( $ch, CURLOPT_POST, true);

   curl_setopt( $ch, CURLOPT_HTTPHEADER, $headers);

   curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true);

   curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

   curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode( $fields));

   $result = curl_exec($ch);

   return $result;

}
  • how to call the function?? It is quite easy. 

$registrationIDs = array("APA91bEr6sdfjJzIsdfO76YsdfsvQ5NGago9JvRYod0v-n...", "APA91bEr6zWLWizsdfMO76YVRdfsfQ5NGagdfYod0vdsf...");
// The registeration id you obtained in 5. Implement GCM register code.(Client). You can add multiful registeration ids.

$data = array("Type" => "My Type", "CMD" => 'My Command', "MSG" => "My Message" );
// You should add the same key value pairs just the same as you will receive in you client app you implemented in 6. Implement GCM receiver code.(Client).
$result = sendGCMMessage_($data, $registrationIDs);
 

Sunday, April 20, 2014

Google Cloud Messaging(GCM) for Android. (Part 1/2)

1. What is GCM??

You can implement push service in you app with GCM and can find more information from this page.
This logo image is free to use.
http://developer.android.com/google/gcm/index.html

Under my experience, push messages cannot be delivered well when  user turn on wifi connection. So, you should implent pull service such as alarm notification together or develop your own push service.

The gcm message can be done under below messaging processes.

a. Register for GCM(Client)
This step only occurs on time for each client. In this step, client android app will obtain registration id from GCM connection server.
You can send the reg id to server to let server can send message to client with the key.

b. Send message to GCM connection server.(Server)
You have to implement a program to send message to GCM.
You will use the reg id of step 1.
I'll choose HTTP JSON method for this post.

c. GCM connection server tries to send message to client app.

d. Receive GCM message.(Client)
You have to implement WakefulBroadcastReceiver in your app.

2. Steps for implementation.
The step is quite simple.
  • Creating a Google API project and obtaining an API Key.
  • Set Up Google Play Services for Android.(Client)
  • Implement GCM register code.(Client)
  • Implement GCM receiver code.(Client)
  • Implement GCM message sender.(Server)
3. Creating a Google API project and obtaining an API Key.
  • go to google cloud console(https://cloud.google.com/console).
  • Create project if you don't have on yet. Copy project code to use later.
  • go to APIs & auth>Credentials and click 'Create New Key' button under Public API access.
  • In the Create a new key dialog, click Browser key.
  • When click 'create' button you can have a new browser key. Copy it to further use.
4. Set Up Google Play Services for Android.(Client)

Please see How to use Android Google Maps(API Ver2) in older Android version such as 2.3.(Part 1/2)  for this topic.
 
5. Implement GCM register code.(Client)
Your PROJECTCODE - the google API project code you created in 3. Creating a Google API project and obtaining an API Key.

@Override

protected void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   setContentView(R.layout.activity_gcm_register);


   RegisterBackground task = new RegisterBackground();

   task.setContext(getBaseContext());

   task.execute();

}
// inner class that sends GCM registration request and receive registration id.
class RegisterBackground extends AsyncTask<String,String,String>{
   Context ctx;
   public void setContext(Context ctx){
      this.ctx = ctx;
   }
@Override

public String doInBackground(String... arg0) {
   String msg = "";
   String errMsg = "";
   try {
      String regId = GoogleCloudMessaging.getInstance(ctx).register("Your PROJECTCODE");
      msg = "Dvice registered, registration ID=" + regId;
      Log.i("GCMRegister.RegisterBackground", msg);
      if(regId != null){
         sendMyInfo(regId);
      }
   } catch (IOException ex) {
      errMsg = "Error :" + ex.getMessage();
      Log.e("GCMRegister.RegisterBackground", errMsg, ex);
   }
   return errMsg;
}
}
 
public void sendMyInfo(String regId){
    // TODO add your code to send GCM registration id to your server system.


Code igniter multiple file upload.

1. Prepare upload form view.

<< uploadview.php >>

<html>
<head>
<title>Upload Form</title>
</head>
<body>
<h2> file upload example </h2>
Only image files(gif|jpg|png) can be accepted. <br /> <br />
<?php echo $error;?>
<?php echo form_open_multipart('upload/do_upload');?>
<input type="file" name="userfile" size="20" /><br /><br />
<input type="file" name="userfile2" size="20" />
<br /><br />
<input type="submit" value="upload" />
</form>
</body>
</html>

2. Prepare uploadsuccess page view.

<< uploadsuccess.php >>

<html>
<head>
<title>Upload Form</title>
</head>
<body>
<h3>Your file was successfully uploaded!</h3>
<table ><tr valign=top><td>
<ul>
<?php foreach ($upload_data as $item => $value):?>
<li><?php echo $item;?>: <?php echo $value;?></li>
<?php endforeach; ?>
</ul>
<img src="/uploads/<?php echo $upload_data["file_name"]?>">
</td><td>
<ul>
<?php foreach ($upload_data2 as $item => $value):?>
<li><?php echo $item;?>: <?php echo $value;?></li>
<?php endforeach; ?>
</ul>
<img src="/uploads/<?php echo $upload_data2["file_name"]?>">
</td></tr></table>
<p><?php echo anchor('upload', 'Upload Another File!'); ?></p>
</body>
</html>

3. Prepare upload controller.

<< upload.php >>

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Upload extends CI_Controller {
    public function __construct() {
        parent::__construct();
    }

   function index()
   {
     $data['error'] = '';
     $this->load->view('uploadview', $data);
   }
   function do_upload()
   {
     $this->load->helper(array('form', 'url'));
     $config['upload_path'] = 'C:\wamp\www\uploads';
     $config['allowed_types'] = 'gif|jpg|png';
     $config['max_size'] = '100';
     $config['max_width']  = '1024';
     $config['max_height']  = '768';
     $this->load->library('upload', $config);

     $result = $this->upload->do_upload("userfile");
     if (!$result){
         $error = array('error' => $this->upload->display_errors());
         echo $this->upload->display_errors();
         $this->load->view('uploadview', $error);
         return;
     }
     $data = array('upload_data' => $this->upload->data());
     $result2 = $this->upload->do_upload("userfile2");
     if (!$result2){
         $error = array('error' => $this->upload->display_errors());
         echo $this->upload->display_errors();
         $this->load->view('uploadview', $error);
         return;
     }
     $data['upload_data2'] = $this->upload->data();
     $this->load->view('uploadsuccess', $data);
     }
}

4. You can find more information from this user-guide page.

http://ellislab.com/codeigniter/user-guide/libraries/file_uploading.html