">


  페이스북SDK, 카카오톡SDK 등에서 간편 로그인을 등을 사용하기 위해서 반드시 앱에 대한 해시키(Hash key)를 등록해야 합니다. 해시키는 안드로이드 개발 환경에서 가지고 있는 인증서 바이너리에 대한 해시값으로 쉽게 앱 고유의 키 값이라고 생각하면 됩니다. 앱 고유의 값을 사용하기 위해 페이스북이나, 카톡에서 앱의 해시값을 필요로 하는 겁니다. 


  해시키는 개발용 key와 릴리즈용 key로 구분되며 개발용은 개발할 때만 사용하는 키로 본인의 안드로이드 개발 환경에 기본적으로 저장되어 있는 인증서 바이너리에 대한 해시값입니다.

릴리즈용 key는 실제 앱을 배포할 때 사용한 인증서 바이너리에 대한 해시 값입니다. 

카톡이나 페이스북에 사용자 포럼에 가면 배포용은 되는데 릴리즈용은 안된다는 분들이 있습니다. 해시키를 배포용으로 변경하지 않아서 그렇겠죠?


  개발환경이 다른 경우가 많아서 개발 시 해시키를 가져오는 건 코드 상에서 가져오는게 가장 정확한 것 같습니다. 

아래는 그 코드 입니다. 

@Override
 protected void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     setContentView(R.layout.activity_facebook_hash_key);
     try {
            PackageInfo info = getPackageManager().getPackageInfo("your.package.name", PackageManager.GET_SIGNATURES);
            for (Signature signature : info.signatures) {
                MessageDigest md = MessageDigest.getInstance("SHA");
                md.update(signature.toByteArray());
                Log.d("KeyHash:", Base64.encodeToString(md.digest(), Base64.DEFAULT));
            }
        } catch (NameNotFoundException e) {
         e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
         e.printStackTrace();
        }
    }
}



두물머리에서 어느 카페를 가지?


두물머리에 가서 산책하며 걷기 전 혹은 데이트를 마치고 돌아가는 길에 가보기 좋은 카페를 하나 소개할까 해요.

두물머리에서 카페를 어디갈지 고민하는 사람들에게 좋은 글이 되길 기대하며...


오늘 소개드릴 카페는 'OMNI라는 카페예요~


카페에서 데이트를 하기에는 은은한 조명과 배경음악 그리고 맛있는 음료가 필수적이겠죠?

OMNI는 이 모든 것을 다 갖춘 카페라고 할 수 있어요~

체인점의 획일화된 디자인이 아닌 개성있는 카페 인테리어도 맘에 들더라구요. 



요즘 유행하는 액자도 딱~ 예쁘죠?

그리고 여기 저기 아기자기하게 소품이 많아서 보는 맛이 있는 것 같아요. 



이제 카페 메뉴를 한번 볼게요!!



이번에 제가 직접 먹어본 음료는 메뉴를 미처 못찍었는데 수제! 블루베리청 아이스라떼와 수제! 딸기청 아이스라떼입니다. 

수제로 청을 담궈서 커피에다 넣었다고 해서 어떤 맛일까 신기해서 먹어봤어요. 

아메리카노나 라떼가 쓰다고 못먹는 분들에게 시럽 대신 달달한 청을 넣은 이 음료 강추 드려요~

단!!! 커피 본연의 맛에 집중하고 싶은 분들은 당연 오리지널로 드시는게 좋겠죠? 



화장실도 깔끔해요!!!



음료, 분위기, 배경음악 이 3박자를 모두 갖춘 카페에서 데이트를 시작하거나 이어나가면 분명 만족스러울거라 생각하여 직접 이용해보고 추천합니다!!!  꼭 한번 가보시길 :)

위치는!!! 경기도 양평군 양서면 두물머리길 24로 우선 검색하시고 자세한 위치는 아래 지도를 참고하시면 되요~


Firebase를 통한 Admob 사용


1. Firebase에서 프로젝트를 추가한다. 

2. AdMob 페이지에 가서 등록하고 광고를 추가한다. 

에드몹 페이지 가기 >

3. AdMob 테스트 광고를 삽입해서 광고가 잘 나오는지 확인한다.  


Firebase 페이지에서 로그인 후 콘솔 화면으로 갑니다. 그리고 프로젝트를 하나 추가해 줍니다. 

프로젝트 추가 이후 좌측 하단에 AdMob 메뉴를 클릭합니다. 

AdMob은 Firebase에서 설명이 잘 되어 있어서 추가 설명은 하지 않겠습니다. 


단, 광고를 삽입하고 나서 광고 화면이 바로 나오지 않을텐데 에러가 없다면 잘 입력한 것이니 당황하지 않으셔도 됩니다. 

광고가 나오는 것을 확인하고 싶으면 아래 코드를 액티비티나 프래그먼트에 삽입해보세요.

아래 코드를 삽입하고 광고가 잘 나오면 시간이 좀 지나면 테스트 광고가 아닌 정상적인 광고가 잘 나옵니다. 

길게는 몇일이 걸릴 수도 있습니다. 



  AdView mAdview = (AdView) findViewById(R.id.adView);

  AdRequest adRequest = new AdRequest.Builder().addTestDevice(AdRequest.DEVICE_ID_EMULATOR).build();

  mAdview.loadAd(adRequest); 



'프로그래밍 > Android' 카테고리의 다른 글

커스텀 리스트뷰 만들기 - Chapter01  (0) 2017.03.18
해시키(Hash key) 가져오기  (0) 2017.03.15
FCM 구현 - 안드로이드  (0) 2017.02.28
당겨서 새로고침(Pull to refresh)  (0) 2017.02.20
Fragment 새로고침  (0) 2017.02.20

FCM 알아보기



GCM을 대신해 새로운 버전인 FCM이 나왔습니다. 안드로이드 앱에서 설정해줘야 하는 부분이 대폭 줄어서 개발자 입장에서는 편리한 점이 많은 것 같아요. 서버가 개발 되지 않았더라도 푸시 메시지를 잘 받을 수 있는지 확인도 가능합니다. 

Firebase는 엔드포인트단에서 쉽게 여러 가지 서비스가 가능하도록 도와줍니다. 

Firebase에 문서가 아직 좀 덜 정리된 느낌이여서 블로그에 정리해서 올려보았습니다. 순서대로만 하시면 Firebase에 설명보다 더 빠르게 FCM을 구성할 수 있을 겁니다. 


구현하기

1. 안드로이드 스튜디오를 통해 프로젝트를 하나 생성 합니다. 

2.  앱 수준의 build.gradle 파일에 FCM 종속 항목을 추가합니다. 


3. 모듈의 Gradle 파일에 플러그인 사용 설정을 합니다. 


4. google-services.json 파일을 다운로드 받아 안드로이드 스튜디오 프로젝트 안에 추가해 줍니다. 우선 Firebase에서 새로운 프로젝트를 생성합니다. 프로젝트 생성 후에 안드로이드 아이콘을 선택하면 아래와 같은 화면을 볼 수 있습니다. 


안드로이드 스튜디오에서 생성한 프로젝트의 패키지 명을 입력하고 앱 추가 버튼을 클릭 합니다. 

그러면 또 아래와 같은 이미지를 확인할 수 있는데 여기서 google-services.json 파일을 다운 받아 이미지에 있는 것 처럼 프로젝트 폴더 안에 넣어주도록 합니다. 


5. 안드로이드 스튜디오에서 빨간 테두리에 있는 버튼을 찾아 Gradle 싱크를 맞춥니다. 


6. AndroidManifest.xml 파일에 아래 코드를 추가합니다. 

  처음 서비스는 등록 토큰 생성, 순환, 업데이트를 처리하기 위해 추가한 것이고, 푸시 메시지를 특정 기기로 전송하거나 기기 그룹을 만드는 경우에 필요합니다.

  두번 째 서비스는 백그라운드에서 앱의 알림을 수신하는 것 이외에 다른 방식으로 메시지를 처리하려는 경우에 필요합니다. 포어그라운드 앱의 알림 수신, 데이터 페이로드 수신, 업스트림 메시지 전송 등을 수행하려면 이 서비스를 확장해야 합니다. 

 

 <service

    android:name=".MyFirebaseInstanceIDService">

    <intent-filter>

        <action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>

    </intent-filter>

 </service>


 <service

    android:name=".MyFirebaseMessagingService">

    <intent-filter>

        <action android:name="com.google.firebase.MESSAGING_EVENT"/>

    </intent-filter>

 </service>



7. 프로젝트에 'MyFirebaseInstanceIDService' 와 'MyFirebaseMessageingService' 클래스 파일을 각 각 만들어 줍니다. 그리고 상속 받는 코드를 추가해 주면 됩니다. 


*MyFirebaseInstanceIDService.class

 

 public class MyFirebaseInstanceIDService extends FirebaseInstanceIdService {


    private static final String TAG = "MyFirebaseIIDService";


    @Override

    public void onTokenRefresh() {

        // Get updated InstanceID token.

        String refreshedToken = FirebaseInstanceId.getInstance().getToken();

        Log.d(TAG, "Refreshed token: " + refreshedToken);



        // If you want to send messages to this application instance or

        // manage this apps subscriptions on the server side, send the

        // Instance ID token to your app server.

        sendRegistrationToServer(refreshedToken);

    }

 private void sendRegistrationToServer(String token) {

        // TODO: Implement this method to send token to your app server.

    }

 }



*MyFirebaseMessageingService.class

 

 public class MyFirebaseMessagingService extends FirebaseMessagingService {


    private static final String TAG = "MyFirebaseMsgService";

   

    @Override

    public void onMessageReceived(RemoteMessage remoteMessage) {

        // [START_EXCLUDE]

        // There are two types of messages data messages and notification messages. Data messages are handled

        // here in onMessageReceived whether the app is in the foreground or background. Data messages are the type

        // traditionally used with GCM. Notification messages are only received here in onMessageReceived when the app

        // is in the foreground. When the app is in the background an automatically generated notification is displayed.

        // When the user taps on the notification they are returned to the app. Messages containing both notification

        // and data payloads are treated as notification messages. The Firebase console always sends notification

        // messages. For more see: https://firebase.google.com/docs/cloud-messaging/concept-options

        // [END_EXCLUDE]



        // TODO(developer): Handle FCM messages here.

        // Not getting messages here? See why this may be: https://goo.gl/39bRNJ

        Log.d(TAG, "From: " + remoteMessage.getFrom());



        // Check if message contains a data payload.

        if (remoteMessage.getData().size() > 0) {

            Log.d(TAG, "Message data payload: " + remoteMessage.getData());

        }



        // Check if message contains a notification payload.

        if (remoteMessage.getNotification() != null) {

            Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());

        }



        // Also if you intend on generating your own notifications as a result of a received FCM

        // message, here is where that should be initiated. See sendNotification method below.

    }

    // [END receive_message]



    /**

    * Create and show a simple notification containing the received FCM message.

    *

    * @param messageBody FCM message body received.

    */

    private void sendNotification(String messageBody) {

        Intent intent = new Intent(this, MainActivity.class);

        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,

                PendingIntent.FLAG_ONE_SHOT);



        Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);

        NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)

                .setSmallIcon(R.drawable.ic_stat_ic_notification)

                .setContentTitle("FCM Message")

                .setContentText(messageBody)

                .setAutoCancel(true)

                .setSound(defaultSoundUri)

                .setContentIntent(pendingIntent);



        NotificationManager notificationManager =

                (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);



        notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());

    }

}



8. 앱 설정은 끝났습니다. 이제 Firebase에서 메시지를 보내서 수신이 잘 되는지 테스트 하면 됩니다. 

Firebase 콘솔로 가서 좌측 메뉴 중간 부분에 Notifications를 들어가면 메시지를 보낼 수 있습니다. 


메시지가 잘 도착하면 이로써 Application 단은 수신 준비는 끝났습니다. 

물론 토큰을 생성하거나 메시지를 처리하는 부분은 추가 구현이 필요하지만 기본적인 동작은 끝난 겁니다. 


다음은 서버를 구성해서 푸시 메시지를 전송하는 법을 알아보도록 하겠습니다. 

읽으면서 배우는 CSS, 폰트 설정


출처: Code Academy


1. 글꼴 변경

CSS를 통해 글꼴을 변경하는 방법, 어렵지 않습니다. 

아래 코드를 보면 글꼴과 관련되었기 때문에 'font-family' 를 사용해서 글꼴을 변경해 줍니다. 

출처: Code Academy


글꼴을 여러개 지정할 수 있는데 여러개를 지정하는 이유는 해당 서체가 없을 때 차선책으로 다음 글꼴을 사용하도록 해주는 것입니다. 가장 먼저 적은 것이 기본이며 해당 글꼴이 없을 경우 다음 글꼴로 표시 됩니다. 



2. 폰트 사이즈 변경

폰트 사이즈는 'font-size'를 통해 변경할 수 있습니다. 폰트 사이즈는 3가지 단위를 사용하는데 아래 그림과 같습니다. 실제로 사용하는 방법은 그 다음 그림과 같습니다. 


실제 사이즈를 적용하는 방법입니다. 



3. 줄 간격 변경


각종 문서 프로그램, 블로그 등에서도 줄 간격 설정이 가능합니다. CSS에서 줄 간격 설정은 'line-height'를 사용하여 가능합니다. 


실제로 line-height 값을 '1em' 과 '2em'을 줬을 때 차이를 보겠습니다. 

   



4. 단어 사이 간격

단어 사이 간격도 변경 가능합니다. 'word-spacing' 를 통해서 단어 사이 간격을 변경할 수 있습니다. 

여기서 단위도 줄 간격과 동일하게 'em'을 사용합니다. 사용 방법은 아래 그림과 같습니다. 



5. 글자 간 간격

글자 간 간격도 변경 가능합니다. 'letter-spacing' 를 통해서 글자 한자 한자 간의 사이 간격을 변경할 수 있습니다. 단어 사이 간격과 차이점은 단어 사이 간격은 각 단어 간 간격 즉, 스페이스바를 사용한 뒤 단어 간 간격을 말하는 것이고, 글자 간 간격은 한글자 한글자 간 간격을 의미합니다. 



6. 두껍게(볼드체)

폰트를 두껍게 나타내는 방법입니다. 강조할 때 사용하기도 하죠?  'font-weight'를 사용합니다. 

font-weight 다음에 올 수 있는 값은 bold와 숫자로 100, 200, 300 ... 900까지 사용할 수 있습니다. 

100은 thin 즉 얇은 글꼴, 200~400은 보통 두께, 500~900은 두꺼운 글자체를 의미합니다. 



7. Italic

기울여 쓰기를 하고 싶다면 font-style을 사용할 수 있습니다. 



8. 대문자, 소문자로 만들기

영문에만 해당하지만 모두 대문자나 소문자로 만드는 방법은 'text-transform'을 사용합니다. 

모두 대문자로 사용하려면 'uppercase'를 사용하고 모두 소문자로 사용하려면 'lowercase'를 사용합니다. 



9. 정렬

글자를 좌우로 정렬할 수 있는 기능 입니다. 'text-align' 을 사용하여 정렬하면 됩니다. 

사용하는 값은 'right', 'left', 'center'을 사용할 수 있다. 


'프로그래밍 > CSS' 카테고리의 다른 글

읽으면서 배우는 CSS, 색상 변경하기  (0) 2017.02.23

읽으면서 배우는 CSS, 색상 변경하기


출처: Code Academy


CSS를 공부하는데 있어 가장 기본은 사용 법이다. HTML문 안에서 CSS를 어떻게 사용하는지 아래 그림을 보면 알 수 있다. 

출처: Code Academy


두 가지 link 사용이 나와있는데 각각 차이가 있다. 첫번 째 링크는 인터넷 상에 있는 주소를 직접 입력하여 CSS를 적용하는 것이고, 두 번째 방법은 직접 만든 CSS 파일을 가지고 적용하는 방법이다. 

이 글의 첫 이미지 처럼 selector를 지정하여 html 내에서 어떤 테그에 저 속성을 지정할지 정해야 한다. 그리고 그 뒤에는 적용하고자 하는 속성 즉 property를 지정해 폰트 크기, 사이즈, 배경 색깔, 배경 이미지 등을 지정할 수 있다. 속성 다음은 반드시 콜론( : ) 을 넣어 줘야하며 각각의 속성마다 세미콜론( ; )으로 마쳐야 한다. 


색상 변경하기

색상을 변경하는 방법에는 몇 가지가 있다. 색상 이름을 직접 입력 하는 방법, GRB 코드를 입려하는 방법, Hex 값을 입력하는 방법, HSL 값을 입력하는 방법 등이 있다.


1. 색상 이름을 직접 입력 하는 방법

색상을 직접 입력 할 수 있는 가지수는 무려 147개가 있다. 색상에 대해 입력 가능한 것을 보려면 아래 그림을 클릭 하면된다. 색상 위에 마우스를 올리면 해당 색상의 이름이 나온다. 

출처: Code Academy


2. Hex 코드를 입력하는 방법

위의 그림 처럼 입력해도 색상 값을 지정할 수 있다. # 뒤의 가장 앞의 두 자리는 red 값을, 중간 두 자리는 blue 값을, 가장 마지막 두 자리는 green 값을 나타내며 이 모든 값을 섞었을 때 색상이 최종적으로 나타난다. 


3. HSL 값을 입력하는 방법

hsl(Hue, Saturation, Lightness) 즉 색상, 채도, 명도로 볼 수 있는데 이 값을 입력해서 색상 값을 출력할 수 있다. 

Hue 값은 0 ~ 360 까지 입력이 가능하며 채도와 명도는 퍼센트로 입력한다. 


rgb나 hsl에 'a'를 붙이면 alpha 즉 투명도를 설정할 수 있는데 이 투명도는 0~1까지 값을 입력할 수 있다. 

투명도가 낮을 수록 유리창이 깨끗하다고 생각하면 된다. 투명도가 1이면 유리창이지만 뒤를 볼 수 없다고 생각하면 된다.


'프로그래밍 > CSS' 카테고리의 다른 글

읽으면서 배우는 CSS, 폰트 설정  (0) 2017.02.24

당겨서 새로고침, Pull to refresh


당겨서 새로고침을 위해서 SwipeRefreshLayout가 필요하며 이는 Android support library v4에 포함되어 있다. 

먼저 gradle에 support v4 라이브러리를 추가한다. 

  

  dependencies {

     . . .

    complie 'com.android.support:support-v4:25.1.0'

  }



다음은 새로고침을 적용할 뷰를 SwipeRefreshLayout로 감싼다. 아마 대부분 ListView나 RecyclerView가 될 것이다. 


 <android.support.v4.widget.SwipeRefreshLayout

         android:layout_width="match_parent"

         android:layout_height="match_parent"

         android:id="@+id/sr_layout">


        <ListView

            . . . 

        />


 </android.support.v4.widget.SwipeRefreshLayout>



이제 새로고침에 대한 반응을 할 OnRefreshListener 인터페이스를 등록해야 한다. 등록하기에 앞서 SwipeRefreshLayout 객체를 만들자. 

 

 SwipeRefreshLayout swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.sr_layout);


 swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {

       @Override

       public void onRefresh() {

            // 새로고침 할 작업

            swipeRefreshLayout.setRefreshing(false);

       }

 }

위에서 setRefreshing(false)가 없으면 새로고침 아이콘이 사라지지 않는다. 


현재 구글은 Pull To Refresh UI에 대한 새로운 스타일을 공개했고, 이와 관련해서 Naver D2에서 오픈소스로

공개한 주소를 공유한다. 

https://github.com/nhnopensource/android-pull-to-refresh

Fragment Refresh, 프래그먼트 새로고침


프래그먼트에 리스트뷰를 사용하거나 화면을 새로고침해야 하는 경우가 있다. 

보통 액티비티에서 리스트뷰를 사용할 때 리스트뷰의 아이템에 변경이 발생했을 시

리스트 항목을 새로고침 하려고 한다. 이 때 사용하는 것이 리스트뷰의 adapter을 사용하여

새로고침 하는 방법이다. 

adapter.notifyDataSetChanged(); 를 사용하여 새로고침 한다. 


하지만!!

프래그먼트에서 리스트뷰를 새로고침하기 위해 아무리 위의 메서드를 호출하더라도

리스트뷰의 새로고침을 볼 수 없다. 

프래그먼트 화면을 새로 고침해줘야하는데 이때 FragmentTransaction을 사용한다. 

FragmentTransaction ft = getFragmentManager().beginTransaction();

ft.detach(this).attach(this).commit(); 을 하면 화면이 바뀌는 것을 확인할 수 있다. 

strings.xml

문자열, 문자열 배열, 수량문자열(복수형)을 지원합니다. 안드로이드 프로젝트 생성시 기본적으로 strings.xml을 사용하여 문자열에 대한 정의 및 수정을 하면 됩니다. 하지만 필요할 시 strings.xml 말고 xml 파일을 새로 추가하여 사용할 수 있습니다. 아래는 간단한 사용 방법을 적은 것이고 자세한 사용법을 알고 싶다면 개발자 페이지를 참고하면 됩니다. 

참고: https://developer.android.com/guide/topics/resources/string-resource.html


한줄 띄워쓰기

한줄 띄우고 싶은 부분에 \n 을 추가하면 됩니다. 

 다음에는 한 줄 띄워 쓰기 \n 다음줄 부터 시작함


볼드체, 이텔릭체 적용하기

적용하고자 하는 텍스트 앞 뒤로 태그를 추가하면 됩니다. 

 <b> 여기는 두껍게 </b>

 <i> 여기는 기울여 쓰기 </i>

 <u> 여기는 및줄 </u>


Table 최고 사이즈 확인 방법

 SHOW TABLE STATUS FROM DB name LIKE 'Table name';


이 명령어 이후 Create_options에 있는 max_rows와 avg_row_length를 곱한 값이 용량이 된다. MB 단위로 환산하려면 1024로 두번 나누어 주면 된다. 



DB 사이즈 확인 방법


 SELECT count(*) NUM_OF_TABLE,

              table_schema,concat(round(sum(table_rows)/1000000,2),'M') rows,

              concat(round(sum(data_length)/(1024*1024*1024),2),'G') DATA,

              concat(round(sum(index_length)/(1024*1024*1024),2),'G') idx,

              concat(round(sum(data_length+index_length)/(1024*1024*1024),2),'G') total_size,

              round(sum(index_length)/sum(data_length),2) idxfrac

 FROM information_schema.TABLES

            GROUP BY table_schema

            ORDER BY sum(data_length+index_length) DESC LIMIT 10;




각 테이블 사이즈 확인 방법


 SELECT table_name,

              table_rows,

              round(data_length/(1024*1024),2) as 'DATA_SIZE(MB)',

              round(index_length/(1024*1024),2) as 'INDEX_SIZE(MB)'

 FROM information_schema.TABLES 

 WHERE table_schema = 'DB_name'

 GROUP BY table_name 

 ORDER BY data_length DESC LIMIT 10;





'프로그래밍 > DB' 카테고리의 다른 글

MySQL ERD 생성하기 ERWin에서...  (0) 2016.10.11
Mac(맥)에 MySQL 설치하기  (0) 2016.08.10
MySQL ALTER TABLE 테이블 변경하기  (0) 2016.08.03

+ Recent posts