2016년 5월 19일 목요일

zxing - QRCode, Barcode

1. build.gradle (Module: app)
apply plugin: 'com.android.application'

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.3"

    defaultConfig {
        applicationId "com.example.falcon.myqrcode"
        minSdkVersion 19
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.4.0'

 // Supports Android 4.0.3 and later (API level 15)
    compile 'com.journeyapps:zxing-android-embedded:2.3.0@aar'

    // Supports Android 2.1 and later (API level 7), but not optimal for later Android versions.
    // If you only plan on supporting Android 4.0.3 and up, you don't need to include this.
    compile 'com.journeyapps:zxing-android-legacy:2.3.0@aar'

    // Convenience library to launch the scanning Activities.
    // It automatically picks the best scanning library from the above two, depending on the
    // Android version and what is available.
    compile 'com.journeyapps:zxing-android-integration:2.3.0@aar'

    // Version 3.0.x of zxing core contains some code that is not compatible on Android 2.2 and earlier.
    // This mostly affects encoding, but you should test if you plan to support these versions.
    // Older versions e.g. 2.2 may also work if you need support for older Android versions.
    compile 'com.google.zxing:core:3.2.0'
}

2. AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.falcon.myqrcode">

    <uses-feature android:name="android.hardware.camera"/>
    <uses-permission android:name="android.permission.CAMERA"/>
    <uses-permission android:name="android.permission.FLASHLIGHT"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.INTERNET" />

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

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

</manifest>

3. MainActivity.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.falcon.myqrcode.MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="바코드정보"
        android:id="@+id/mResult"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="52dp" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="읽기"
        android:id="@+id/btnRead"
        android:layout_below="@+id/mResult"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="99dp" />
</RelativeLayout>

4. MainActivity.java
package com.example.falcon.myqrcode;

import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.google.zxing.integration.android.IntentIntegrator;
import com.google.zxing.integration.android.IntentResult;

public class MainActivity extends AppCompatActivity {

    TextView mResult;
    Button mReadBtn;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mReadBtn = (Button) findViewById(R.id.btnRead);
        mResult = (TextView) findViewById(R.id.mResult);

        mReadBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mResult.setText("");

                IntentIntegrator integrator = new IntentIntegrator(MainActivity.this);
                integrator.setOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
                integrator.addExtra("PROMPT_MESSAGE", "상품코드를 사각형 안에 비춰주세요.");
                integrator.initiateScan();
            }
        });

    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        IntentResult result = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);
        mResult.setText(result.getContents());

        // result.getFormatName() : 바코드 종류
        // result.getContents() : 바코드 값

        Toast.makeText(getApplicationContext(),"contents: "+result.getFormatName(), Toast.LENGTH_LONG).show();

/*
        if(requestCode == 0) {

            if(resultCode == Activity.RESULT_OK)
            {
                String contents = data.getStringExtra("SCAN_RESULT");
                //위의 contents 값에 scan result가 들어온다.
                Toast.makeText(this,contents,Toast.LENGTH_LONG).show();
                mResult.setText(contents+"&imei=");
            }

        }
*/

    }
}

2016년 5월 13일 금요일

AsyncHttpClient, Handler 를 이용한 HTML 소스 가져오기

1. AndoridManifest.xml 인터넷 권한추가
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.rock.myhandlertest1">

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

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

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

2. gradle:(Module app) 에 AsyncHttpClient 추가
compile 'com.loopj.android:android-async-http:1.4.9'

3. activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.rock.myhandlertest1.MainActivity"
    android:focusableInTouchMode="false">

    <EditText
        android:layout_width="250sp"
        android:layout_height="wrap_content"
        android:id="@+id/editText"
        android:text="http://m.naver.com"
        android:layout_alignParentTop="true"
        android:layout_alignParentStart="true" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="test"
        android:id="@+id/button"
        android:layout_alignTop="@+id/editText"
        android:layout_alignParentEnd="true" />

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/scrollView"
        android:layout_below="@+id/editText"
        android:layout_alignParentStart="true">

        <TextView
            android:id="@+id/content"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_gravity="top" />
    </ScrollView>
</RelativeLayout>

4. MainActivity.java
package com.example.rock.myhandlertest1;

import android.content.Context;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    static TextView tvUrl;
    static TextView tvContent;
    String mStrUrl = "";

    Handler mHandler;
    MyRunnable myRunnable;
    InputMethodManager imm;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button button = (Button) findViewById(R.id.button);
        tvUrl = (TextView) findViewById(R.id.editText);

        tvContent = (TextView) findViewById(R.id.content);

        mHandler = new Handler();

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                tvUrl.clearFocus();
                tvContent.setText("");

                // 키보드 화면에서 내리기
                imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
                imm.hideSoftInputFromWindow(tvUrl.getWindowToken(), 0);

                mStrUrl = tvUrl.getText().toString();

                myRunnable = new MyRunnable(mStrUrl);

                mHandler.post(myRunnable);
            }
        });
    }
}

5. MyRunnable.java
package com.example.rock.myhandlertest1;

import android.util.Log;
import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.AsyncHttpResponseHandler;
import cz.msebera.android.httpclient.Header;

/**
 * Created by rock on 2016-05-13.
 */
public class MyRunnable implements Runnable {

    AsyncHttpClient httpClient;
    final String url;
    final String TAG = "MYTEST";

    public MyRunnable(final String pUrl) {
        url = pUrl;
    }

    @Override
    public void run() {

        httpClient = new AsyncHttpClient();

        httpClient.get(url, new AsyncHttpResponseHandler() {
            @Override
            public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
                Log.d(TAG,"Http get Success");

                String text = new String(responseBody);
                MainActivity.tvContent.setText(text);
            }

            @Override
            public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {
                Log.d(TAG,"Http get Fail");
                Log.d(TAG,"Status Code:"+statusCode);
                Log.d(TAG,"Error:"+error.getMessage());

                MainActivity.tvContent.setText("Http get fail.\nstatus code="+statusCode+"\nError:"+error.getMessage());
            }
        });
    }
}

6. 실행결과

2016년 5월 9일 월요일

Handler 테스트

내부클래스, 외부 클래스, 멤버객체를 사용하는 방법 테스트

1. activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.falcon.mythreadtest1.MainActivity">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="메인스레드값"
        android:id="@+id/tvMainValue"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="24dp" />
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="작업스레드값"
        android:id="@+id/tvBackValue"
        android:layout_below="@+id/tvMainValue"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="73dp" />
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="메인스레드증가"
        android:id="@+id/btnMainIncrease"
        android:layout_centerVertical="true"
        android:layout_centerHorizontal="true" />
</RelativeLayout>

2. MainActivity.java
package com.example.falcon.mythreadtest1;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    SendMessageHandler mHandler;
    int mainValue = 0;
    int backValue = 0;
    TextView tvMainValue;
    TextView tvBackValue;
    Button btnMainIncrease;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        tvMainValue = (TextView) findViewById(R.id.tvMainValue);
        tvBackValue = (TextView) findViewById(R.id.tvBackValue);
        btnMainIncrease = (Button) findViewById(R.id.btnMainIncrease);

        mHandler = new SendMessageHandler(tvBackValue); // 2. 핸들러 객체를 사용했을때는 필요없음

        BackThread thread = new BackThread();
        thread.setDaemon(true);
        thread.start();

        btnMainIncrease.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mainValue++;
                tvMainValue.setText("MainValue: " + mainValue);
            }
        });
    }

    class BackThread extends Thread {
        @Override
        public void run() {
            //super.run();
            while(true) {

                backValue++;

                Message msg = mHandler.obtainMessage();

                //mHandler.sendEmptyMessage(0);

                msg.what = 0;
                msg.arg1 = backValue;
                msg.obj = tvBackValue; // View 객체도 메시지로 전달

                mHandler.sendMessage(msg);

                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /*
    // 1. 내부 클래스 사용했을때
    class SendMessageHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            Log.d("MYTEST", "msg.what: "+msg.what);

            if (msg.what == 0) {
                tvBackValue.setText("BackValue: " + backValue);
            }
        }
    }
    */

    /* 2. 핸들러 멤버객체를 사용했을때
    Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            Log.d("MYTEST", "msg.what: "+msg.what);

            if (msg.what == 0) {
                tvBackValue.setText("BackValue: " + backValue);
            }
        }
    };*/
}

3. SendMessageHandler.java
package com.example.falcon.mythreadtest1;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.widget.TextView;
/**
 * Created by falcon on 2016-05-09.
 */
// 3. 외부 클래스 사용했을때
public class SendMessageHandler extends Handler {

    TextView tvBackValue;

    public SendMessageHandler(TextView tvBackValue) {
        // TextView 객체를 메시지로 받지 않고
        // 핸들러 객체 생성시 TextView 객체를 받고 전역변수로 대입함.
        // 메시지로 받는 경우에는 필요없음.
        this.tvBackValue = tvBackValue;
    }

    @Override
    public void handleMessage(Message msg) {

        Log.d("MYTEST", "msg.what: "+msg.what);

        if (msg.what == 0) {
            //tvBackValue.setText("BackValue: " + msg.arg1);
            TextView textView = (TextView) msg.obj; // TextView 객체를 메시지로 받음
            textView.setText("BackValue: " + msg.arg1);
        }
    }
}

* 실행결과

2016년 5월 5일 목요일

Broadcast Receiver 테스트 - 정적(static)

1 송신 (sender) : MyBCastSender

1) activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.rock.mybcastsender.MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="송신기"
        android:id="@+id/textView"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="메세지보내기"
        android:id="@+id/button1"
        android:layout_below="@+id/textView"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="64dp" />
</RelativeLayout>

2) MainActivity.java
package com.example.rock.mybcastsender;

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        final Button sendButton = (Button) findViewById(R.id.button1);

        sendButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent("com.example.rock.BROADCAST_TEST"); // 수신기에서 받을 인텐트 필터 지정. 수신기의 Manifest에서 이 필터를 지정해준다.
                intent.putExtra("testValue", "가나다");
                sendBroadcast(intent);

                Log.d("MYTEST", "보낸메시지:" + "가나다");
            }
        });
    }
}


2 수신 : MyBcastReceiver

1) AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.rock.mybcastreceiver">

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

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

        <receiver
            android:name=".MyReceiver"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="com.example.rock.BROADCAST_TEST" /> // 송신자에서 보낸 인텐를 받기 위한 필터 지정
            </intent-filter>
        </receiver>
    </application>
</manifest>

또는 아래와 같이 인텐트필터를 지정하지 않고 MyReceiver 에서 프로그램상으로 필터링 할 수도 있다.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.rock.mybcastreceiver">

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

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

        <receiver
            android:name=".MyReceiver"
            android:enabled="true"
            android:exported="true">
        </receiver>
    </application>

</manifest>

2) activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.rock.mybcastreceiver.MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="수신기"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true" />
</RelativeLayout>

3) MainActivity.java
package com.example.rock.mybcastreceiver;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

4) MyReceiver.java
package com.example.rock.mybcastreceiver;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;

public class MyReceiver extends BroadcastReceiver {
    public MyReceiver() {
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        // TODO: This method is called when the BroadcastReceiver is receiving
        // an Intent broadcast.
        //throw new UnsupportedOperationException("Not yet implemented");

        String name = intent.getAction();

        // AndroidManifest.xml 에서 인텐트필터를 지정하지 않은 경우 아래와 같이 if 문으로 필터링
        // 인텐트필터를 지정했으면 if 문 생략
        if (name.equals("com.example.rock.BROADCAST_TEST")) {
            String msg = intent.getStringExtra("testValue");
            Log.d("MYTEST", "받은메시지:" + msg);
        }
    }
}

Android Studio 에서 위의 Broadcast Receiver 추가방법

* 테스트

1) MyBcastReceiver 를 먼저 실행한 다음 MyBcastSender 를 실행한다.
아래 사진에서 왼쪽은 에물레이터 상에서 프로그램 두개를 모두 띄운 상태.

2) MyBcastSender에서 '메시지보내기' 버튼을 클릭하면 Android Studio 하단에 있는 logcat에서 메세지가 전달되는 것을 확인할 수 있다.
MyBcastReceiver 가 한번 실행되어 브로드캐스트를 받을 수 있는 상태가 되었으므로 이제 MyBcastReceiver 가 실행되지 않은 상태에서도 메시지를 받을 수 있다.
MyBcastReceiver 에서 메시지를 받았을때 notification 이나 메시지를 받았을때 실행할 activity를 구현하면 됨.

- 송신기(MyBcastSender) 쪽 로그

- 수신기(MyBcastReceiver) 쪽 로그

2016년 5월 3일 화요일

Android Studio 에서 NanoHttpd 테스트

1. bulid.gradle (Module: app)
  dependencies 에 com.nanohttpd:nanohttpd-webserver:2.1.1' 추가
dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.3.0'
    compile 'com.nanohttpd:nanohttpd-webserver:2.1.1'
}

2. AndroidManifest.xml 에 퍼미션추가
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

3. activity_main.xml 에 서버 IP 주소를 보여줄 TextView 추가
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.rock.myhttpd.MainActivity">

    <TextView
        android:id="@+id/ipaddr"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:paddingBottom="40dp"
        />
    <TextView
        android:id="@+id/hello"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Hello"
        />
</LinearLayout>

4. MainActivity.java
package com.example.rock.myhttpd;

import fi.iki.elonen.NanoHTTPD;

import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Enumeration;
import java.util.Map;

public class MainActivity extends AppCompatActivity {
    private WebServer server;
    private static final String TAG = "MYSERVER";
    private static final int PORT = 8080;
    String ipAddress;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        TextView text = (TextView) findViewById(R.id.ipaddr);
        ipAddress = getLocalIpAddress();

        if (ipAddress != null) {
            text.setText("Please Access:" + "http://" + ipAddress + ":" + PORT);
        } else {
            text.setText("Wi-Fi Network Not Available");
        }

        server = new WebServer();
        try {
            server.start();
        } catch(IOException ioe) {
            Log.w("Httpd", "The server could not start.");
        }
        Log.w("Httpd", "Web server initialized.");

    }

    // DON'T FORGET to stop the server
    @Override
    public void onDestroy()
    {
        super.onDestroy();
        if (server != null)
            server.stop();
    }

    public String getLocalIpAddress() {
        try {
            for (Enumeration<NetworkInterface> en = NetworkInterface
                    .getNetworkInterfaces(); en.hasMoreElements();) {
                NetworkInterface intf = en.nextElement();
                for (Enumeration<InetAddress> enumIpAddr = intf
                        .getInetAddresses(); enumIpAddr.hasMoreElements();) {
                    InetAddress inetAddress = enumIpAddr.nextElement();
                    if(!inetAddress.isLoopbackAddress() && inetAddress instanceof Inet4Address) {
                        String ipAddr = inetAddress.getHostAddress();
                        return ipAddr;
                    }
                }
            }
        } catch (SocketException ex) {
            Log.d(TAG, ex.toString());
        }
        return null;
    }


    private class WebServer extends NanoHTTPD {

        public WebServer()
        {
            super(PORT);
        }

        @Override
        public Response serve(String uri, Method method,
                              Map<String, String> header,
                              Map<String, String> parameters,
                              Map<String, String> files) {
            String answer = "";
            try {
                // Open file from SD Card
                File root = Environment.getExternalStorageDirectory();
                FileReader index = new FileReader(root.getAbsolutePath() +
                        "/www/index.html");
                BufferedReader reader = new BufferedReader(index);
                String line = "";
                while ((line = reader.readLine()) != null) {
                    answer += line;
                }
                reader.close();

            } catch(IOException ioe) {
                Log.w("Httpd", ioe.toString());
            }


            return new NanoHTTPD.Response(answer);
        }
    }
}

5. 안드로이폰 SD카드에 www 디렉토리생성
- 내파일 > 모든파일 선택 후 www 디렉토리 생성

6. 아래와 같은 샘플 html 을 작성하여 index.html 로 저장하고 www 디렉토리에 복사
<!doctype html>
<html lang="en">
 <head>
  <meta charset="UTF-8">
  <title>test</title>
 </head>
 <body>
  <h1>TEST</h1>
  <h2><font color=red>한글은 잘 나옵니까? ^^</font></h2>
 </body>
</html>

7. 앱을 실행시키고(httpd 서버를 가동) PC 에서 웹브라우져로 접속해 본다.

2016년 5월 2일 월요일

FrameLayout, LayoutInflater, Button Listener 테스트

FrameLayout, LayoutInflater, Button Listener 테스트

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.rock.myfragment2.MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <Button
            android:id="@+id/button1"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="프레임1"/>

        <Button
            android:id="@+id/button2"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="프레임2"/>

    </LinearLayout>

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <LinearLayout
            android:id="@+id/container"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"
            android:background="#9c9c9c"/>

        <View
            android:id="@+id/view1"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="#4bbad1"/>
    </FrameLayout>

</LinearLayout>

sub_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="서브레이아웃"
        android:id="@+id/textView"
        android:layout_gravity="center_horizontal" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="서브버튼"
        android:id="@+id/subButton"
        android:layout_gravity="center_horizontal" />
</LinearLayout>

MainActivity.java

package com.example.rock.myfragment2;

import android.content.Context;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    Button button1;
    Button button2;
    Button subButton;

    View view1;
    LinearLayout container;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        button1 = (Button) findViewById(R.id.button1);
        button2 = (Button) findViewById(R.id.button2);

        view1 = findViewById(R.id.view1);
        container = (LinearLayout)findViewById(R.id.container);

        LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        inflater.inflate(R.layout.sub_layout, container, true);

        subButton = (Button) findViewById(R.id.subButton);

        button1.setOnClickListener(this);
        button2.setOnClickListener(this);
        subButton.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.button1 :
                view1.setVisibility(View.VISIBLE);
                container.setVisibility(View.GONE);
                break;
            case R.id.button2 :
                view1.setVisibility(View.GONE);
                container.setVisibility(View.VISIBLE);
                break;
            case R.id.subButton :
                Toast.makeText(getApplicationContext(), "서브버튼이 클릭됨", Toast.LENGTH_SHORT).show();
                break;
        }
    }
}

2016년 4월 10일 일요일

GCM 6. 테스트

1. 스마트폰 기기등록

앱을 실행하여 '인스턴스ID 토큰 가져오기' 버튼을 눌러서 토큰을 획득.


2.토큰 복사

토큰을 획득할때 로그에 출력하도록 되어있으므로 안드로이드 모니터에서 토큰값을 복사한다.
필터옵션을 Verbose, GcmRegistrationIntentService 으로 맞추면 값을 쉽게 찾을 수 있다.
GCM Registration Token: 에 있는 값을 복사해 놓는다.


3. advanced REST client 설치

- 수동으로 메시지를 보내기 위한 rest client 설치

1) 구글 크롬을 설치하시고.. 주소창에 chrome://apps/ 를 입력하고 엔터키를 누른다음 웹스토어 아이콘을 클릭


2) 검색창에 rest 를 검색하면 여러 rest 클라이언트가 나오는데 advanced REST client를 선택하여 크롬에 추가

3) advanced REST client 샐행


4) 아래와 같이 입력하고 SEND 버튼을 누른다.
URL: http://android.googleapis.com/gcm/send

   Method: POST

   Headers From:
     authorization key=GCM 등록할때 받은 Server API Key 값
     content-type application/json

   Raw payload
{
  "registration_ids" : ["GCM Registration Token 값"],
 
  "data": {
    "title" : "GCM 테스트"
    "message" : "GCM 테스트 메시지 입니다."
  }
}

5) 전송결과 화면