admin

336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

1. 전체 페이지 cache 사용 설정.

<script type="text/javascript" charset="utf-8">

    $( document ).on( "mobileinit", function() {

$.mobile.page.prototype.options.domCache = true;

});

</script>


2. 페이지 단위별 설정.

<div data-role="page" id="cacheMe" data-dom-cache="true">


3.  페이지 호출시 설정

$('#page').page({ domCache: true });


4. 전체 페이지 cache사용 설정시 특정페이지 만 cache사용 안함 설정

<div data-role="page" data-cache="never">


참고 사이트: http://kosbie.net/cmu/fall-12/15-237/handouts/lab6-advanced-jquery-mobile.html

336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

cordova cordova-plugin-admob plugin을 사용하여 애드몹광고하기

1). admob 가입하기

http://kr.admob.com/my_sites/ 사이트에 회원 가입 후 "사이트 및 앱"을 선택 후 사이트 및 앱 추가를 클릭 한다.


앱을 추가 한다. 

App Store URL : https://itunes.apple.com/app/id + Apple ID

App Store URL : https://itunes.apple.com/app/id + Apple ID

Apple ID : Itunes Connect에서 확인 .


정보를 다 입력 했으면 계속을 클릭하여 저장 한다.

최종 등록이 완성된 화면이다 .


설정관리를 클릭하여 publisherId(게시자ID)를 확인한다.


publisherId에 게시자 ID를 입력한다.


2) plugin 설치하기(https://github.com/aliokan/cordova-plugin-admob)

  해당 프로젝트의/platform으로 이동 

  cordova plugin add https://github.com/aliokan/cordova-plugin-admob.git   

설치확인.

config.xml

    <feature name="AdMobPlugin">

        <param name="ios-package" value="AdMobPlugin" />

    </feature>

www/cordova_plugin.j

{

        "file": "plugins/com.google.cordova.plugin.AdMobPlugin/www/AdMobPlugin.js",

        "id": "com.google.cordova.plugin.AdMobPlugin.AdMob",

        "clobbers": [

            "window.admob"

        ]

    }

plugin 확인

AdMobPlugin.js확인


  admob SDK를 설치할 필요가 없다 plugin에 포함이 되어있다.

Project에서 설정


3) Xcode 설정

Libraries 설정

  Proejct > Build Phases > Link Binary With Libraries 을 열어 "  Ad Support.framework"를 추가 해 준다.





https://github.com/aliokan/cordova-plugin-admob/blob/master/Example/index.js를 참조하여 

코드를 수정 후 테스트 해보자.

336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

앱 이름 변경하기

IOS에서 표시되는 앱의 이름을 변경 함


Project > Build Settings > Packaging > Product Name 을 변경


변경후 다시 실행하면 아래와 같이 이름이 변경된 것을 확인 할 수 있음.



336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

iOS 7, PhoneGap and the Status Bar 

폰갭(코도바)이 IOS 7에서 status bar 가 겹치는 현상 해결..



(원문)-http://www.kadrmasconcepts.com/blog/2013/10/06/ios-7-phonegap-and-the-status-bar/

1. cordov3.1.0으로 업데이트

cd ~/my_project_directory




2. Xcode에서 status Bar 설정

  Project > Resources > -info.plist를 열어 아래와 같이 수정 합니다.


"+" 기호를 클릭하여 아래와 같이 

key: Status bar is initially hidde

value: YES

key: View controller-based status bar appearance

value: No

를 추가 해준다.


이렇게 한다음 확인 하면  IOS 7의 status Bar가 사라진것을 확인 할 수 있다.



my

336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.


 Cordova(3.0.6)  Apps 작성시 아래와 같이 텍스트 입력시 텍스트 박스를 키보드 위로 올릴기 설정하기

Proejct > res > xml > config.xml 을 열어

<preference name="fullscreen" value="false" /> 

fullscreen의 옵션을 true에서 fase로 변경하면 아래와같이 텍스트 입력시 키보드 입력 위로 올라 갑니다.


336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

1. 사전준비

  1)필요한 키

     (1) client

           가). GCMIntentService Project_id OR Push Plugin의 Sender ID

           API Console의 project ID 

       

나). Register ID: Client에서 GCM Server로부터 발급 받은 Register ID ()

       (2)  Server

            가).   API Key

                    https://code.google.com/apis/console에서 발급받은 API Key


나). Client Reg ID(메세지를 받을 Client Register ID ==>)

 

2. https://code.google.com/apis/console 등록 

※ api Console 등록으로 알수얻을수 있는것

  Proejct ID : https://code.google.com/apis/console/#project:0000XXXXX

   #project 뒤부분의 0000XXXXX가 프로젝트  ID  이다.

         => Client에서 GCM Server로 등록시 사용.

  API Key :  GCM Service를 등록하여 받은 Key

             => GCM Server로 메세지 전송시 사용


1) https://code.google.com/apis/console에 접속 


2) Sercies를 클릭

3) Google Cloud Messaging for Android 클릭 



4) 동의가 완료되면 아래와 같이 On으로 표시 되어 있는것을 확인.

5) 그리고 다시 API Service를 클릭하면 아래와 같이 API Key가 발급된것을 확인 할 수 있음


4. GCM 개발환경 설정

1) GCM 관련 Plugin 설정

(1) android SDK가 설치된 Eclipse에서 Window > Android SDK Manager를 실행 합니다.

(2) Google Clound Messaging for Android를 선택하고 install packages..를 클릭.

(3) 설치가 완료되면 아래와 같이 Android SDK가 설치된 디렉토리 하위에 관련 jar파일이 생성된것을 확인 할 수 잇습니다.

gcm.jar를 Client로 복사하고

gcm-server.jar, json-simple-1.1jar를 서버 프로젝트로 복사하면 설정이 완료 됩니다. 


4. cordova Push plugin 설정

cordova prject생성한 디렉토리로 이동

cd /Users/myname/java/hybridweb/helloworld

1) Push Notification Plugin  추가

cordova plugin add https://github.com/phonegap-build/PushPlugin.git

2) device Plugin 추가

    cordova plugin add https://git-wip-us.apache.org/repos/asf/cordova-plugin-device.git

    vi platforms/android/AndroidManifest.xml을 열어

     <uses-permission android:name="android.permission.READ_PHONE_STATE" /> 이부분이 있는지 확인 하고 없으면 추가 합니다.


최종 AndroidManifest.xml의 내용

<?xml version='1.0' encoding='utf-8'?>

<manifest android:hardwareAccelerated="true" android:versionCode="1" android:versionName="1.0.0" android:windowSoftInputMode="adjustPan" package="com.example.helloworld" xmlns:android="http://schemas.android.com/apk/res/android">

    <supports-screens android:anyDensity="true" android:largeScreens="true" android:normalScreens="true" android:resizeable="true" android:smallScreens="true" android:xlargeScreens="true" />

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

    <application android:debuggable="true" android:hardwareAccelerated="true" android:icon="@drawable/icon" android:label="@string/app_name">

        <activity android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale" android:label="@string/app_name" android:name="HelloWorld" android:theme="@android:style/Theme.Black.NoTitleBar">

            <intent-filter>

                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />

            </intent-filter>

        </activity>

        <activity android:name="com.plugin.gcm.PushHandlerActivity" />

        <receiver android:name="com.plugin.gcm.CordovaGCMBroadcastReceiver" android:permission="com.google.android.c2dm.permission.SEND">

            <intent-filter>

                <action android:name="com.google.android.c2dm.intent.RECEIVE" />

                <action android:name="com.google.android.c2dm.intent.REGISTRATION" />

                <category android:name="com.example.helloworld" />

            </intent-filter>

        </receiver>

        <service android:name="com.plugin.gcm.GCMIntentService" />

    </application>

    <uses-sdk android:minSdkVersion="10" android:targetSdkVersion="18" />

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

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

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

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

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

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

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

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

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

    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />

    <permission android:name="com.example.helloworld.permission.C2D_MESSAGE" android:protectionLevel="signature" />

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

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

</manifest>

3) PushNotification java file 확인

    ※ PushNotification을 설치 했을경우 com.plugin.gcm에 GCMIntentService.java이 생성되고

      PushNotification을 사용하지 않을 경우 com.example.helloworl에 GCMIntentService.java을 구현 해야 함. 

4) assets/www/PushNotification.js 화일을 확인후 없으면 찾아서 복사해줘야 함.

   

https://github.com/phonegap-build/PushPlugin/releases여기에서 최신버젼을 다운받아 설치 할 수도 있다.


5. Client Program

1). index.html

<!doctype html>

<html>

        <meta charset="UTF-8" name="viewport" content="width=device-width, initial-scale=1"> 

            <title>Windorado.com</title>

            <link rel="stylesheet" href="css/jquery.mobile-1.3.2.css" />

            <script src="js/jquery-1.9.1.js"></script>

            <script src="cordova.js"></script>

             <script src="PushNotification.js"></script>

            <script type="text/javascript">

            var pushNotification;

            function onDeviceReady() {

     try 

   

                    pushNotification = window.plugins.pushNotification;

                    if (device.platform == 'android' || device.platform == 'Android') {

    $("#app-status-ul").append('<li>registering android</li>');

                        pushNotification.register(successHandler, errorHandler, {"senderID":"894488614381","ecb":"onNotificationGCM"}); // required!

    } else {

    $("#app-status-ul").append('<li>registering iOS</li>');

                        pushNotification.register(tokenHandler, errorHandler, {"badge":"true","sound":"true","alert":"true","ecb":"onNotificationAPN"}); // required!

                    }

                    }

    catch(err) 

   

    txt="There was an error on this page.\n\n"

    txt+="Error description: " + err.message + "\n\n"

    alert(txt); 

   

                }

             // result contains any error description text returned from the plugin call

                function tokenHandler (result) {

                    $("#app-status-ul").append('<li>token: '+ result +'</li>');

                    // Your iOS push server needs to know the token before it can push to this device

                    // here is where you might want to send it the token for later use.

                }


                function successHandler (result) {

                    $("#app-status-ul").append('<li>success:'+ result +'</li>');

                }

                

                function errorHandler (error) {

                    $("#app-status-ul").append('<li>error:'+ error +'</li>');

                }

             // iOS

                function onNotificationAPN(event) {

                    if (event.alert) {

                        navigator.notification.alert(event.alert);

                    }


                    if (event.sound) {

                        var snd = new Media(event.sound);

                        snd.play();

                    }


                    if (event.badge) {

                        pushNotification.setApplicationIconBadgeNumber(successHandler, errorHandler, event.badge);

                    }

                }

                // Android

                        function onNotificationGCM(e) {

                

                            $("#app-status-ul").append('<li>EVENT -> RECEIVED:' + e.event + '</li>');


                            switch( e.event )

                            {

                                case 'registered':

                                if ( e.regid.length > 0 )

                                {

                                    $("#app-status-ul").append('<li>REGISTERED -> REGID:' + e.regid + "</li>");

                                    // Your GCM push server needs to know the regID before it can push to this device

                                    // here is where you might want to send it the regID for later use.

                                    console.log("regID = " + e.regid);

                                    //alert("regID = " + e.regid);

                                }

                                break;


                                case 'message':

                                    // if this flag is set, this notification happened while we were in the foreground.

                                    // you might want to play a sound to get the user's attention, throw up a dialog, etc.

                                    if (e.foreground)

                                    {

                                        $("#app-status-ul").append('<li>--INLINE NOTIFICATION--' + '</li>');


                                        // if the notification contains a soundname, play it.

                                        var my_media = new Media("/android_asset/www/"+e.soundname);

                                        my_media.play();

                                    }

                                    else

                                    {   // otherwise we were launched because the user touched a notification in the notification tray.

                                        if (e.coldstart)

                                            $("#app-status-ul").append('<li>--COLDSTART NOTIFICATION--' + '</li>');

                                        else

                                        $("#app-status-ul").append('<li>--BACKGROUND NOTIFICATION--' + '</li>');

                                    }


                                    $("#app-status-ul").append('<li>MESSAGE -> MSG: ' + e.payload.message + '</li>');

                                    $("#app-status-ul").append('<li>MESSAGE -> MSGCNT: ' + e.payload.msgcnt + '</li>');

                                break;


                                case 'error':

                                    $("#app-status-ul").append('<li>ERROR -> MSG:' + e.msg + '</li>');

                                break;


                                default:

                                    $("#app-status-ul").append('<li>EVENT -> Unknown, an event was received and we do not know what it is</li>');

                                break;

                            }

                        }           

            

    document.addEventListener('deviceready', onDeviceReady, false);

             </script>

             <script src="js/jquery.mobile-1.3.2.js"></script>

    </head>

 <body>

       <div id="app-status-div">

<ul id="app-status-ul">

<li>Cordova PushNotification Plugin Demo</li>

</ul>

</div>


        </div>

        

 </body>

</html>


2). GCMIntentService.java

package com.plugin.gcm;


import java.util.Iterator;

import java.util.List;


import com.google.android.gcm.GCMBaseIntentService;


import org.json.JSONException;

import org.json.JSONObject;


import android.annotation.SuppressLint;

import android.app.ActivityManager;

import android.app.ActivityManager.RunningTaskInfo;

import android.app.Notification;

import android.app.NotificationManager;

import android.app.PendingIntent;

import android.content.Context;

import android.content.Intent;

import android.os.Bundle;

import android.support.v4.app.NotificationCompat;

import android.util.Log;


@SuppressLint("NewApi")

public class GCMIntentService extends GCMBaseIntentService {


public static final int NOTIFICATION_ID = 237;

private static final String TAG = "GCMIntentService";

public GCMIntentService() {

super("GCMIntentService");

}


@Override

public void onRegistered(Context context, String regId) {


Log.v(TAG, "onRegistered: "+ regId);


JSONObject json;


try

{

json = new JSONObject().put("event", "registered");

json.put("regid", regId);


Log.v(TAG, "onRegistered: " + json.toString());


// Send this JSON data to the JavaScript application above EVENT should be set to the msg type

// In this case this is the registration ID

PushPlugin.sendJavascript( json );


}

catch( JSONException e)

{

// No message to the user is sent, JSON failed

Log.e(TAG, "onRegistered: JSON exception");

}

}


@Override

public void onUnregistered(Context context, String regId) {

Log.d(TAG, "onUnregistered - regId: " + regId);

}


@Override

protected void onMessage(Context context, Intent intent) {

Log.d(TAG, "onMessage - context: " + context);


// Extract the payload from the message

Bundle extras = intent.getExtras();

StringBuffer msg = new StringBuffer();

        Iterator<String> iterator = extras.keySet().iterator();

        while(iterator.hasNext()) {

            String key = iterator.next();

            String value = extras.get(key).toString();

            Log.i(TAG, "onMessage. "+key+" : "+value);

            msg.append(String.format("key:[%s]value:[%s]", key,value));

        }

        extras.putString("message",msg.toString());

        extras.putString("msgcnt", "0");

        createNotification(context, extras);

        /*

if (extras != null)

{

PushPlugin.sendExtras(extras);


// Send a notification if there is a message

if (extras.getString("message").length() != 0) {

createNotification(context, extras);

}

}

*/

}


public void createNotification(Context context, Bundle extras)

{

NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

String appName = getAppName(this);


Intent notificationIntent = new Intent(this, PushHandlerActivity.class);

notificationIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);

notificationIntent.putExtra("pushBundle", extras);


PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);

NotificationCompat.Builder mBuilder =

new NotificationCompat.Builder(context)

.setDefaults(Notification.DEFAULT_ALL)

.setSmallIcon(context.getApplicationInfo().icon)

.setWhen(System.currentTimeMillis())

.setContentTitle(appName)

.setTicker(appName)

.setContentIntent(contentIntent);


String message = extras.getString("message");

if (message != null) {

mBuilder.setContentText(message);

} else {

mBuilder.setContentText("<missing message content>");

}


String msgcnt = extras.getString("msgcnt");

if (msgcnt != null) {

mBuilder.setNumber(Integer.parseInt(msgcnt));

}

mNotificationManager.notify((String) appName, NOTIFICATION_ID, mBuilder.build());

}

public static void cancelNotification(Context context)

{

NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);

mNotificationManager.cancel((String)getAppName(context), NOTIFICATION_ID);

}

private static String getAppName(Context context)

{

CharSequence appName = 

context

.getPackageManager()

.getApplicationLabel(context.getApplicationInfo());

return (String)appName;

}

@Override

public void onError(Context context, String errorId) {

Log.e(TAG, "onError - errorId: " + errorId);

}


}


6. Server Program

  http://developer.android.com/intl/ko/google/gcm/server.html을 참고하여 서버 모듈을 작성합니다.

{

  "registration_ids" : ["APA91bEcaH32K2lAD-EHn739Utx_6l3Ntaiu1K5PDeSAKRpB5Gelxuj..."],

  "data" : {"name":"james.. "

               ,"nation":"korea"

              ,"age":"18"

   },

}

6.실행 결과..




아래의 REGID로 서버에서 호출 해줘야 클라이언트에 메세지를 전달 할 수있습니다.




336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

 IOS Simulator에서 카메라가 지원되지 않는다. 그래서 사진 점부 테스트를 하려면 사진을 사진을 IOS Simulator에 넣어야 하는데 방법을 몰라 삽질을 했는데 알고보니 간단합니다.

1. IOS Simulator에서 Safari or App을 실행합니다.




2. Finder에서 이미지를 선택 후 클릭하여 Safari 브라우져로 드래그앤 드랍으로 추가 합니다.


3. Save To Camera Roll 을 클릭하여 저장합니다

 4. App을 클릭하여 테스트 합니다.

5. 이미지 첨부를 클릭함.




336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

PhoneGap(cordova) API를 이용하여 하드웨어에 접근하는 방법에 대하여 설명하겠습니다.

우선 하드웨어에 접근하려면 plugin을 설치 해야 합니다.

설치 방법은 2가지 방법이 있는데 

첫쨰 cordova를 이용하여 설치하는 방법

둘쨰 node.js설치 후 plugman을 이용하여 설치 하는 방법이있습니다.


여기서는 cordova을 이용하여 plugin을 설치 하겠습니다.

1. 만들 프로젝트 폴더로 이동합니다.

  cordova create MyFunkyApp

cd MyFunkyApp

cordova platform add ios

cordova emulate ios

이렇게 App을 만들었다면 MyFunkyApp 폴더로 이동합니다

$ cordova plugin add https://git-wip-us.apache.org/repos/asf/cordova-plugin-camera.git 을 실행하여 plugin을 설치 합니다.

[Error: Error fetching plugin: Error: "git" command line tool is not installed: make sure it is accessible on your PATH.]

이렇게 메세지가 나온다면 git가 설치가 되지 않아서 보여지는 에러니 

https://help.github.com/articles/set-up-git에서 다운받아 설치 합니다.



이제 

cordova plugin add https://git-wip-us.apache.org/repos/asf/cordova-plugin-camera.git

다시 실행합니다.

정상적으로 실행 되었다면 ios>config.xml파일을 열어

    <feature name="Camera">

        <param name="ios-package" value="CDVCamera" />

    </feature>

카메라 관련 설정이 추가되어있는지 확인합니다.

마찬가지로 안드로이드도 프로젝트>/res/xml/config.xml에 

    <feature name="Camera">

        <param name="android-package" value="org.apache.cordova.camera.CameraLauncher" />

    </feature>

가 추가 되어있는것을 확인 할 수 있습니다.

API plugin URL

cordova-plugin-battery-status   https://git-wip-us.apache.org/repos/asf/cordova-plugin-battery-status.git

cordova-plugin-camera   https://git-wip-us.apache.org/repos/asf/cordova-plugin-camera.git

cordova-plugin-console   https://git-wip-us.apache.org/repos/asf/cordova-plugin-console.git

cordova-plugin-contacts   https://git-wip-us.apache.org/repos/asf/cordova-plugin-contacts.git

cordova-plugin-device   https://git-wip-us.apache.org/repos/asf/cordova-plugin-device.git

cordova-plugin-device-motion (accelerometer)   https://git-wip-us.apache.org/repos/asf/cordova-plugin-device-motion.git

cordova-plugin-device-orientation (compass)   https://git-wip-us.apache.org/repos/asf/cordova-plugin-device-orientation.git

cordova-plugin-dialogs   https://git-wip-us.apache.org/repos/asf/cordova-plugin-dialogs.git

cordova-plugin-file   https://git-wip-us.apache.org/repos/asf/cordova-plugin-file.git

cordova-plugin-file-transfer   https://git-wip-us.apache.org/repos/asf/cordova-plugin-file-transfer.git

cordova-plugin-geolocation   https://git-wip-us.apache.org/repos/asf/cordova-plugin-geolocation.git

cordova-plugin-globalization   https://git-wip-us.apache.org/repos/asf/cordova-plugin-globalization.git

cordova-plugin-inappbrowser   https://git-wip-us.apache.org/repos/asf/cordova-plugin-inappbrowser.git

cordova-plugin-media   https://git-wip-us.apache.org/repos/asf/cordova-plugin-media.git

cordova-plugin-media-capture   https://git-wip-us.apache.org/repos/asf/cordova-plugin-media-capture.git

cordova-plugin-network-information   https://git-wip-us.apache.org/repos/asf/cordova-plugin-network-information.git

cordova-plugin-splashscreen   https://git-wip-us.apache.org/repos/asf/cordova-plugin-splashscreen.git

cordova-plugin-vibration   https://git-wip-us.apache.org/repos/asf/cordova-plugin-vibration.git


이제 추가 했으니 카메라 API sample을 작성해봅시다.

<!DOCTYPE html>
<html>
  <head>
    <title>Capture Photo</title>

    <script type="text/javascript" charset="utf-8" src="cordova.js"></script>
    <script type="text/javascript" charset="utf-8">

    var pictureSource;   // picture source
    var destinationType; // sets the format of returned value

    // Wait for device API libraries to load
    //
    document.addEventListener("deviceready",onDeviceReady,false);

    // device APIs are available
    //
    function onDeviceReady() {
        pictureSource=navigator.camera.PictureSourceType;
        destinationType=navigator.camera.DestinationType;
    }

    // Called when a photo is successfully retrieved
    //
    function onPhotoDataSuccess(imageData) {
      // Uncomment to view the base64-encoded image data
      // console.log(imageData);

      // Get image handle
      //
      var smallImage = document.getElementById('smallImage');

      // Unhide image elements
      //
      smallImage.style.display = 'block';

      // Show the captured photo
      // The inline CSS rules are used to resize the image
      //
      smallImage.src = "https://t1.daumcdn.net/cfile/tistory/233A9D3A56EB11EE2E" + imageData;
    }

    // Called when a photo is successfully retrieved
    //
    function onPhotoURISuccess(imageURI) {
      // Uncomment to view the image file URI
      // console.log(imageURI);

      // Get image handle
      //
      var largeImage = document.getElementById('largeImage');

      // Unhide image elements
      //
      largeImage.style.display = 'block';

      // Show the captured photo
      // The inline CSS rules are used to resize the image
      //
      largeImage.src = imageURI;
    }

    // A button will call this function
    //
    function capturePhoto() {
      // Take picture using device camera and retrieve image as base64-encoded string
      navigator.camera.getPicture(onPhotoDataSuccess, onFail, { quality: 50,
        destinationType: destinationType.DATA_URL });
    }

    // A button will call this function
    //
    function capturePhotoEdit() {
      // Take picture using device camera, allow edit, and retrieve image as base64-encoded string
      navigator.camera.getPicture(onPhotoDataSuccess, onFail, { quality: 20, allowEdit: true,
        destinationType: destinationType.DATA_URL });
    }

    // A button will call this function
    //
    function getPhoto(source) {
      // Retrieve image file location from specified source
      navigator.camera.getPicture(onPhotoURISuccess, onFail, { quality: 50,
        destinationType: destinationType.FILE_URI,
        sourceType: source });
    }

    // Called if something bad happens.
    //
    function onFail(message) {
      alert('Failed because: ' + message);
    }

    </script>
  </head>
  <body>
    <button onclick="capturePhoto();">Capture Photo</button> <br>
    <button onclick="capturePhotoEdit();">Capture Editable Photo</button> <br>
    <button onclick="getPhoto(pictureSource.PHOTOLIBRARY);">From Photo Library</button><br>
    <button onclick="getPhoto(pictureSource.SAVEDPHOTOALBUM);">From Photo Album</button><br>
    <img style="display:none;width:60px;height:60px;" id="smallImage" src="" />
    <img style="display:none;" id="largeImage" src="" />
  </body>
</html>

안드로이드 프로젝트에서 카메라 기능을 on시키고 확인하면 잘 동작 하는것을 확인 할 수 있습니다.

참고  URL

336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

첫 하이브리드 앱(Ajax JSONP을 이용한 비동기 서버 호출)


Mac 환경설정 > Mac cordova설치 및 Eclipse 연동에서 작성한 helloworld  Project를 이용하여 로그인 페이지를 작성하겠습니다.

흐름은 아래 그림과 같으며 서버는 로컬에서 Eclipse로 구동하여 테스트 했습니다.

소스코드는 cordova3.0.5을 이용하여 생성했습니다.

Project Folder

Xcode


안드로이드(Eclipse)



1.login.html페이지 작성.

  화면

소스코드

<!doctype html>

<html>

    <head>

        <meta charset="UTF-8">

            <title>Untitled Document</title>

            <link rel="stylesheet" href="./css/jquery.mobile-1.3.2.min.css" />

            <script src="./js/jquery-1.9.1.js"></script>

            <script src="./js/jquery.mobile-1.3.2.js"></script>

            <script src="./js/common.js"></script>

            <script type="text/javascript">

                $(document).on( 'click', '#checkLogin', function(){

                               checkLogin($('#name').val(),$('#password').val());

                               });

                function checkLogin(id,pass) {

                    var params = {ID:id

                        ,PASS:pass

                        ,AUTOLOGIN:'N'

                    };

                    $.ajax({

                           type: 'GET',

                           url: "http://172.16.1.50:8080/myweb/cb.jsp",

                           data : params,

                           contentType: "Content-Type: application/javascript",

                           dataType: "jsonp",

                           jsonp : "callback",

                           jsonpCallback: "jsonpCallback",


                           error: function (xhr, ajaxOptions, thrownError) {

                           alert("Error: " + xhr.status + "\n" +

                                 "Message: " + xhr.statusText + "\n" +

                                 "Response: " + xhr.responseText + "\n" + thrownError);

                           }

                           });

                }

                function jsonpCallback(data){

                   // alert('jsonpCallback1:___'+JSON.stringify(data));

                    if(data.RESULT=='2'){

                        $.mobile.changePage('./main.html');

                    }else{

                        alert('not user... please retry..');

                    }

                }

                </script>

    </head>

    <body>

        <div id="test-page" data-role="page">

            <div data-role="header">

                <h1><a data-ajax="false" href="/">Login</a></h1>

            </div>

            <div data-role="content">

                <div data-role="fieldcontain">

                    <label for="name">Name:</label>

                    <input id="name" type="email" name="name" />

                </div>

                <div data-role="fieldcontain">

                    <label for="password">Password:</label>

                    <input id="password" type="password" name="password" />

                </div>

            </div>

            <button type="button" id="checkLogin" name="checkLogin" >LOGIN</button>

        </div>

    </body>

</html>



2.main.html 페이지 작성.

<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8">

<title>Insert title here</title>

</head>

<body>

Main page....

</body>

</html>


3.Server Module 작성 

Menu Bar > File > New > Dynamic Web Project 을 선택하여 새로운 web프로젝트를 생성합니다.

그리고 WebContent하위에 cb.jsp파일을 생성하고 아래와 같이코딩을 합니다.

 <%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%>

<%

String cb = request.getParameter("callback");

String id = request.getParameter("ID");

String pass = request.getParameter("PASS");

String auto = request.getParameter("AUTOLOGIN");


/*

login check..

   if login OK return '2' 

   else '1'

*/


String result = "2";


%>

<%=cb %>({'RESULT':'<%=result %>'})



마지막으로config.xml의 access 설정을 변경합니다.

 프로젝트의 config.xml을 열어서 <access origin="172.0.0.1*" />이부분을 

<access origin="*" />로 변경하여 모든 접속을 허용하도록 합니다.

위치는 Xcode는 프로젝트/config.xml(프로젝트/www/config.xml이 아님)

 android Eclipse는 프로젝트/res/xml/config.xml 찾아서

을 변경합니다.


이제 Xcode에서 프로젝트 실행을 클릭하고 로그인하여 정상적으로 되는지 확인하자


 



이렇게 메인 페이지까지 나오면 정상적으로 된것이다 .. 

이제 안드로이드도 확인을 해봅시다.

프로젝트 > Debug As > Android Application을 선택 합니다.

테스용디바이스를 선택 합니다.

이미 구동중인 device가 있으면 아래와 같이 화면에 보이고 아니면 아래의 "Launch a new Android Virtual Device"에서 선택하여 실행합니다.





안드로이드도 정상적으로 로그인되는것을 확인 합니다.



  

336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

cordova설치 및 Eclipse 연동

nodejs가 되어 있지 않다면 http://nodejs.org/download/에 접속하여 다운로드 설치 합니다.


http://phonegap.com/install/ 사이트에 접속면 접속 화면이 설치 화면이 나온다

그런데.. phonegap을 설치하고 

$ phoegap create myApp 

$ cd myApp

$ phonegap run android

이렇게 하면 완성된 화면의 배포를 만드는것같다 .. (?? )

그래서 phonegap을 삭제하고  cordova를 설치 했다.

hponegap  삭제

/usr/local/lib/node_modules>sudo npm uninstall phonegap


$>sudo npm install -g cordova 로 설치를 한다. 

설치 후 sample 프로그램을 만들보자 

cordova create hello com.example.hello Helloworld

실행 후" -bash: /usr/local/bin/cordova: No such file or directory"의 에러 메세지가 

발생한다 .. 이 에러는 "https://issues.apache.org/jira/browse/CB-4686"의 이슈에 등록 되어있다 ..

그래서 현재 버젼을 지우고 이전 버전을 설치 합니다.

/usr/local/lib/node_modules>sudo npm uninstall cordova

/usr/local/lib/node_modules>sudo npm install -g cordova@3.0.6

 설치 후 sample 프로젝트 생성

my_java_source>cordova create hello com.example.hello Helloworld

cd hello

cordova platform add ios

cordova platform add android

혹 "cordova platform add android"를 실행했을때 

"[Error: Please install Android target 17 (the Android 4.2 SDK). Make sure you have the latest Android tools installed as well. Run `android` from your command-line to install/update any missing SDKs or tools.]" 이런메세지가 나오면

$ android 를 실행하여 android 버젼을 추가 합니다


이제 Eclipse를 실행하여 생성한 프로젝트를 안드로이드 폰에서 확인 하도록 하겠습니다.

Eclipse 실행

Menu Bar에서 File > New > Others.. 선택 합니다.

Android > Android Project from Existing Code를 선택 실행합니다.

 

좀전에 생성한 myApps > platform > android 를 선택합니다.


이제 프로젝트를 실행하여 안드로드폰으로 확인 하도록 하겠습니다.

프로젝트 > 오른쪽마우스(control + 마우스클릭)을 해서 Run as > Android Application을 선택 합니다.

Android Device Chooser에서 Mac Book연결된 안드로이드폰을 선택하고 OK를클릭합니다.

핸드폰에 index.html의 내용이 표시되는 것을 확인 합니다.

그림 밑에 "ANDROID PHONEGAP  테스트 입니다"라고 MyApps > Assets > index.html의 내용이 표시됩니다. 

핸드폰으로 바로 연결


Virtual Device로 연결

가상의 디바이스로 연결하려면 Launch new Android Virtual Device에서 선택 후 실행하면

Virtual Device로 선택되어 실행되고 다시 실행할때는 아래와 같이 선택할 수 있도록 보입니다. 





자 이제 본격적으로 하이브리드 앱을 개발해볼까요 ..