/* scrip for google analytic */

Ads 468x60px

แสดงบทความที่มีป้ายกำกับ Development/Geek แสดงบทความทั้งหมด
แสดงบทความที่มีป้ายกำกับ Development/Geek แสดงบทความทั้งหมด

วันพุธที่ 27 เมษายน พ.ศ. 2559

[Neo4j] สวัสดีชาวโลก! Hello World! ด้วย JAVA Implements กับ Neo4j

ในบทความนี้จะมาเล่าถึงวิธีการนำ Neo4j มา Implements ให้อ่านกัน
จากบทความที่ผ่านๆมา เป็นการปูพื้นก่อนที่จะนำ Graph Database มาใช้

ก่อนที่มาเริ่ม Coding ก็ให้มาติดตั้ง Environment ให้เสร็จเรียบร้อยก่อน ได้แก่

1. Java JDK
2. ติดตั้ง Path เป็น JAVA_HOME ให้เรียบร้อย
3. ติดตั้ง JAVA EE
4. ติดตั้ง Neo4j ให้เรียบร้อย

จากนั้นก็เริ่ม สร้าง Project ขึ้นมา select File -> new -> Java Project 



จากนั้นก็เริ่ม Build Path ของ Neo4j เข้ามาใน Library



กด Properties


วันจันทร์ที่ 25 เมษายน พ.ศ. 2559

[Development] ในที่สุดก็เข้าใจคำว่า API เสียทีน่ะ!

ในที่สุดก็เข้าใจคำว่า API (Application Programming Interface) เสียที
จากบทความของผู้เขียนท่านอื่นๆมักจะให้คำนิยามกับ API ว่า

เป็นช่องทางการสื่อสารหรือตัวกลางของเว็บไซต์ใดเว็บไซต์หนึ่ง ส่งข้อมูลไปยังเว็บไซต์อื่นๆ
หรือเป็นช่องทางการเชื่อมต่อระหว่าง Client กับ Server
หรือช่องทางการเชื่อมต่อระหว่าง Server กับ Server นั้นเอง

โดยส่วนตัวแล้วบทความที่อ่านผ่านๆมามักอธิบายยืดยาวและต้องใช้จินตนาการสูง
แต่ในบทความนี้ ผู้เขียนขอสรุปสั้นๆง่ายๆ แถมภาพ ปลากรอบ ด้วยน่ะเออ...

ซึ่งเจ้าตัวกลางนี้เอง จริงๆแล้วมันก็คือ Code ก้อนหนึ่งเท่านั้นเอง
ที่จะออกแบบเพื่อรับส่งข้อมูล แล้วข้อมูลนั้นมีอะไรบ้างก็ขึ้นอยู่กับ
การออกแบบของผู้พัฒนา ที่ต้องจะนำมาเก็บหรือแสดงผล
ซึ่ง Code ก้อนนั้นๆจะเป็นภาษาอะไรก็ได้ขึ้นอยู่กับงานที่จะทำนั้นๆ

ผมขอยกตัวอย่างซึ่งเป็นประสบการณ์ของผมเอง

ในการออกแบบในครั้งนั้น ตอนนั้นยังไม่มีความรู้ เรื่องการออกแบบ API
จึงได้ทำแบบลูกทุ่งๆ ออกแบบระบบตามความเข้าใจ
แต่พอมาอ่าน เอ๊า นี้มันก็ที่เคยทำนิมันเรียกว่า API หรอกหรอ...

ระบบดังกล่าว ผมได้ใช้ App Android ภาษา JAVA เชื่อมต่อกับฐานข้อมูล MySQL
โดยใช้ภาษา PHP เชื่อมต่อกับฐานข้อมูลด้วยคำสั่ง SQL

ให้ลองนึกถึง ช่องกรอกชื่อนามสกุล ในโปรแกรมทั่วๆไปที่พัฒนาด้วย JAVA มันจะส่งข้อมูลโดยการเชื่อมต่อกับ PHP ด้วยการ POST หรือ GET เพื่อไปสั่งให้ PHP ให้ส่งคำสั่ง SQL เก็บข้อมูลที่ช่องกรอกข้อมูลลงฐานข้อมูลอีกทีหนึ่ง ในส่วนนี้ผู้เขียนขอเรียกมันว่าการอัพโหลด

ส่วนการดาวน์โหลดก็จะใช้วิธีการให้ PHP ใช้คำสั่งในการทำให้ข้อมูลออกมาเป็น Array หรือภาษา JSON นั้นเอง แล้วให้ JAVA ไปรับค่าด้วยการ Connect ที่ URL ที่ชี้ไปยังฐานข้อมูลแล้วดึงข้อมูลมาเก็บไว้ที่ตัวแปรแล้วนำมาแสดงผล


นี้แหละครับ API ในนิยามของผม แล้วนิยามของคุณละคืออะไร??

วันจันทร์ที่ 18 เมษายน พ.ศ. 2559

[Neo4j] สรุปการประยุกษ์ใช้ Cypher ร่วมกับ Graph Data Modeling เพื่อความเข้าใจที่มากขึ้น



จากที่ได้ลองศึกษา และทำความเข้าใจกับ เทคโนโลยีนี้มาหลายบทความพอสมควร
ผู้เขียนก็ได้อ่านและรวบรวมข้อมูลแปลแล้วสรุป ผิดบ้างถูกบ้างก็ถูๆไถกันไป 
จากนั้นก็นำมาเล่าให้อ่านกันเพื่อเป็นประโยชน์แก่ผู้ที่สนใจเรื่อยๆ

สามารถเข้าไปอ่านเต็มๆได้ที่ http://neo4j.com/developer/guide-data-modeling/

ในบทความนี้ลองมาทบทวน ให้เข้าใจมากขึ้นกับการประยุกษ์ใช้ Cypher 
ให้มากขึ้นอีกสักนิดนึงกับทฤษฎีเล็กๆน้อยๆกันสักหน่อย

หลังจากที่ได้ทำความรู้จัก กับ Cypher พื้นฐานกันไปแล้ว พอจะเห็นได้จากการปฎิบัติกับคำสั่งเบื้องต้นกันไปแล้วนะครับ



ลองมาพิจารณา กับประโยคด้านล่าง

Two peopleJohn and Sally, are friends. Both John and Sally have read the book,Graph Databases.

เราสามารถจับเอาประโยคดังกล่าว มาแปลงเป็นส่วนประกอบต่างๆใน Graph Database อย่างไรได้บ้างกันครับ

มาทบทวนกันหน่อย

Node 

หน่วยที่เป็นพื้นฐานที่สุดของ Graph จริงๆแล้ว คือ Node และ Relationship
ใน Neo4j ทั้งสองอย่างที่ได้กล่าวไป สามารถมี Properties เป็นของตัวเอง
Node บ่อยครั้งมักจะแทน Entity แต่ขึ้นอยู่กับ Ralationship 
ส่วนที่แยกออกมาจาก Properties คือ Label

Node สามารถ มี Label หลาย Label หรือไม่มีก็ได้ ดังภาพด้านล่าง

วันอาทิตย์ที่ 17 เมษายน พ.ศ. 2559

[Neo4j] สรุปการใช้ Cypher Query Languege ที่ใช้ใน Graph Database และคำสั่ง CREATE, MATCH และ RETURN



เมื่อเราติดตั้ง Neo4j Server ขึ้นมาแล้วเราจะต้องมารู้จักกับ ภาษาที่ใช้ Query ใน Graph Database

http://skl-songkiat.blogspot.com/2016/04/neo4j-neo4j-windows-graph-database.html

Cypher Query Language เป็นภาษาหนึ่งที่ คล้ายกับ SQL ที่มาใช้สำหรับ Query ข้อมูลที่อยู่ในฐานข้อมูลแบบ Graph ซึ่งข้อดีของ ภาษา Cypher มีดังนี้

- เป็นภาษาที่สามารถอธิบายคำสั่งได้ด้วยตัวมันเอง
- เป็นภาษาเขียนโปรแกรมที่ถูกออกแบบให้มีความใกล้เคียงภาษามนุษย์มากขึ้น
- มีโครงสร้างในรูปแบบของภาษาอังกฤษ ใกล้เคียงภาษาในเชิงสัญลักษณ์
- มีความง่ายของคำสั่งเหมาะกับความซับซ้อนในฐานข้อมูลแบบ Graph
- คล้ายกับภาษา JAVA ภาษา Script เช่น JRuby , Gremlin
- มีคำสั่ง ที่คล้ายกับ SQL เช่น WHERE ,ORDER ประกอบกับภาษาสัญลักษณ์ ง่ายต่อความเข้าใจ

จากข้อดีในหลายๆข้อนี้ เรามาดูคำสั่งต่างๆ ที่ใช้กับ ภาษา Cypher นี้กันดีกว่า คำสั่งที่สำคัญมีดังนี้

1. CREATE : เพิ่ม Node ,Relationship และ Properties
2. MATCH  : ดึงข้อมูลจาก Node, Relationship และ Properties
3. RETURN: ส่งค่าผลลัพท์กลับจากการ Query
4. WHERE  : ตั้งเงื่อนไข ในการดังข้อมูล
5. DELETE : ลบ Node และ Relationship
6. REMOVE : ลบ Properties ของ Node และ Relationship
7. ORDER By : เรียงข้อมูลที่ดึงมา
8. SET : เพิ่มหรืออัพเดท Label

ในบทความนี้ ผมขอยกคำสั่งเบื้องต้นมาให้ดูและ นำมาแสดงเป็นตัวอย่างให้ดู ได้แก่ CREATE, MATCH และ RETURN กันก่อน เพราะเป็นคำสั่งเบื้องต้น

วันเสาร์ที่ 16 เมษายน พ.ศ. 2559

[Neo4j] ติดตั้ง neo4j บนระบบ windows - graph database ง่ายนิดเดียว



บทความนี้ มาเล่าวิธีการติดตั้ง neo4j ให้อ่านกัน ไม่ยากอย่างที่คิด
ก่อนอื่นก็เข้าไปที่ website ของ neo4j เพื่อ Download โปรแกรมมาติดตั้งที่เครื่อง server ของเรา

http://neo4j.com/download/ คลิ้กลิ้ง



คลิ้กลิ้งที่ วงกลมสีแดง จะ Download อัตโนมัติ

Set up ที่ Icon ดังภาพด้านล่าง




จากนั้น Install กด Next ไปเรื่อยๆ ขึ้นอยู่กับ Path ที่ต้องการติดตั้ง



วันเสาร์ที่ 7 พฤศจิกายน พ.ศ. 2558

[Project] แอพพลิเคชั่นสแกนบาร์โค๊ดลงฐานข้อมูลด้วยระบบแอนดรอยด์พร้อมป้อนข้อมูลรายละเอียดสินค้า (2)


จากบทความที่แล้วที่ผู้เขียนได้นำเสนอวิธีสร้างแอพพลิเคชั่นสแกนบาร์โค๊ดไป แต่ยังไม่ได้ทำในส่วนของฐานข้อมูลเอาไว้อย่างที่ตั้งหัวข้อเอาไว้ ฉะนั้นในบทความนี้ ก็จะสานต่อจากบทความที่แล้ว


 

บทความที่แล้วได้ ทำให้แอพพลิเคชั่นสามารถสแกนบาร์โค๊ดได้แล้ว โดยการนำค่าสตริงที่เก็บอยู่ใน Key String มาเก็บไว้ที่ตัวแปร 

ในความเป็นจริงในการทำสต็อกสินค้า เราจะทำการ สร้างบาร์โค๊ดสำหรับสินค้านั้นๆ แล้วจึงใส่รายละเอียดข้อมูลสินค้าเข้าไป เช่น ชื่อ, ลักษณะ, ราคา, ยี่ห้อ, ขนาด, ปริมาณ ฯลฯ แล้วแต่ยูสเซอร์ได้เลย ซึ่งบาร์ทำหน้าที่อ้างอิงข้อมูลเหล่านี้



คอนเซ็ปของแอพตัวนี้ ผู้เขียนต้องการทำเพื่อเก็บข้อมูลสินค้าในฐานะผู้ซื้อ ไม่ใช่ ผู้ขาย หมายความว่า ผู้ซื้อสามารถสร้างฐานข้อมูลของตัวเองเอาไว้ เพื่อความสะดวกในการซื้อสินค้าชิ้นเดิมในครั้งต่อๆไปในภายหลัง นั้นเอง

ส่วนในบทความนี้ ผู้เขียนจะพัฒนาในส่วนของ ฐานข้อมูลและการป้อนข้อมูลลงฐานข้อมูลเท่านั้น

ผู้เขียนจะสร้างระบบในการสแกนเพื่อนำมาสินค้ามารวมใน พร้อมแสดงผลออกมาดังรูปภายได้ ในภายหลัง


ร่วมสนับสนุนนักเขียนด้วยการคลิ๊กลิ้ง ด้านล่าง ขอบคุณครับ รับรองไม่มีไวรัส





มาดูตัวอย่างของแอพที่ผู้เขียนพัฒนาขึ้น



 ภาพนี้เป็นสินค้าตัวอย่างไม่ได้ค่าโฆษณาแต่อย่างใด ของแค่ได้ใจของผู้อ่าน ก็พอ ฮิ้ววววว

เอ้า มาต่อ



 เมื่อสแกนเสร็จเราจะเห็นว่า เราได้รหัส ที่อ่านได้ตรงตาม บาร์โค๊ด


มันจะเปลี่ยนหน้าที่นี้ ตามโปรแกรมที่เราเขียนเอาไว้ โดยค่าที่ได้จาก key string ในโค๊ดตัวอย่างในบทที่แล้ว มาใส่ใน Input text นั้นเอง


จากนั้น ก็ระบุรายละเอียดด้วยผู้ซื้อเอง


ดันกดนิ้ว Volume มาด้วย เมื่อกด ตกลง ก็มีข้อความขึ้นมาว่า เพิ่มข้อมูลเสร็จสิ้น เท่านี้ข้อมูลก็เข้าไปอยู่ในฐานข้อมูลเรียบร้อยแล้ว

มาดูตัวอย่างโค๊ดกัน โค๊ดคำสั่งที่สำคัญๆมีอะไรบ้าง

แต่ก่อนอื่นมาลองทำความเข้าใจกับขั้นตอนของระบบกันก่อน หรืออัลกอริทึมนั่นเอง สำหรับผู้ที่สนใจบางท่าน อาจจะมองปุ้ปรู้ปั้ม เหมือนจับวาง หรือเรียกว่า เมพ...ขิงๆ ก็ขออภัยก็แล้วกันนะครับ แต่เพื่อที่บางท่านอาจจะยังใหม่ในการเขียนโปรแกรม (ปล. ผู้เขียนก็ยังใหม่เหมือนกัน สามารถชี้แนะได้น่ะ มาคุยกัน) ผู้เขียนจะขออธิบาย กันลืมเองก็แล้วกัน อยากให้เข้าใจมากกว่า เข้ามาก็อปโค๊ดไปแปะ โปรดใช้วิธีพิมพ์ตาม นะครับ


ร่วมสนับสนุนนักเขียนด้วยการคลิ๊กลิ้ง ด้านล่าง ขอบคุณครับ รับรองไม่มีไวรัส




Step 1. สร้าง Input Text
Step 2. รับค่าตัวแปรที่ได้จาก การสแกนมาเก็บเอาไว้ ในตัวแปร
Step 3. เช็คค่าในช่อง Input เมื่อกด ปุ่ม Button
        Step 3.1 แปลงค่าทุกช่องให้เป็นค่า String
        Step 3.2 Select เลือกฐานข้อมูล
        Step 3.3 Insert ป้อนลงฐานข้อมูล
Step 4. ตั้งค่าใน Input ให้เป็นช่องว่าง แบบค่าสตริง (" ")
Step 5. แจ้งเตือน

ตัวอย่าง code
 
String content = getIntent().getExtras().getString("CONTENT");

barcode.setText(content);
 
 
ในโค๊ดด้านบนนี้ เป็นคำสั่งดึงค่าจาก key String ของการ intent ส่งค่า และ set ค่าในของ Input ด้วยตัวแปรที่เก็บค่าเท่าไว้

โค๊ดทั้งหมด

package com.blogspot.sheepcodeblog.scannerbarcodetodatabase;

import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.database.sqlite.SQLiteDatabase;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class InputData extends ActionBarActivity {

    databaseScanner DBscan;
    SQLiteDatabase db_manage ;

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

        DBscan = new databaseScanner(this);
        db_manage = DBscan.getWritableDatabase();

Step 1.

        final EditText barcode = (EditText) findViewById(R.id.editbarcode);
        final EditText name = (EditText) findViewById(R.id.editname);
        final EditText cost = (EditText) findViewById(R.id.editcost);
        final EditText where = (EditText) findViewById(R.id.editwhere); 
Step 2. 
 
        String content = getIntent().getExtras().getString("CONTENT");

        barcode.setText(content);
 
Step 3.  
 
        Button okey = (Button) findViewById(R.id.buttonok);
        okey.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
 Step 3.1 
               String barcodeString = barcode.getText().toString();
                String nameString = name.getText().toString();
                String costString = cost.getText().toString();
                String whereString = where.getText().toString();
Step 3.2
                 if (barcodeString.length() != 0 && nameString.length() != 0 && costString.length() != 0 && whereString.length() != 0) {
                    Cursor cursor = db_manage.rawQuery("SELECT * FROM " + databaseScanner.TABLE_NAME                            + " WHERE " + databaseScanner.COL_ID + "= '" + barcodeString + "'"                            + " AND " + databaseScanner.COL_NAME + "= '" + nameString + "'"                            + " AND " + databaseScanner.COL_COST + "= '" + costString + "'"                            + " AND " + databaseScanner.COL_WHERE + "= '" + whereString + "'", null);
Step 3.3
                     if (cursor.getCount() == 0) {
                        db_manage.execSQL(" INSERT INTO " + databaseScanner.TABLE_NAME + " ("                                + databaseScanner.COL_ID + ", " + databaseScanner.COL_NAME                                + ", " + databaseScanner.COL_COST + ", " + databaseScanner.COL_WHERE + " ) VALUES ( '"                                + barcodeString + "', '" + nameString + "', '" + costString + "', '" + whereString + "'); ");

Step 4
                       barcode.setText(" ");
                        name.setText(" ");
                        cost.setText(" ");
                        where.setText(" ");
Step 5
                        Toast.makeText(getApplicationContext(), " เพิ่มข้อมูลเสร็จสิ้น ", Toast.LENGTH_LONG).show();
                    } else {
                        Toast.makeText(getApplicationContext(), " มีข้อมูลนี้แล้ว", Toast.LENGTH_LONG).show();
                    }
                } else {
                    Toast.makeText(getApplicationContext(), "กรุณป้อนให้ครบทุกช่อง", Toast.LENGTH_LONG).show();
                }

            }
        });
    }

    public void onStop() {
        super.onStop();
        DBscan.close();
        db_manage.close();
    }


}


โค๊ดตัวอย่าง ฐานข้อมูล

package com.blogspot.sheepcodeblog.scannerbarcodetodatabase;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

/** * Created by sheepcodeblog.blogspot.com on 11/4/15. */public class databaseScanner extends SQLiteOpenHelper {

    private static final String DB_NAME = "scanDb";
    private static final int DB_VERSION = 1;

    public static final String TABLE_NAME = "scanTable";

    public static final String COL_ID = "id_scan";
    public static final String COL_NAME = "name";
    public static final String COL_COST = "cost";
    public static final String COL_WHERE = "date";

    public databaseScanner (Context context) {
        super(context, DB_NAME, null, DB_VERSION);
        // TODO Auto-generated constructor stub    }

    @Override    public void onCreate(SQLiteDatabase db) {
        // TODO Auto-generated method stub
        String create =  "CREATE TABLE " + TABLE_NAME + " (" + COL_ID +" INTEGER PRIMARY KEY, " + COL_NAME + " TEXT, " + COL_COST + " TEXT, " + COL_WHERE + " TEXT);" ;
        String insert = "INSERT INTO " + TABLE_NAME + " (" + COL_ID + " , " + COL_NAME + " , " + COL_COST + " , " + COL_WHERE + " ) VALUES ( '8888','SheepCode','blog','Blogspot.com');";
        db.execSQL(create);
        db.execSQL(insert);

    }

    @Override    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // TODO Auto-generated method stub        db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
        onCreate(db);

    }


}

ตัวอย่างโค๊ด XML 

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:weightSum="1">


<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="125dp"
android:layout_weight="0.44"
android:weightSum="1">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="บันทึกสินค้า"
android:id="@+id/textView"
android:layout_gravity="center_horizontal" />

<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="76dp">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="barcode"
android:id="@+id/txtbarcode" />

<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/editbarcode"
android:layout_gravity="center_horizontal" />
</LinearLayout>

<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">

<TextView
android:layout_width="wrap_content"
android:layout_height="41dp"
android:text="ชื่อสินค้า"
android:id="@+id/txtname" />

<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/editname" />
</LinearLayout>
</LinearLayout>

<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="163dp">

<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="94dp">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="ราคาสินค้า"
android:id="@+id/txtcost" />

<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/editcost" />
</LinearLayout>

<LinearLayout
android:orientation="horizontal"
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/txtwhere" />

<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/editwhere" />
</LinearLayout>
</LinearLayout>

<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="77dp">

<Button
android:layout_width="187dp"
android:layout_height="wrap_content"
android:text="ตกลง"
android:id="@+id/buttonok" />

<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="ยกเลิก"
android:id="@+id/buttoncancel" />
</LinearLayout>

</LinearLayout>




นอกจากนี้ ขอพูดถึงข้อเสียในการทำแอพแบบเสียหน่อย 

ข้อแรกก็คือ ในการทำระบบโดยการใช้ Intent รู้สึกค่อนข้างจะสแกนได้ช้า และการควบคุมโฟกัสช้า ขณะที่ทำการสแกน เมื่อเปรียบเทียบกับ การเปิดแอพ barcode scan โดยตรง แค่สกิดนิดเดียวก็แสดงผลแล้ว ถือว่ายังได้ผลที่ยังไม่ดีนักสำหรับการนำไปใช้ในเชิงธุรกิจ

แต่ยังไม่สามารถบอกได้ 100% เพียงแค่บอกว่า ใช้วิธี Intent นี้แล้ว ช้า...

ถ้าหากลองใช้วิธีนำ library ของ zxing มาต่อยอด ก็อาจจะเร็วขึ้นก็ได้

ข้อสอง คือ ถ้าหากผู้ซื้อนำไปใช้จริงๆแล้วละก็ ค่อนข้างเสียเวลาที่จะต้องสแกนและป้อน ข้อมูลเอง ถ้าหากว่าราคามีการปรับเปลี่ยนอยู่ตลอดเวลา ผู้ใช้คงเซ็งน่าดู ก็ยังถือว่า ยังใช้ไม่ได้



ร่วมสนับสนุนนักเขียนด้วยการคลิ๊กลิ้ง ด้านล่าง ขอบคุณครับ รับรองไม่มีไวรัส



แล้วทำแอพนี้ขึ้นมาทำไม

1. เรียนรู้การใช้ สแกนบาร์โค๊ด
2. รู้ว่า ทำได้จริง แต่ยังไม่ดี ต้องพัฒนาเพิ่ม
3. เอามันส์

ยังไม่จบ 

บทถัดไป จะสแกนแล้วนำมาแสดงผล เป็น ผลรวม โชว์ค่า








วันพฤหัสบดีที่ 5 พฤศจิกายน พ.ศ. 2558

[Project] แอพพลิเคชั่นสแกนบาร์โค๊ดลงฐานข้อมูลด้วยระบบแอนดรอยด์ (1)

บาร์โค๊ดคืออะไร หลายๆคนคงเคยเห็นกันอยู่แล้ว เพราะมันอยู่ในชีวิตประจำตัวเราไม่ใกล้ไม่ไกล เรานี้เอง ไม่ว่าเราจะไปกินอาหาร ซื้อขนม ซื้อนม ซื้อเนย จิปาถะ สินค้าบางตัวก็จะมีติดมากับห่อของมัน หรือ บางทีตอนเราจ่ายเงินค่าอาหารบางร้านก็จะมีบาร์โค๊ด แทรกมาที่ใบเสร็จให้เราอีกด้วย 



แต่จะมีคนรู้หรือสงสัยเบื้องลึกๆของมันหรือไม่ว่า มันถูกสร้างมาอย่างไร มันถูกออกแบบมาเพื่ออะไร มีประโยชน์อะไรบ้าง อย่างเช่น





มันถูกนำมาใช้ประโยชน์ในเรื่องของ การจำหรือการจัดหมวดหมู่ ให้กับทางด้านธุรกิจได้อย่างดีเยี่ยม เวลาที่เราเข้า 7-11 เลือกสินค้าเสร็จ ก็เอามาให้คนขาย เราก็จะเห็น ปืนเลเซอร์ มายิง ดัง "ปิ้ด ปิ้ด" เสร็จ จ่ายตังค์ จบกระบวนการ ซื้อ-ขาย อย่างง่ายดาย หรือเคาท์เตอร์เซอร์วิสเกิดขึ้นมาเพื่อเพิ่มช่องทางในการจ่ายเงินของพ่อค้าหัวใส เช่น มีจดหมายค่าน้ำ ค่าไฟ สมัยนี้ง่ายดาย เห็นบาร์โค๊ด เข้า 7-11 หรือที่ไหนก็ได้ที่มีสัญลักษณ์ เคาท์เตอร์เซอรวิส ยิงบาร์โค๊ด ชำระเงิน จบ รวดเร็ว จริงๆ เรื่องเสียเงิน หึหึ


ร่วมสนับสนุนนักเขียนด้วยการคลิ๊กลิ้ง ด้านล่าง ขอบคุณครับ รับรองไม่มีไวรัส



ถ้าจะสรุปออกมาว่าบาร์โค๊ดคืออะไร แบบวิชาการหน่อยก็ 

บาร์โค้ด หมายถึง "เลขหมายประจำตัวสินค้า ใช้แทนด้วยแท่งบาร์ขาว-ดำ เรียงเข้าด้วยกัน และประกอบด้วยตัวเลข 8-13 หลัก สามารถอ่านได้ด้วยเครื่องสแกนเนอร์ โดยอาศัยหลักของการสะท้อนแสง นิยมใชักับสินค้าอุปโภคบริโภคแทบทุกชนิด และสินค้าสำเร็จรูปต่าง ๆ"

มีประโยชน์หลายอย่าง ได้แก่
1. ลดขั้นตอนและประหยัดเวลาการทำงาน
2. มีความสะดวกรวดเร็วมากขึ้น โดยเฉพาะการรับชำระเงิน การออกใบเสร็จ การตัดสินค้าคงคลัง
3. ง่ายต่อระบบสินค้าคงคลังคอมพิวเตอร์ซึ่งเชื่อมกับเครื่องสแกนเนอร์จะตัดยอดสินค้าโดยอัตโนมัติ 
4. เพิ่มประสิทธิภาพการบริหารสินค้า
5. บริหารงานด้านการผลิต การจัดซื้อ และการตลาดได้อย่างรวดเร็ว และมีประสิทธิภาพ   

ในบทความนี้ ผู้เขียนคงไม่ได้อธิบายรายละเอียดของการสร้างบาร์โค๊ดมากนัก แต่ถ้าผู้มีสนใจอยากรู้รายละเอียดที่มากขึ้น ผู้เขียนแนะนำ เว็บไซต์นี้
เพราะผู้เขียนคิดว่าเว็บไซน์นี้ค่อนข้างระเอียด ที่จะได้ความรู้เกี่ยวกับบาร์โค๊ด ในบทความนี้ผู้เขียนจะ ออกไปทางออกแบบนำเอามาประยุกษ์ใช้ซะมากกว่า ในโปรเจคนี้ จะพัฒนาแอพพลิเคชั่นบนมือถือระบบ Android ใช้ภาษา JAVA 

เครื่องมือที่ใช้พัฒนาได้แก่ 

Android Studio
Asus zenfone 5 android 4.4.2

แนวคิดการออกแบบคือต้องการจะเก็บข้อมูลสินค้า ด้วยการสแกนบาร์โค๊ดจาก บาร์โค๊ดตามสินค้าที่ซื้อเอาไว้ เพื่อเก็บลงฐานข้อมูล และสามารถที่จะสแกนได้อีกครั้งในภายหลัง โดยเมื่อสแกนเสร็จสามารถคิดราคารวมได้

โดยออกแบบหน้าตาของแอพพลิเคชั่นเบื้องต้นไว้ ตามภาพด้านล่าง



ร่วมสนับสนุนนักเขียนด้วยการคลิ๊กลิ้ง ด้านล่าง ขอบคุณครับ รับรองไม่มีไวรัส



ในส่วนของ GUI







ไฟล์ XML

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >

<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="169dp">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Scan barcode for calculate"
android:layout_marginTop="40dp"
android:id="@+id/text"
android:layout_gravity="center_horizontal" />

<Button
android:layout_width="230dp"
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
android:text="สแกนบันทึกข้อมูลสินค้า"
android:onClick="scanBar"
android:id="@+id/scan_barcode_input"
android:layout_gravity="center_horizontal" />
</LinearLayout>

<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="174dp">

<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
android:text="สแกนคำนวนสินค้านวนสินค้า"
android:id="@+id/scan_barcode_caluclation"
android:layout_gravity="center_horizontal" />

</LinearLayout>

<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">

<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
android:text="แนะนำ sheepcodeblog.blogspot.com"
android:id="@+id/go"
android:layout_gravity="center_horizontal" />
</LinearLayout>
</LinearLayout>



ในส่วน class mainactivity 

 
แอพพลิเคชั่น Barcode Scanner 



final String ACTION_SCAN = "com.google.zxing.client.android.SCAN";

สร้างตัวแปรขึ้นมาเก็บ ข้อความสตริงของพาทของแอพพลิเคชั่น สแกนบาร์โค๊ด ขึ้นมา แอพพลิเคชั่นตัวนี้เป็น open source สามารถดาวน์โหลด Library มาได้ แต่ส่วนตัวผู้เขียนคิดใช้วิธี ดาวน์โปรแกรมมาใช้ แล้วเรียกใช้ด้วยวิธี intent จะดีกว่า เพราะไม่จำเป็นต้องพัฒนาเอง

method scanBer

public void scanBar (View v){
    try{
        Intent intent = new Intent(ACTION_SCAN);
        intent.putExtra("SCAN_MODE", "PRODUCT_MODE");
        startActivityForResult(intent, 0);
    }
    catch (ActivityNotFoundException anfe){
        showDialog(MainActivity.this, "No Scanner Found"
        "Download a scanner code activity?","Yes","No").show();
    }
}
 
scanBar method ทำหน้าที่ intent เพื่อกระโดดไปใช้แอพ Barcode Scanner

ใช้การตรวจสอบด้วย Try Catch ถ้ายังไม่มีแอพ Barcode Scanner ให้ถามว่าจะ Download หรือไม่
ใน methode ถัดไป method showDialog

public static AlertDialog showDialog(final Activity act, CharSequence title, CharSequence message, CharSequence buttonYes, CharSequence buttonNo){
    AlertDialog.Builder downloadDialog = new AlertDialog.Builder(act);
    downloadDialog.setTitle(title);
    downloadDialog.setMessage(message);
    downloadDialog.setPositiveButton(buttonYes, new DialogInterface.OnClickListener() {
        @Override        public void onClick(DialogInterface dialogInterface, int i) {
            Uri uri = Uri.parse("market://search?q=pname:" + "com.google.zxing.client.android");
            Intent intent = new Intent(Intent.ACTION_VIEW, uri);
            try{
                act.startActivity(intent);
            }
            catch (ActivityNotFoundException anfe){

            }
        }
    });
    downloadDialog.setNegativeButton(buttonNo, new DialogInterface.OnClickListener() {
        @Override        public void onClick(DialogInterface dialogInterface, int i) {

        }
    });
    return downloadDialog.show();
}

โดยที่ setPositiveButton  คือ กดปุ่ม Dialog ที่เด้งขึ้นมาถาม ในปุ่ม ใช่ ตรงกันข้าม setNegativeButton คือ ปุ่มไม่

สุดท้ายเป็น method ที่รับค่าคืนด้วย intent มาจากแอพ Barcode Scanner มาเก็บ ในตัวแปร content เราก็เอาตัวแปรตัวนี้ ไปทำการเก็บเช่น เก็บลง database

public void onActivityResult(int requestCode, int resultCode, Intent intent){
    if(requestCode == 0){
        if(resultCode == RESULT_OK){
            String content = intent.getStringExtra("SCAN_RESULT");
            String format = intent.getStringExtra("SCAN_RESULT_FORMAT");
        }
    }
}


SCAN_RESULT , SCAN_RESULT_FORMAT คือ ค่าคงที่ ที่เก็บอยู่ใน keyword ที่รับค่า
มาจากแอพ Barcode Scanner
 





ร่วมสนับสนุนนักเขียนด้วยการคลิ๊กลิ้ง ด้านล่าง ขอบคุณครับ รับรองไม่มีไวรัส



บทความถัดไป จะเอาเก็บลง database พร้อม ใส่ระบุรายละเอียดสินค้า เช่น ชื่อ, ราคา, และวันที่

package com.blogspot.sheepcodeblog.scannerbarcodetodatabase;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.ActivityNotFoundException;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;

public class MainActivity extends ActionBarActivity {

    final String ACTION_SCAN = "com.google.zxing.client.android.SCAN";

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

    public void scanBar (View v){
        try{
            Intent intent = new Intent(ACTION_SCAN);
            intent.putExtra("SCAN_MODE", "PRODUCT_MODE");
            startActivityForResult(intent, 0);
        }
        catch (ActivityNotFoundException anfe){
            showDialog(MainActivity.this, "No Scanner Found", "Download a scanner code activity?","Yes","No").show();
        }
    }


    public static AlertDialog showDialog(final Activity act, CharSequence title, CharSequence message, CharSequence buttonYes, CharSequence buttonNo){
        AlertDialog.Builder downloadDialog = new AlertDialog.Builder(act);
        downloadDialog.setTitle(title);
        downloadDialog.setMessage(message);
        downloadDialog.setPositiveButton(buttonYes, new DialogInterface.OnClickListener() {
            @Override            public void onClick(DialogInterface dialogInterface, int i) {
                Uri uri = Uri.parse("market://search?q=pname:" + "com.google.zxing.client.android");
                Intent intent = new Intent(Intent.ACTION_VIEW, uri);
                try{
                    act.startActivity(intent);
                }
                catch (ActivityNotFoundException anfe){

                }
            }
        });
        downloadDialog.setNegativeButton(buttonNo, new DialogInterface.OnClickListener() {
            @Override            public void onClick(DialogInterface dialogInterface, int i) {

            }
        });
        return downloadDialog.show();
    }

    public void onActivityResult(int requestCode, int resultCode, Intent intent){
        if(requestCode == 0){
            if(resultCode == RESULT_OK){
                String content = intent.getStringExtra("SCAN_RESULT");
                //String format = intent.getStringExtra("SCAN_RESULT_FORMAT");
                            }
        }
    }
}


Referrence 


http://www.pen1.biz/TipBarcode.html 
http://www.dek-d.com/board/view/1462138/ 
http://www.rightsoftcorp.com/?name=news&file=readnews&id=8 
http://tamanmohamed.blogspot.com/2012/02/barcode-professional-java-bar-code-api.html
http://examples.javacodegeeks.com/android/android-barcode-and-qr-scanner-example/

วันศุกร์ที่ 30 ตุลาคม พ.ศ. 2558

[Project] แอพพลิเคชั่นจำศัพท์ แบบง่ายๆ ในนาม Vocab Card

ในยุคปัจจุบันภาษาอังกฤษนับว่าเป็นภาษาที่ เรียกได้ว่าเป็นภาษาที่สำคัญ หรือเป็นภาษาที่สองไปเสียแล้ว ในการสื่อสารยุคนี้ เพราะฉะนั้น หากได้รับการฝึกฝนตั้งแต่วัยเยาว์ก็จะได้เปรียบเป็นอย่างมากเพราะ เมมโมรี่ของสมองยังว่างพอที่จะจับยัดคำศัพท์เข้าไปได้มากๆ ด้วยการท่องจำ แต่หากว่ามาฝึกฝนตอนวัยชาน(ชรา) แล้วนั้นวิธีที่สอนเด็กๆ เช่น การท่องจำก็คงจะไม่เข้าหัวกันอีกต่อไป อย่างผู้เขียนก็เช่นกัน เคยฝึกแบบท่องวันละ 10 คำ 20 คำ แต่สมองก็ไม่จำสักที แล้วก็เบื่อไปในที่สุด ที่พอจะรับได้ก็ต้องใช้เวลามากกว่า เด็กๆ อายุน้อยๆ 

ผู้เขียนจึงเปลี่ยนวิธีมาเป็นการ อ่านกวาด(Scanning) เพื่อดูว่าคำศัพท์คำไหนที่ยังไม่รู้ หรือยังจำไม่ได้ ก็จดเอาไว้ก่อนแล้วจึงเอามาแปลทีหลัง เมื่อแปลคำศัพท์แล้วก็ เอามาอ่านอีกรอบพร้อมกับ ดูคำศัพท์ แต่การใช้วิธีนี้ ผู้เขียนคิดว่าจะต้องรู้ grammar พอสมควรถึงจะอ่านสนุก เป็นเทคนิคส่วนตัวสำหรับผู้เขียนอะน่ะ ก็ใครถนัดแบบไหนควรหาให้เจอด้วยตัวเอง 


พอผู้เขียนใช้วิธีนี้แล้วเนี่ย ปัญหาใหญ่ที่สุดเลยก็คือ ลายมือไม่สวย @@ 
.
.
.
ก็ส่วนหนึ่ง ฮ่าๆ 

อันที่จริงแล้ว คือ อ่านๆไปก็เจอคำศัพท์ ที่เจอแล้ว เจออีก เจอซ้ำ เจอซาก 

เจอจนจำได้ เอ่อ...แล้วมันไม่ดีตรงไหนหรือเปล่า บ่นซะ

ก็เอาเป็นว่าผู้เขียน ก็ได้ไอเดียว่า จะทำอย่างไรดีน่ะ ที่จะบันทึกคำศัพท์ ที่ตัวเรายังจำไม่ได้ แล้วก็ไม่ต้องบันทึกซ้ำมันอีก สามารถเก็บอยู่ในที่เดียวกัน 

อืมมม คิด คิด คิด ..... จดลงกระดาษ ก็เก็บไม่หมด จดลงสมุดก็แล้ว ใหญ่ไป ถือไม่ถนัด 

เอาเป็นว่า ขายเลยแล้วกัน จูงใจกันมาหลายบรรทัดแล้ว กับทีวีไดเร็ค ขอนำเสนอ แอพพลิเคชั่น Android ชื่อ Vocab Card 

จอร์น : สวัสดีซ่ารา

ซ่าร่า : ว่าไงค่ะจอร์น


ร่วมสนับสนุนนักเขียนด้วยการคลิ๊กลิ้ง ด้านล่าง ขอบคุณครับ รับรองไม่มีไวรัส


ร่วมสนับสนุนนักเขียนด้วยการคลิ๊กลิ้ง ด้านล่าง ขอบคุณครับ รับรองไม่มีไวรัส



เหตุผลที่ ผู้เขียนตั้งชื่อว่า Vocab Card ก็มีที่มาจากว่า เทคนิคของบางคนในการฝึกภาษา ก็จะใช้วิธี เปิด การ์ดคำศัพท์มานั่งอ่านในเวลาว่าง






ผู้เขียนจึงเกิดไอเดียขึ้นมาทันที ก็เช่นเคยว่า วาดระบบขึ้นมาก่อนจะทำโครงงานอะไรสักอย่าง





ไก่เขี่ยมากๆ 

ก็จะแบ่งเป็น สามฟังก์ชัน ได้แก่ ป้อนคำศัพท์ เปิดคำศัพท์ และลบคำศัพท์

เมื่อกดปุ่มป้อนคำศัพท์ก็จะแสดงผลออกในหน้านี้


ในการป้อนข้อมูลนั้นเป็นการใส่ตามใจผู้ใช้ได้เลย

เมื่อกดตกลง ก็จะแสดง alert ขึ้นมาว่า เพิ่มคำศัพท์เสร็จสิ้น


เมื่อมีป้อนก็ต้องมีเปิด ออกไปหน้าแรก แล้วก็กดปุ่ม เปิดคำศัพท์จะได้หน้านี้ทันที

 เราสามารถที่จะกดดูเพื่อความชัดเจน ที่ใหญ่ขึ้นได้



เมื่อเราไม่ต้องการคำศัพท์คำนี้แล้ว เพราะ เราจำได้แล้ว ก็สามารถที่จะลบคำๆนั้นออกจากฐานข้อมูลของเรา ก็เช่นเดิมออกไปหน้าแรกแล้ว ก็กด ลบคำศัพท์
เมื่อเข้ามาจะมีหน้าตาที่ไม่ต่างกับ ปุ่มเปิดคำศัพท์เลยอย่างกะฝาแฝด พูดง่ายๆ codeโปรแกรมเหมือนกัน อย่างกะแกะ (Sheep Code) อย่าเข้าใจผิดว่าไปก็อปเขามาล่ะ ผิดกฎหมายเด้อ.... 


ร่วมสนับสนุนนักเขียนด้วยการคลิ๊กลิ้ง ด้านล่าง ขอบคุณครับ รับรองไม่มีไวรัส




ก็เมื่อกดที่คำศัพท์คำที่เราไม่ต้องการ ก็จะมี ไดอะล็อกขึ้นมาถามเราว่าจะลบหรือไม่นั้นเอง


เมื่อกด ใช่ ก็จะขึ้น alert ขึ้นมาว่า ลบคำศัพท์เสร็จสิ้น


ออกจากหน้าเดิมก่อน แล้วค่อยกลับมาเปิดอีกที จึงจะหายไป.....
เท่านี้ละครับ โปรแกรมตัวนี้

จริงๆแล้ว สำหรับ นักพัฒนา Android ที่คุ้นเคยกับแอพพลิเคชั่นแบบนี้ก็คงจะทำเองได้ไม่ยาก เพราะก็แค่ มี Input เข้าไปใน database แล้ว Select ออกมาโชว์บน ListView เท่านี้ก็เสร็จแล้ว

ก็ผู้เขียนมี Link ให้ download Application ตัวนี้ไว้ให้ เพื่อว่าบางคนอยากได้เอาไปใช้ ตามนี้เลยครับ VocabCard[google Drive]

หรือหากว่าใครอยากจะเอา Code ไปพัฒนาต่อก็ Link นี้ครับ 
SourceCode_VoCab[googleDrive] 

ขอขอบคุณ คุณเอก Android( GDE ) แห่ง Android~Sleepless for less

http://www.akexorcist.com/2013/02/android-code-cursor-sqlite.html
http://www.akexorcist.com/2013/01/android-code-query-sqlite.html 





 
 
Blogger Templates