------

[ AD ] Port Monitor ( Try to use a Best WebSite Monitoring Tool )

------
이용약관

독소조항 - 콘텐츠 생산자 저작권

“귀하는 트위터 본사에 트위터 콘텐츠를 다른 미디어 및 서비스상에서 신디케이션, 방송, 배포 또는 출판하기 위해
트위터와 협력하는 다른 기업, 조직 또는 개인에게 해당 콘텐츠를 제공할 수 있는 권리를 부여한다”


독소조항 - 사용료

“귀하에게 사용료를 지불하지 않고 트위터 또는 트위터와 협력하는 다른 기업, 조직 또는 개인은
귀하가 서비스를 통해 제출, 게시, 전송 또는 기타 다른 방식으로 제공한 콘텐츠를 사용할 수 있다”

[반면에 트위터는]
트위터는 구글에게 데이터베이스를 공개하는 조건으로 거액을 받는다....


<참조>
MeToday -

“회원의 게시물은 검색결과나 관련 프로모션 등에 노출될 수 있지만 회사는 저작권법 규정을 준수하며,
회원은 언제든지 고객센터 또는 서비스 내 관리기능을 통해 해당 게시물에 대해 삭제, 검색결과 제외,
비공개 등의 조치를 취할 수 있다”

CyWorld -
“회원의 개별 동의 없이 회원의 게시물 및 정보를 미디어, 통신사 등에 제공하지 않는다”
“회사가 회원의 게시물을 영리 목적으로 제공할 경우 회원에게 사전 동의를 얻어야 함은 물론이고 회원에게 별도의 보상을 제공한다”



http://ipodart.net/573


아이폰 유닛과 SRPG 방식의 조화 Rebirth of Fortune[리뷰와 리딤코드 이벤트 종료]



 

개성있는 유닛과 SRPG 게임 방식의 조화 리버스 오브 포춘 - Rebirth of Fortune K

'온라인게임' 카테고리의 다른 글

SNS Privacy 비교  (0) 2010.10.27
트위터 이용약관  (0) 2010.10.27
슬펐던 일이...기쁨을 안기네..용  (0) 2010.10.26
안드로이드 갤럭시 s  (0) 2010.10.26
UX  (0) 2010.10.25

이승기의 날개 벽화가 새 둥지를 찾았다.

'1박2일'에서 이승기가 기념 촬영을 했던 날개 벽화가 유명세를 타면서 일부 몰지각한 시민들의 추태로 인해 지워졌다.

이러한 날개 벽화가 다시 새둥지에 정착하게 됐다.


날개 벽화를 그린 김주희씨는 왕십리 광장에서 11월 첫째 주부터 날개 벽화를 그리게 될 것이며 구청의 허가를 받았다는 소식을 전했다.

김씨는 "왕십리 광장은 지하철 2호선과 5호선이 있는 왕십리역에서 나오면 바로 보이는 곳으로 분수대 근처"라고 장소에 대해 설명하며 광장 내 어느 자리에 그림이 그려지게 될지 확정되지 않았다고 전했다.

이어 김씨는 "단순히 다양한 이야기를 하고 싶었다"며 "왕십리 광장이라는 새로운 공간에 맞는 새로운 날개를 그려보고 싶다. '빛과 어둠'이라는 콘셉트로 어둠은 검은색의 느낌을 주는 어둠이 아니라 다양한 색으로 명암을 표현하게 될 것"이라고 이번 날개 그림에 대한 해석까지 덧붙였다.



<김한수 기자> 취재요청 및 보도자료 mailto@vop.co.kr
저작권자© 한국의 대표 진보언론 민중의소리
화면 복구 하기 ..

[키 작동 ]

Home Key  - 홈 바탕화면으로 ::

Home Key LongPress - 작업 관리자 화면으로 ::

Hold Key - 슬립 화면으로 ::

Hold Key LongPress - 시스템 메뉴 화면으로 ::


[이벤트]

onPause() - 복구할 값 저장

onResume() - 복구할 값 읽기

onWindowFocusChanged() - 토글 값 설정 / on-저장 / off -읽기




커피 프림 성분


1. 프림의 주성분


1)식물성 유지

-야자나무의 열매에서 얻은 야자유(팜유)가 주로 사용되며 콜레스테롤이 거의 없으며(?) 맛이 고소하고 단백합니다.

2)우유

-우유에서 추출한 카제인 단백질을 사용하며 우유단백질중 가장 품질이 우수하고 소화가 잘되어 

분유및 이유식에도 많이 사용되고 있습니다

3)전당분 

-옥수수 가루를 효소처리하여 제조한 것 으로 단맛을 내고 혼합을 도와 줍니다.


2. 프림의 열량

1) 프림의 열량

-시중에 판매 되는 보통의 프림 제품의 열량은 1g당 약 6칼로리 정도 이며,

이는 한잔 5g 정도사용을 기준으로 할 때 커피 한잔에 들어 있는 프림의 열량은 30 칼로리 정도로 본다

2) 열량 비교

-포도 한송이 140kal,멜론 한개 300kal,바나나 한개 100kal,콩밥 254kcal,

백미 300kcal등과 비교해 볼때 그리 높은 열량은 아닌 것 으로 판단 되어 집니다.


3. 팜유란?

1) 원재료에 포함된 포화지방산

-프림의 원료인 팜유는 오일 팜이라는 열매에서 나오는 기름인데요, 

이게 출신성분은 "식물성"이지만 내용을 분석해보면 우지나 돈지와 비교해도 손색이 없을만큼 포화지방산이 많습니다. 

프림은 포화지방산으로서 혈중 콜레스테롤을 높이는 주범이 되므로 성인병을 예방할 때 가장 먼저 제한해야 합니다.


2) 관련 속설

-우스개 소리로 커피한잔속에 프림을 다 연소 시키려면 지구 한바퀴인지 몇바퀴인지? 그런말도 있었어요.


4. 트랜스지방 vs 포화지방


1) 트랜스 지방의 피해

-콜레스테롤과 관련한 트랜스지방의 악영향은 포화지방의 2배에 이른다고 합니다.. 

트랜스지방이 피 속의 나쁜 콜레스테롤을 증가시킬 뿐 아니라 혈관을 깨끗이 청소하는 

좋은 콜레스테롤을 감소시켜 혈관을 굳게 하고 좁게 만들기 때문이죠.

-현대문명이 만들어낸 트랜스지방산은 일단 한번 먹으면 몸밖으로 배출이 되지 않는다고 합니다. 

교묘하게 위장한 트랜스지방산을 우리 몸이 잘 구별해 내지 못하기 때문이죠. 


2) 자연 상태의 지방산의 비교

-자연 형태의 지방산은 굽은 편자 모양으로 외부의 침입자를 선택적으로 투과하도록 생겼지만

트랜스지방산은 곧은 막대기 모양을 하고 있어서 멀쩡한 영양분은 슬슬 흘려버립니다. 

-게다가 바이러스 같은 엉뚱한 병원균은 쉽게 받아들이죠. 이같은 현상은 세포의 자동조절력을 

잃어버리게 하고 곧바로 ‘면역력 저하’로 이어지게 합니다.

'People in' 카테고리의 다른 글

경로 의존 법칙  (0) 2010.11.16
가사 : 언제나 ~ 허각  (0) 2010.11.12
와이브로 wibro  (0) 2010.10.11
제작 엔터테인먼트  (0) 2010.10.11
3G망과 WiFi(와이파이), 와이브로 비교  (0) 2010.10.07
UX user experience

-interaction
 : 사용자가 시스템과 상호 반응 
-communication
 : 사용자가 시스템과 소통
-process
-response
-method

UI는 보이는 것을 디자인 하지만, UX는 보이지 않는 것을 디자인 한다.


* 수도꼭지에서 물을 나오게 하는 방법
물의 양을 조절하는 절차
물의 온도에 따른 적절한 경고 메시지
 :이것들이  UX의 인터렉션/커뮤니케이션/프로세스/리스판스/메쏘드의 하나다.

프롤로그 설득 심리학으로의 초대
필요없는 물건을 사게 되는 이유
무의식적인 의사결정의 장단점
의사결정 원리를 악용하는 불로소득자들
인간심리를 공략하는 '허허실실법'

설득의 법칙 1 상호성의 법칙
상호성의 비밀
상호성의 속임수
상호성을 이용한 일보 후퇴, 이보 전진 전략
상호성의 법칙에 대항하는 자기 방어 전략

설득의 법칙 2 일관성의 법칙
기계화된 일관성의 함정
개입과 일관성의 심리전
작은 약속부터 시작하는 문전 걸치기 기법
미군 조종에 성공한 중공군의 세뇌 프로그램
자녀교육시 해야 할 일과 해서는 안될 일
일관성의 근거를 만드는 미끼 기법
일관성의 법칙에 대항하는 자기 방어 전략

설득의 법칙 3 사회적 증거의 법칙
코미디 프로그램에서 가짜 웃음을 들려주는 이유
사이비 종교에 빠지는 이유
'다수의 무지'가 불러온 길거리 살인사건
유사성의 영향력
사회적 증거의 법칙에 대항하는 자기 방어 전략

설득의 법칙 4 호감의 법칙
호감의 법칙을 이용한 판매전략
호감의 원천
호감의 법칙을 활용한 집단간의 갈등 극복
연상 작용의 엇갈리는 명암
호감의 법칙에 대항하는 자기 방어 전략

설득의 법칙 5 권위의 법칙
밀그럼의 실험 : 권위에 대한 맹종
아브라함은 왜 아들을 죽이려 했는가
권위의 상징물들
권위의 법칙에 대항하는 자기 방어 전략

설득의 법칙 6 희귀성의 법칙
희귀성의 가치
상실에 대한 두려움
로미오와 줄리엣 효과
희귀성의 영향력을 강화시키는 조건
희귀성의 법칙에 대항하는 자기 방어 전략

에필로그 - 정보화 시대의 설득 전략
원시 시대의 의사결정
정보화 시대의 의사결정
의사결정의 지름길 법칙을 사수하라

'온라인게임' 카테고리의 다른 글

안드로이드 갤럭시 s  (0) 2010.10.26
UX  (0) 2010.10.25
Querying the contact database / Retrieving Contact Details  (0) 2010.10.25
[스크립트] Flash Socket을 이용한 채팅프로그램  (0) 2010.10.25
진저브레드  (0) 2010.10.25

Querying the contact database

Retrieving Contact Details



public class TestContacts extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        ContentResolver cr = getContentResolver();
        Cursor cur = cr.query(People.CONTENT_URI,
null, null, null, null);
        if (cur.getCount() > 0) {
     while (cur.moveToNext()) {
         String id = cur.getString(cur.getColumnIndex(People._ID));
         String name = cur.getString(cur.getColumnIndex(People.DISPLAY_NAME));
     }
        }
    }
}


주소록 Contacts - 바뀐 변수명들
 2.0이상 버전에선 ContactsContract를 통해 주소록의 데이터에 접근할 수 있다.

예전에는 People.Number 이라던가 People.Name이 사용되었지만 현재는 바뀌었다. 그리고 웹상에서는
바뀐 버전에 대해 괜찮은 소스를 찾아보기가 힘들어서 이렇게 기록을 해둔다.

안드로이드 SDK 예제 소스(ContactManager) 중 일부를 참고하였다.

name            =  ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME
phone           =  ContactsContract.CommonDataKinds.Phone.NUMBER
phoneType   =  ContactsContract.CommonDataKinds.Phone.TYPE
email            =  ContactsContract.CommonDataKinds.Email.DATA
emailType    =  ContactsContract.CommonDataKinds.Email.TYPE


 

// Prepare contact creation request
        //
        // Note: We use RawContacts because this data must be associated with a particular account.
        //       The system will aggregate this with any other data for this contact and create a
        //       coresponding entry in the ContactsContract.Contacts provider for us.

        ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
        ops.add(ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)
                .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, mSelectedAccount.getType())
                .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, mSelectedAccount.getName())
                .build());
        ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
                .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
                .withValue(ContactsContract.Data.MIMETYPE,
                        ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
                .withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, name)
                .build());
        ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
                .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
                .withValue(ContactsContract.Data.MIMETYPE,
                        ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
                .withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, phone)
                .withValue(ContactsContract.CommonDataKinds.Phone.TYPE, phoneType)
                .build());
        ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
                .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
                .withValue(ContactsContract.Data.MIMETYPE,
                        ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE)
                .withValue(ContactsContract.CommonDataKinds.Email.DATA, email)
                .withValue(ContactsContract.CommonDataKinds.Email.TYPE, emailType)
                .build());





Retrieving Contact Image of Specific Contact

Postby Valay » Tue Aug 24, 2010 1:06 am

I was working on How to retrieve contact Image from the contact book. I searched a lot on Internet and many forums. But the solution I got was for Android 1.6 which has people class which is totally different from Android 2.1 ContactContract Class.

So Looked into the detail of contact contract class and found out solution. 


public class ContactInfo {

   private static Activity MAIN_ACTIVITY;
        public ContactInfo(Activity activity){
           MAIN_ACTIVITY=activity;
        }

   protected InputStream openPhoto(long contactId) {
      Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI,
            contactId);
      Uri photoUri = Uri.withAppendedPath(contactUri,
            Contacts.Photo.CONTENT_DIRECTORY);
      Cursor cursor = MAIN_ACTIVITY.getContentResolver().query(photoUri,
            new String[]{Contacts.Photo.DATA15}, null, null, null);
      if (cursor == null) {
         return null;
      }
      try {
         if (cursor.moveToFirst()) {
            byte[] data = cursor.getBlob(0);
            if (data != null) {
               return new ByteArrayInputStream(data);
            }
         }
      } catch (Exception e) {
         e.printStackTrace();
      } finally {
         cursor.close();
      }
      return null;
   }
       
   public Bitmap getImage(long contactId) {
      InputStream stream = openPhoto(contactId);
      return stream != null
            ? BitmapFactory.decodeStream(stream, null, null)
            : null;

   }


Here in this code just call the getImage Function to your ImageView. I mean ImageView.setImageBitmap(contactInfo.getImage(contactId));

This will solve your problem.

Let me know if there is any problem with my code.

 

'온라인게임' 카테고리의 다른 글

UX  (0) 2010.10.25
설득의 심리학 - 6가지 불변의 법칙  (0) 2010.10.25
[스크립트] Flash Socket을 이용한 채팅프로그램  (0) 2010.10.25
진저브레드  (0) 2010.10.25
달라진 아이폰 앱 개발자 정책  (0) 2010.10.25

[스크립트] Flash Socket을 이용한 채팅프로그램

웹상에서 채팅 프로그램을 구현할 때 가장 힘든 부분이 바로  
HTTP 프로토콜이 접속이 바로 끊기고 상태를 저장하지 않는 접속을 이용한다는 점입니다.  
즉, 소켓 프로그래밍에서 접속을 열고 닫고 하는것이 굉장히 운영체제 차원에서는 비싼 작업인 반면  
이미 열려진 소켓에서 몇바이트 쯤 더 쓰는 것은 속도나 성능 면에서 전혀 문제가 되지 않는다는 것이죠  
(요즘은 인터넷이 빨라서 초당 몇MB씩도 쓰고 하잖아요. 하지만 접속을 여는 데에는 여전히 시간이 걸리죠.)  
그러나 Flash Action Script에서 지원하는 Socket 클래스를 이용하면 자신이 다운로드된 서버와  
접속이 유지된 통신을할 수 있습니다.  
본 프로그램에서는 이점을 이용하여 클라이언트로는 Flash와 자바스크립트를 이용하고  
서버로는 C++로 자체 제작한 서버 프로그램을 이용하여 채팅방을 구현하였습니다.  
본 예제는 Flash Player 9.0을 필요로 하며 Internet Explorer와 Firefox에서 동작합니다.  
먼저 demo 페이지를 보시겠습니다.  
<a href="http://astronote.org/" target=_blank>http://astronote.org/</a>  
마우스 드래그를 통한 창이동, 창 최소화, 창 숨기기 기능을 지원합니다.  
서버 프로그램  
서버 프로그램은 리눅스상에서 c++을 이용하여 개발하였으며 g++을 이용하여 컴파일 하였습니다.  
저는 astronote.org 서버를 집에서 dyndns와 인터넷 공유기의 port mapping을 이용하여 돌리고 있습니다.  
그렇기 때문에 집에서 원하는 포트에 서버를 실행시킬 수 있지만  
웹호스팅 받으시는 분들은 서버상에서 프로그램을 실행시킬 수 없다면 본 예제를 적용할 수 없습니다. 참고하세요.  
일단 서버 소스코드를 올려드리겠습니다.  
#include <sys/types.h>  
#include <sys/stat.h>  
#include <sys/socket.h>  
#include <signal.h>  
#include <unistd.h>  
#include <netinet/in.h>  
#include <arpa/inet.h>  
#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>  
#include <pthread.h>  
#include <stdlib.h>  
#include <vector>  
#include <string>  
using namespace std;  
// 접속된 클라이언트 IP를 저장하기 위한 전역 변수  
struct client  
 
string ip;  
int fd;  
};  
class Error {}; // 에러 처리를 위한 Dummy 객체  
vector<client> clients;  
void *thread_comm(void *);  
int load_address();  
int main(int argc, char **argv)  
 
    if (argc != 2)  
    {  
        printf("Usage : ./server [port]\n");  
        exit(0);  
    }  
    // socket -> bind -> listen 순서로  
    // 듣기 소켓 생성  
    int server_sockfd;  
    if ((server_sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)  
    {  
        perror("socket error");  
        exit(0);  
    }  
    int val = 1;     
    if (setsockopt(server_sockfd, SOL_SOCKET, SO_REUSEADDR, (char *) &val, sizeof val) < 0)  
 
  perror("setsockopt");  
  close(server_sockfd);  
  exit(0);  
    }  
struct sockaddr_in serveraddr;  
bzero(&serveraddr, sizeof(serveraddr));  
    serveraddr.sin_family = AF_INET;  
    serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);  
    serveraddr.sin_port = htons(atoi(argv[1]));  
    if (bind(server_sockfd, (struct sockaddr*)&serveraddr, sizeof(serveraddr)) == -1)  
    {  
        perror("bind error");  
        exit(0);         
    }  
printf("접속을 기다리고 있습니다.\n");  
if (listen(server_sockfd, 5) == -1)  
    {  
        perror("bind error");  
        exit(0);     
    }  
    while(1)  
    {  
        // 만약 듣기 소켓에 연결이 들어온다면  
        // 새로운 쓰레드를 생성시킨다.  
        // 새로운 쓰레드 생성시 클라이언트 소켓을 쓰레드  
        // 인자로 넘겨서 쓰레드와 클라이언트가 통신하도록 한다.   
    struct sockaddr_in clientaddr;  
  int client_len;  
  int client_sockfd;  
  try  
  {  
  client_sockfd = accept(server_sockfd, (struct sockaddr*)&clientaddr, (socklen_t*)&client_len);  
  client cl;  
  cl.ip = inet_ntoa(clientaddr.sin_addr);  
  cl.fd = client_sockfd;  
  clients.push_back(cl);  
  pthread_t p_thread;  
  if (pthread_create(&p_thread, NULL, thread_comm, (void *)client_sockfd) == -1)  
  {  
    perror("쓰레드 생성 실패\n");  
    exit(0);  
  }  
  }  
  catch (Error&) {}  
    }  
shutdown(server_sockfd, 2);  
    close(server_sockfd);  
 
// 쓰레드 생성시 넘어온 클라이언트 소켓을 이용해서 클라이언트와 통신한다.  
void *thread_comm(void* data)  
 
    int sockfd = (int)data;  
string ip;  
for(vector<client>::iterator ci = clients.begin(); ci != clients.end(); ci++)  
  if(ci->fd == sockfd)  
  ip = ci->ip;  
printf("%s 에서 접속..\n", ip.c_str());  
printf("현재 접속자수 : %d 명\n", clients.size());  
char buf[1024];  
// 모든 사용자에게 접속을 알림  
sprintf(buf, "%s|connected|%d\n", ip.c_str(), clients.size());  
for(vector<client>::iterator ci = clients.begin(); ci != clients.end(); ci++)  
 
  if(write(ci->fd, buf, strlen(buf)+1) == -1)  
  printf("%s 에서 쓰기 에러\n", ip.c_str());  
 
char c;  
string line;  
try  
 
  while(read(sockfd, &c, 1) > 0)  
  {  
  line += c;  
  if (c == '\n')  
  {  
    line = ip + "|" + line;  
    for(vector<client>::iterator ci = clients.begin(); ci != clients.end(); ci++)  
    {  
    if(write(ci->fd, line.c_str(), line.length()+1) == -1)  
    {  
      printf("%s 에서 쓰기 에러\n", ip.c_str());  
      break;  
    }  
    }  
    line.clear();  
  }  
  }  
 
catch (Error&) {}  
shutdown(sockfd, 2);  
close(sockfd);  
printf("%s 에서 접속 종료\n", ip.c_str());  
// 벡터에서 삭제한다.  
for(vector<client>::iterator ci = clients.begin(); ci != clients.end(); ci++)  
  if(ci->fd == sockfd)  
  {  
  clients.erase(ci,ci+1);  
  break;  
  }  
try  
 
  // 자기 자신을 제외한 모든 사용자에게 끊김을 알림  
  sprintf(buf, "%s|disconnected|%d\n", ip.c_str(), clients.size());  
  for(vector<client>::iterator ci = clients.begin(); ci != clients.end(); ci++)  
  {  
  if(write(ci->fd, buf, strlen(buf)+1) == -1)  
    printf("%s 에서 쓰기 에러\n", ip.c_str());  
  }  
 
catch (Error&) {}  
printf("현재 접속자수 : %d 명\n", clients.size());  
return (void *)NULL;  
 
서버프로그램은 보시다시피 간단합니다.  
클라이언트측에서 보내주는대로 자신을 포함한 모든 클라이언트에서 broadcasting 해 주는 것 밖에는 특별한 기능이 없습니다.  
소스코드를 업로드하시고 컴파일합니다.  
$ g++ -o chat-server -lpthread server.cpp  
그런 다음 chat-server에 실행옵션 주고 실행합니다. 파라미터로 포트번호를 넘깁니다.  
$ chmod 700 chat-server  
$ ./chat-server 25000 &  
그럼 OK 입니다.  
클라이언트 프로그램  
클라이언트 프로그램은 flash 부분과 javascript 부분으로 나누어집니다.  
먼저 flash를 띄우고 첫번째 프레임에서 F9를 눌러 ActionScript 창을 띄운 후 다음과 같이 입력합니다.  
import flash.external.ExternalInterface;  
import flash.net.Socket;  
var str:String = '';  
var socket:Socket = null;  
socket = new Socket();  
socket.connect('astronote.org',25000); // 이부분은 서버 설정에 맞게 수정하세요.  
socket.addEventListener(ProgressEvent.SOCKET_DATA, socketDataHandler);  
function sendIt(str:String) : void  
 
socket.writeMultiByte(str+'\n', "euc-kr");  
socket.flush();  
 
function socketDataHandler(event:ProgressEvent):void  
 
var str = socket.readMultiByte(socket.bytesAvailable, "euc-kr");  
ExternalInterface.call("received", str);  
 
ExternalInterface.addCallback("sendIt", sendIt);  
내용은 실행될 때 소켓을 열고 자바스크립트 함수에서 호출할 수 있는 sendIt 이라는 메소드를 노출했습니다.  
서버로부터 자료를 받으면 received 라는 자바스크립트 함수를 호출해 줍니다.  
자신의 서버 설정에 맞게 도메인명과 포트번호를 수정합니다.  
저는 웹서버 설정을 euc-kr로 했기 때문에 euc-kr로 했지만 utf-8로 할 수 도 있습니다.  
이제 Shift+F12를 눌러 컴파일합니다.  
이제 자바스크립트 부분입니다.  
먼저 항상 떠 있는 안보이는 frame을 만들어서 chat.htm을 띄워놓습니다. 여기에 flash로 만든 swf 파일을 올립니다.  
<frameset rows='*,0' border=0 frameborder=0>  
<frame name=main src=/home.htm border=0>  
<frame name=sock src=/chat.htm border=0>  
</frameset>  
다음은 chat.htm의 코드입니다.  
<script src="AC_RunActiveContent.js"></script>  
<script>  
if (AC_FL_RunContent == 0)  
 
alert("This page requires AC_RunActiveContent.js.");  
 
else  
 
AC_FL_RunContent('codebase', 'http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0',  
'width', '100',  
'height', '100',  
'src', 'astrowar',  
'quality', 'high',  
'pluginspage', 'http://www.macromedia.com/go/getflashplayer',  
'align', 'middle',  
'play', 'true',  
'loop', 'true',  
'scale', 'showall',  
'wmode', 'window',  
'devicefont', 'false',  
'id', 'astrowar',  
'bgcolor', '#000000',  
'name', 'astrowar',  
'menu', 'true', 'allowFullScreen', 'false', 'allowScriptAccess','always', 'movie', 'astrowar', 'salign', '');  
 
var saved = '';  
var idpool = [];  
var chatnum = 0;  
function findid(ip)  
 
for(var i = 0; i < idpool.length; i++)  
 
  if(idpool[i].ip == ip) return idpool[i].name+"<small>("+idpool[i].id+")</small>";  
 
return ip;  
 
function update_chatnum()  
 
if(parent.main)  
 
  var cn = parent.main.document.getElementById('chatnum');  
  if(cn) cn.innerHTML = '현재 접속자수 '+chatnum+'명';  
 
 
function received(s)  
 
var arr = s.split('|');  
var str = '';  
switch(arr[1])  
 
case 'connected':  
  str = arr[0] + " 접속<br>";  
  chatnum = arr[2];  
  update_chatnum();  
  break;  
case 'login':  
  str = arr[3]+"("+arr[2] + ") 로그인<br>";  
  if(findid(arr[0]) == arr[0] && arr[2] && arr[3]) idpool[idpool.length] = {ip:arr[0],id:arr[2],name:arr[3]};  
  break;  
case 'logout':  
  str = arr[3]+"("+arr[2] + ") 로그아웃<br>";  
  //if(findid(arr[0]) != arr[0] && arr[2] && arr[3]) idpool[idpool.length] = {ip:arr[0],id:arr[2],name:arr[3]};  
  break;  
case 'disconnected':  
  str = findid(arr[0]) + " 접속 종료<br>";  
  chatnum = arr[2];  
  update_chatnum();  
  break;  
case 'chat':  
  var name = arr[3] + "<small>("+arr[2]+")</small>";  
  if(arr[3]=='') name = arr[0];  
  str = "<font color="+arr[5]+">"+name + " : " + arr[4] + "</font><br>";  
  if(findid(arr[0]) == arr[0] && arr[2] && arr[3]) idpool[idpool.length] = {ip:arr[0],id:arr[2],name:arr[3]};  
  break;  
 
if(str)  
 
  saved += str;  
  if(parent.main)  
  if(parent.main.cv)  
  {  
  var p = parent.main.document.createElement('div');  
  p.innerHTML = str;  
  parent.main.cv.appendChild(p);  
  window.setTimeout('parent.main.cv.scrollTop = parent.main.cv.scrollHeight',100);  
  }  
 
 
var hide = false;  
var chat_closed = false;  
var alpha = 100;  
function onalpha(f)  
 
alpha = f.options[f.selectedIndex].value;  
if(parent.main.cr)  
 
  parent.main.cr.style.opacity = alpha/100;  
  parent.main.cr.style.MozOpacity = alpha/100;  
  parent.main.cr.style.KhtmlOpacity = alpha/100;  
  parent.main.cr.style.filter = "alpha(opacity=" + alpha + ")";  
 
 
var col = '#000000';  
function oncolor(f)  
 
col = f.options[f.selectedIndex].value;  
 
function getMovieName(movieName)  
 
if (navigator.appName.indexOf("Microsoft") != -1) return window[movieName];  
else return document[movieName];  
 
var chatx = 0;  
var chaty = 270;  
var sock;  
window.onload = function(){  
sock = getMovieName("astrowar");  
 
</script>  
AC_RunActiveContent.js 파일은 Flash에서 publish 할 때 생성된 것을 변경 없이 그대로 사용하시면 됩니다.  
저는 swf 파일의 이름을 astrowar.swf 로 했습니다. 하지만 다른 이름으로 해도 무방합니다.  
onalpha 함수와 oncolor 함수는 채팅방에서 투명도나 대화색상을 조절하기 위해 사용합니다.  
이제 본 페이지 들어갑니다.  
홈페이지의 모든 페이지에서 load 되는 head.php 등에 아래 코드를 추가하세요.  
<!-- ---------------------------------------------------------------------- -->  
<!-- ------------ 천문노트 채팅방 2007-11-24 오후 11:48 이형철 ------------ -->  
<script>  
var mem_id = '<?=$mem_id?>';  
var mem_name = '<?=$mem_name?>'; // 이 부분만 자신의 설정에 맞게 수정하면 됩니다.  
</script>  
<div id=chatroom style='z-index:100;position:absolute;top:270px;right:30px;width:200px;display:none;'>  
<div id=titlebar style='padding:3px;background:#F6F6F6;width:100%;'>  
<span id=chatnum style="width:130;"> </span>  
<a href=javascript:chat_hide() style=text-decoration:none;>[ _ ]</a> <a href=javascript:chat_close() style=text-decoration:none;>[ X ]</a>  
</div>  
<div id=chatroominner>  
<div id=chatview style="display:block;padding:5px;width:100%;height:170;"> </div>  
<input name=chatcontent id=chatcontent maxlength=95 style=width:100%  style='border:0;background:whitesmoke;' onkeydown='if(event.keyCode==13) chat(this)' value='메세지를 입력하세요.' onblur="if(!this.value) value='메세지를 입력하세 요.';" onfocus="if(this.value=='메세지를 입력하세요.') this.value='';">  
<div style=padding:3px;font-size:10px;>  
투명도 : <select id=selalpha name=selalpha  style=font-size:8px; onchange="parent.sock.onalpha(this);cci.focus();">  
<option value=100>100%</option>  
<option value=90>90%</option>  
<option value=80>80%</option>  
<option value=70>70%</option>  
<option value=60>60%</option>  
<option value=50>50%</option>  
<option value=40>40%</option>  
<option value=30>30%</option>  
<option value=20>20%</option>  
</select>  
색상 :  
<select id=selcolor name=selcolor  style=font-size:10px; style="background-color=000000;color=white;" onchange='parent.sock.oncolor(this);cci.focus();'>  
<option value="#000000" style=background-color=000000>   </option>  
<option value="#00007F" style=background-color=00007F>   </option>  
<option value="#009300" style=background-color=009300>   </option>  
<option value="#FF0000" style=background-color=FF0000>   </option>  
<option value="#7F0000" style=background-color=7F0000>   </option>  
<option value="#9C009C" style=background-color=9C009C>   </option>  
<option value="#D5AAEB" style=background-color=D5AAEB>   </option>  
<option value="#E7E138" style=background-color=E7E138>   </option>  
<option value="#FC7F00" style=background-color=FC7F00>   </option>  
<option value="#AA6600" style=background-color=AA6600>   </option>  
<option value="#00FC00" style=background-color=00FC00>   </option>  
<option value="#009393" style=background-color=009393>   </option>  
<option value="#00FFFF" style=background-color=00FFFF>   </option>  
<option value="#0000FC" style=background-color=0000FC>   </option>  
<option value="#FF00FF" style=background-color=FF00FF>   </option>  
<option value="#7F7F7F" style=background-color=7F7F7F>   </option>  
<option value="#D2D2D2" style=background-color=D2D2D2>   </option>  
</select>  
</div>  
</div>  
</div>  
<script>  
var cr = document.getElementById('chatroom');  
var cri = document.getElementById('chatroominner');  
var crt = document.getElementById('titlebar');  
var cv = document.getElementById('chatview');  
var ca = document.getElementById('selalpha');  
var cc = document.getElementById('selcolor');  
var cci = document.getElementById('chatcontent');  
// autoscroll  
window.setInterval(function()  
 
if(target) return;  
if(cr) cr.style.top = parseInt(parseInt(cr.style.top) + 0.1 * (parseInt(document.body.scrollTop) + parent.sock.chaty - parseInt(cr.style.top)));  
// if(cr) cr.style.top = parseInt(parseInt(cr.style.top) + 0.1 * (parseInt(document.body.scrollTop) + 270 - parseInt(cr.style.top)));  
},10);  
function chat_close()  
 
parent.sock.chat_closed = !parent.sock.chat_closed;  
if(parent.sock.chat_closed)  
 
  cr.style.display = 'none';  
 
else  
 
  cr.style.display = 'block';  
 
window.setTimeout('cv.scrollTop = cv.scrollHeight;',100);  
 
function chat_hide()  
 
parent.sock.hide = !parent.sock.hide;  
if(parent.sock.hide)  
 
  cri.style.display = 'none';  
  cv.style.height=0;  
 
else  
 
  cri.style.display = 'block';  
  cv.style.height = 170;  
 
 
function addOnLoad(func)  
 
var oldonload = window.onload;  
if (typeof window.onload != 'function') {  
  window.onload = func;  
 
else {  
  window.onload = function() {  
  oldonload();  
  func();  
  }  
 
 
function chat(f)  
 
if(parent.sock)  
if(parent.sock.sock)  
if(parent.sock.sock.sendIt)  
 
  var str = f.value.replace('|','');  
  parent.sock.sock.sendIt('chat|'+mem_id+'|'+mem_name+'|'+str+'|'+parent.sock.col);  
  f.value = '';  
 
 
addOnLoad(function(){  
if(parent.sock)  
 
  // 이미 saved에는 많은 것들이 추가되어있을 것이다.  
  if(parent.sock.saved)  
  {  
  while (cv.hasChildNodes()) cv.removeChild(cv.firstChild);  
  var p = document.createElement('div');  
  p.innerHTML = parent.sock.saved;  
  cv.appendChild(p);  
  window.setTimeout('cv.scrollTop = cv.scrollHeight;',100);  
  }  
  parent.sock.update_chatnum();  
  for(var i = 0; i < ca.options.length; i++)  
  if(ca.options[i].value == parent.sock.alpha) ca.options[i].selected = true;  
  parent.sock.onalpha(ca);  
  for(var i = 0; i < cc.options.length; i++)  
  if(cc.options[i].value == parent.sock.col) cc.options[i].selected = true;  
  parent.sock.oncolor(cc);  
  cv.style.overflow='auto';  
  if(parent.sock.chatx) cr.style.left = parent.sock.chatx;  
  parent.sock.hide = !parent.sock.hide;  
  chat_hide();  
  parent.sock.chat_closed  = !parent.sock.chat_closed;  
  chat_close();  
 
});  
var sMousePos = {x:0,y:0};  
var sTargetPos = {x:0,y:0};  
var target = null;  
function getMousePos(e)  
 
if(e.pageX || e.pageY) return {x : e.pageX, y : e.pageY};  
return {x : e.clientX + document.body.scrollLeft - document.body.clientLeft,  
  y : e.clientY + document.body.scrollTop  - document.body.clientTop};  
 
function getElementPos(e)  
 
var left = 0;  
var top  = 0;  
while (e.offsetParent) {left += e.offsetLeft; top += e.offsetTop; e = e.offsetParent;}  
left += e.offsetLeft;  
top += e.offsetTop;  
return {x:left, y:top};  
 
function inDiv(x, y, div)  
 
var rt = getElementRect(div);  
if(rt.l > x) return false;  
if(x > rt.r) return false;  
if(rt.t > y) return false;  
if(y > rt.b) return false;  
return true;  
 
function getElementRect(e)  
 
var left = 0;  
var top  = 0;  
var e1 = e;  
try  
 
  while (e.offsetParent)  
  {  
  left += e.offsetLeft;  
  top += e.offsetTop;  
  e = e.offsetParent;  
  }  
  left += e.offsetLeft;  
  top += e.offsetTop;  
 
catch(err) {}  
return {l: left, t: top, r: left + e1.offsetWidth, b: top + e1.offsetHeight};  
 
document.onmouseup = function(){  
if(target)  
 
  var pt = getElementPos(target);  
  parent.sock.chaty = pt.y - document.body.scrollTop;  
  parent.sock.chatx = pt.x - document.body.scrollLeft;  
 
target = null;  
};  
document.onmousedown = function(e) {  
e = e || window.event;  
var pt = getMousePos(e);  
var p = e.target || e.srcElement;  
if (inDiv(pt.x, pt.y, crt))  
 
  sMousePos = pt;  
  target = document.getElementById("chatroom");  
  sTargetPos = getElementPos(target);  
 
};  
document.onmousemove = function(e) {  
e = e || window.event;  
var pt = getMousePos(e);  
if (inDiv(pt.x, pt.y, crt))  
 
document.body.style.cursor = 'move';  
 
else  
 
document.body.style.cursor = '';  
 
if(!target) return;  
target.style.left = sTargetPos.x + (pt.x - sMousePos.x);  
target.style.top = sTargetPos.y + (pt.y - sMousePos.y);  
};  
</script>  
<!-- ---------------------------------------------------------------------- -->  
본 예제에서는 채팅방을 구현하였지만 Flash Socket과 서버간의 통신을 구현한 소스 코드는 다른 프로젝트에서도 사용될 수 있을거에요.  
PS. 본 프로그램은 천문노트에서 유환용군과 진행하던 astrowar라는 게임 프로젝트의 부산물입니다.

안드로이드 넥스트 버젼 진저브레드가 공개 될 예정인데,

3.0이 아니라 2.3으로 공개될 소문이 돈다.

3.0->2.3

3.0은 허니콤으로 명명된 듯 하다.

원래 진저브레드는
타블릿에 적합 (2.2 프로요는 타블릿에 적합하지 않다고 발표)
새로운 사용자 인터페이스 - UX를 애플과 경쟁

2010 올해 안에 구글이 공개 한다는 설이 강함.



구글의 모바일 운영체제인 안드로이드 진저브레드(3.0)의 차기버전은 아이스크림(4.0)으로 정해졌다.

16일(현지시각) 미국의 경제지인 포브스는 ARM의 최고경영자인 튜더 브라운과의 인터뷰를 통해 안드로이드 차기버전의 이름은 ‘아이스크림’이 될 것이라고 밝혔다.


구글은 알파벳의 순서대로 간식의 명칭을 따서 안드로이드 버전의 이름을 지어왔는데, 1.5(Cupcake), 1.6(Donut), 2.1(Eclair), 2.2(Froyo), 3.0(Gingerbread), 3.5(Honeycom)의 과정을 거쳐왔으며, 차기 안드로이드 버전은 4.0 아이스크림으로 명명된 것이다.

애시당초 진저브레드의 차기 버전은 허니컴인 것으로 알려졌으나, 허니컴은 진저브레드와 같은 스펙을 가진 태블릿PC용 운영체제로 등장했다.

포브스는 안드로이드 아이스크림의 출시는 내년 하반기에 나올 수 있을 것으로 예상했다. 이니셜 숫자(1.6->2.1, 2.1->3.0)가 바뀌는 기간이 지금까지 약 1년씩 걸린 것으로 볼 때, 이달 중 진저브레드가 출시된다면, 내년 2분기에 열릴 구글 I/O에서 아이스크림을 볼 수 있을 것으로 보인다.

한편, 국내 안드로이드폰의 70%는 아직까지 안드로이드 1.6과 2.1 버전이 탑재돼 있다.


+ Recent posts