บทความนี้จะมีเนื้อหาเกี่ยวกับ Firebase Realtime Database, Firebase Storage, Firebase Crash, Drawer Menu, Fragment, Custom ListView, Camera,Glide และอื่นๆสัพเพเหระ ออกตัวไว้ก่อนคือผมอธิบายไม่ค่อยเก่งนะครับ ดังนั้นเน้นดู Code แล้วจิ้นกันเอาเองเนาะ 5555

เริ่มกันเลยดีกว่า เราจะมาสร้างแอปที่มีรายละเอียดดังต่อไปนี้

  • หน้า ListView เอาไว้แสดง Content ซึ่งมี Header, Content,  TimeStamp, Image
  • สามารถ Create, Read, Update, Delete ได้

สร้างโปรเจคให้มี Navigation Drawer หรือดูจากบทความนี้ How to Add a Navigation Drawer and Implement Fragment

สร้างไฟล์ MainFragment.java โดยมีโครงสร้างดังนี้

public class MainFragment extends Fragment {

    public MainFragment() {
        super();
    }

    public static MainFragment newInstance(){
        MainFragment fragment = new MainFragment();
        Bundle args = new Bundle();
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onStart() {
        super.onStart();
    }

    @Override
    public void onStop() {
        super.onStop();
    }

    /*
     * Save Instance State Here
     */
    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        // Save Instance State here
    }

    /*
     * Restore Instance State Here
     */
    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        if (savedInstanceState != null) {
            // Restore Instance State here
        }
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_main, container, false);
        return rootView;
    }
}

สร้าง layout ไฟล์ flagment_main.xml ให้มี ListView และ Floating Action Button

 

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

    <ListView
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentRight="true"
        android:layout_margin="@dimen/fab_margin"
        app:srcCompat="@android:drawable/ic_input_add" />

</RelativeLayout>

ใน MainActivity.java ทำการเพิ่มเมธอด initFragment เพื่อให้ MainFragment เปิดอัตโนมัติเป็น Fragment แรก

   private void initFragment(Bundle savedInstanceState) {
        if (savedInstanceState == null) {
            getSupportFragmentManager().beginTransaction()
                    .add(R.id.contentContainer, MainFragment.newInstance())
                    .commit();
        }
    }

ที่ไฟล์ activity_main_drawer.xml แก้ไขให้เหลือเมนูเดียวคือ Firebase News

 

ที่ MainActivity.java เพิ่มเมธอด openMainFragment เพื่อให้เมื่อกดเมนู Fragment News ที่ Drawer Menu แล้วแสดง MainFragment

      private void openMainFragment() {
        Fragment fragment = getSupportFragmentManager()
                .findFragmentById(R.id.contentContainer);

        if (fragment instanceof MainFragment == false) {
            getSupportFragmentManager().beginTransaction()
                    .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
                    .replace(R.id.contentContainer,
                            MainFragment.newInstance())
                    .addToBackStack(null)
                    .commit();
        }
    }

 

ลองทดสอบ Run App ดู เมื่อกด  Hamberger Button จะมี  Drawer Menu โผล่ออกมา

 

ต่อไปคือการสร้าง Custom Listview มีตัวอย่างทำไว้ในบทความที่แล้วเรื่อง How to create custom listview

อันดับแรกเรามา Design UI  ของ ListView กันก่อน โดย New Layout กำหนดชื่อว่า Create news_list_item.xml  พร้อมจัดให้มี ImageVew และ TextView ตามรูป หรือจะจัดยังไงก็ได้เอาที่สบายใจ 😛 แต่ขอให้มีรูปกับข้อความ เพราะเราจะไป Sync กับ Firebase

 

เพิ่มไลบรารี่ Glide เพื่อช่วยในการจัดการรูปภาพลงไปใน  build.gradle

dependencies {
  
    compile 'com.github.bumptech.glide:glide:3.7.0'
 
}

 

Create NewsListItem.java โดย extends จาก Class BaseCustomViewGroup (สามารถ download ได้จาก github) ทำการ findById Instance เพื่อผูก Instance กับ Layout และ สร้างเมธอด Set สำหรับ Adapter ต่อไป

public class NewsListItem extends BaseCustomViewGroup {

    private TextView tvHeader;
    private TextView tvDate;
    private TextView tvContent;
    private ImageView imgView;
    private TextView tvId;

    public NewsListItem(Context context) {
        super(context);
        initInflate();
        initInstances();
    }

    public NewsListItem(Context context, AttributeSet attrs) {
        super(context, attrs);
        initInflate();
        initInstances();
        initWithAttrs(attrs, 0, 0);
    }

    public NewsListItem(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initInflate();
        initInstances();
        initWithAttrs(attrs, defStyleAttr, 0);
    }

    @TargetApi(21)
    public NewsListItem(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        initInflate();
        initInstances();
        initWithAttrs(attrs, defStyleAttr, defStyleRes);
    }

    private void initInflate() {
        inflate(getContext(), R.layout.news_list_item, this);
    }

    private void initInstances() {
        tvId = (TextView) findViewById(R.id.tvId);
        tvHeader = (TextView) findViewById(R.id.tvHeader);
        tvDate = (TextView) findViewById(R.id.tvDate);
        tvContent = (TextView) findViewById(R.id.tvContent);
        imgView = (ImageView) findViewById(R.id.imgView);

    }

    private void initWithAttrs(AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        /*
        TypedArray a = getContext().getTheme().obtainStyledAttributes(
                attrs,
                R.styleable.StyleableName,
                defStyleAttr, defStyleRes);

        try {

        } finally {
            a.recycle();
        }
        */
    }

    @Override
    protected Parcelable onSaveInstanceState() {
        Parcelable superState = super.onSaveInstanceState();

        BundleSavedState savedState = new BundleSavedState(superState);
        // Save Instance State(s) here to the 'savedState.getBundle()'
        // for example,
        // savedState.getBundle().putString("key", value);

        return savedState;
    }

    @Override
    protected void onRestoreInstanceState(Parcelable state) {
        BundleSavedState ss = (BundleSavedState) state;
        super.onRestoreInstanceState(ss.getSuperState());

        Bundle bundle = ss.getBundle();
        // Restore State from bundle here
    }

    public void setTvId(String text) {
        tvId.setText(text);
    }

    public void setTvHeader(String text) {
        tvHeader.setText(text);
    }

    public void setTvDate(String text) {
        tvDate.setText(text);
    }

    public void setTvContent(String text) {
        tvContent.setText(text);
    }

    public void setImgView(String path) {
        Glide.with(getContext())
                .load(path)
                .placeholder(loading)
                .diskCacheStrategy(DiskCacheStrategy.ALL)
//                .skipMemoryCache(true)
                .into(imgView);
    }

}

 

สร้างData Access Object ใช้ชื่อว่า NewsDao.java โดยกำหนดให้ implements เป็น Parcelable พร้อมทั้ง Generate Getter and Setter

public class NewsDao implements Parcelable {
    private String newsId;
    private String header;
    private String content;
    private String imagePath;
    private String date;

    public NewsDao() {
    }

    protected NewsDao(Parcel in) {
        newsId = in.readString();
        header = in.readString();
        content = in.readString();
        imagePath = in.readString();
        date = in.readString();
    }

    public static final Creator<NewsDao> CREATOR = new Creator<NewsDao>() {
        @Override
        public NewsDao createFromParcel(Parcel in) {
            return new NewsDao(in);
        }

        @Override
        public NewsDao[] newArray(int size) {
            return new NewsDao[size];
        }
    };

    public String getNewsId() {
        return newsId;
    }

    public void setNewsId(String newsId) {
        this.newsId = newsId;
    }

    public String getHeader() {
        return header;
    }

    public void setHeader(String header) {
        this.header = header;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public String getImagePath() {
        return imagePath;
    }

    public void setImagePath(String imgPath) {
        this.imagePath = imgPath;
    }

    public String getDate() {
        return date;
    }

    public void setDate(String date) {
        this.date = date;
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel parcel, int i) {
        parcel.writeString(newsId);
        parcel.writeString(header);
        parcel.writeString(content);
        parcel.writeString(imagePath);
        parcel.writeString(date);
    }
}

สร้าง Adapter ใช้ชื่อว่า NewsAdapter.java โดย

1. เพิ่ม extends  BaseAdapter จากนั้นก็ Auto Generate method

public class NewsAdapter extends BaseAdapter

2. สร้างฟิลด์ของคลาสด้วย NewsDao โดยกำหนดชนิดข้อมูลเป็น List เพื่อเก็บข้อมูลที่ดึงมาจาก Firebase

List<NewsDao> newsList;

3. ที่เมธอด getCount ส่งค่าขนาดของ Object ที่ดึงมาเก็บไว้ใน NewsList

    public int getCount() {
        if (newsList == null)
            return 0;
        return newsList.size();
    }

4. ที่เมธอด getView นำค่าที่เก็บไว้ใน newsList ส่งไปแสดงผลที่  NewsListItem ที่สร้างไว้

 public View getView(int position, View view, ViewGroup viewGroup) {
        NewsListItem item;
        if (view != null)
            item = (NewsListItem) view;
        else
            item = new NewsListItem(viewGroup.getContext());

        NewsDao dao = newsList.get(position);

        item.setTvId(dao.getNewsId());
        item.setTvHeader(dao.getHeader());
        item.setTvDate(dao.getDate());
        item.setTvContent(dao.getContent());

        item.setImgView(dao.getImgPath());

        return item;
    }

NewsAdapter.java

public class NewsAdapter extends BaseAdapter {
    List<NewsDao> newsList;

    public NewsAdapter(List<NewsDao> newsList) {
        this.newsList = newsList;
    }

    @Override
    public int getCount() {
        if (newsList == null)
            return 0;
        return newsList.size();
    }

    @Override
    public Object getItem(int i) {
        return null;
    }

    @Override
    public long getItemId(int i) {
        return 0;
    }

    @Override
    public View getView(int position, View view, ViewGroup viewGroup) {
        NewsListItem item;
        if (view != null)
            item = (NewsListItem) view;
        else
            item = new NewsListItem(viewGroup.getContext());

        NewsDao dao = newsList.get(position);

        item.setTvId(dao.getNewsId());
        item.setTvHeader(dao.getHeader());
        item.setTvDate(dao.getDate());
        item.setTvContent(dao.getContent());

        item.setImgView(dao.getImgPath());

        return item;
    }
}

ติดตั้ง Firebase และ เพิ่ม Firebase ลงในโปรเจค ดูจากบทความ แนะนำการใช้งาน Firebase และสร้างแอป Android ติดต่อ Firebase Database

Add the dependency for Firebase Realtime Database to your app-level build.gradle file:

compile 'com.google.firebase:firebase-database:11.0.1'

Add the dependency for Firebase Storage to your app-level build.gradle file:

compile 'com.google.firebase:firebase-storage:11.0.1'

สร้างคลาส FirebaseConection.java

public class FirebaseConnection {
    public FirebaseConnection() {
    }

    public DatabaseReference getDatabase() {
        return FirebaseDatabase.getInstance().getReference();
    }

    public DatabaseReference getDatabase(String string) {
        return FirebaseDatabase.getInstance().getReference().child(string);
    }

    public StorageReference getStorage() {
        return FirebaseStorage.getInstance().getReference();
    }

    public StorageReference getStorage(String string) {
        return FirebaseStorage.getInstance().getReference().child(string);
    }

}

กลับมาที่ MainFragment.java

สร้างเมธอด initInstances() เพื่อผูกกับ Object ใน Layer

private void initInstances(View rootView) {
    listView = (ListView) rootView.findViewById(R.id.listView);
    newsList = new ArrayList<>();

}

สร้างเมธอด showData() เพื่อทำการดึงข้อมูลมาจาก Firebase Database จากนั้นส่งไปแสดงใน ListView

   private void showData(){
        Query query = firebase.getDatabase("news");
        query.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                newsList.clear();
                for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
                    NewsDao dao = postSnapshot.getValue(NewsDao.class);
                    newsList.add(dao);
                }
                adapter = new NewsAdapter(newsList);
                listView.setAdapter(adapter);
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {

            }
        });
    }

เพิ่มเมธอด showData() ลงไปใน onCreateView เพื่อให้ดึงข้อมูลจาก firebase มาแสดงอัตโนมัติเมื่อเปิดหน้า  MainFragment

 

เนื่องจากใน Realtime Database ยังไม่มีข้อมูล  ในที่นี้ผมใช้ Postman ส่ง  news.json Post เข้าไปยัง Firebase

 

เมื่อ Post สำเร็จ ใน Realtime Database ก็จะแสดงข้อมูล json ที่ส่งเข้าไป

ทดสอบ Run App ข้อมูลก็จะขึ้นที่ ListView

ขั้นต่อไปเราจะทำการสร้างหน้าเพิ่มข้อมูล โดยออกแบบดังนี้

1.ให้สามารถเพิ่มข้อมูลที่เป็น Text และ Image

2.มีปุ่ม Save , Update , Delete

สร้างไฟล์ Layout ที่ชื่อว่า fragment_add.xml

 

สร้างไฟล์ addFragment.java ตามโครงสร้าง และทำการ Inflate กับ Layout fragment_add.xml ให้เรียบร้อย

public class AddFragment extends Fragment {

    public AddFragment() {
        super();
    }

    public static AddFragment newInstance() {
        AddFragment fragment = new AddFragment();
        Bundle args = new Bundle();
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_add, container, false);
        initInstances(rootView);
        return rootView;
    }

    private void initInstances(View rootView) {
        // Init 'View' instance(s) with rootView.findViewById here
    }

    @Override
    public void onStart() {
        super.onStart();
    }

    @Override
    public void onStop() {
        super.onStop();
    }

    /*
     * Save Instance State Here
     */
    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        // Save Instance State here
    }

    /*
     * Restore Instance State Here
     */
    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        if (savedInstanceState != null) {
            // Restore Instance State here
        }
    }
}

สร้าง Layout Activity ชื่อ activity_add.xml และเพิ่ม FramLayout เพื่อรอ Fragment มาแปะ

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.tntadvance.testfirebasecrud.activity.AddActivity">
    
    <FrameLayout
        android:id="@+id/contentContainer"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</android.support.constraint.ConstraintLayout>

เลือก New->Activity->Empty Activity

ตั้งชื่อว่า AddActivity จะได้ไฟล์ addActivity.java และ activity_add.xml

ที่ไฟล์ activity_add.xml ให้เพิ่ม FramLayout และตั้ง id เป็น ContentContainer เพื่อรอ Fragment มาแปะ

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.tntadvance.testfirebasecrud.activity.AddActivity">
    
    <FrameLayout
        android:id="@+id/contentContainer"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</android.support.constraint.ConstraintLayout>

ที่ไฟล์ AddActivity.java

1.สร้างเมธอด initFragment() เพื่อสั่งให้ AddFragment มาแปะบน ContentContainer

   private void initFragment(Bundle savedInstanceState, NewsDao dao) {
        if (savedInstanceState == null) {
            getSupportFragmentManager().beginTransaction()
                    .add(R.id.contentContainer, AddFragment.newInstance(dao))
                    .commit();
        }
    }

2.สร้างเมธอด initInstance เพื่อเพิ่มปุ่ม Up Button

   private void initInstances() {
        getSupportActionBar().setDisplayShowHomeEnabled(true);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    }

AddActivity.java

public class AddActivity extends AppCompatActivity {

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

        initInstances();
        initFragment(savedInstanceState);
    }

    private void initInstances() {
        getSupportActionBar().setDisplayShowHomeEnabled(true);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    }


    private void initFragment(Bundle savedInstanceState) {
        if (savedInstanceState == null) {
            getSupportFragmentManager().beginTransaction()
                    .add(R.id.contentContainer, AddFragment.newInstance())
                    .commit();
        }
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item.getItemId() == android.R.id.home){
            finish();
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
}

ต่อไปเป็นการเพิ่มคำสั่งที่ให้ปุ่ม Floating Action เปิดหน้าเพิ่มข้อมูล

เนื่องจากปุ่มอยู่ใน  MainFragment ซึ่งแปะอยู่บน MainActivity แต่ AddFragment ที่ต้องการเปิดจะแปะอยู่บน AddActivity เราจึงต้องทำดังนี้

1. Implement Interface FragmentListener บน  MainFragment.java พร้อมสร้างเมธอด openAddFragment() เพื่อไปเรียกใช้ onItemListClicked บน MainActivity พร้อมส่ง NewsDao แนบไปด้วย

   //implement interface
    public interface FragmentListener {
        void onItemListClicked(NewsDao dao);
    }

    private void openAddFragment(){
        NewsDao dao = new NewsDao();

        FragmentListener listener = (FragmentListener) getActivity();
        listener.onItemListClicked(dao);
    }

2.Implement FragmentListener in MainActivity

สร้างเมธอดจาก Interface คือ onItemListClicked เพื่อสั่ง Intent ให้เปิด AddActivity พร้อมแนบ NewsDao ไปด้วย

   @Override
    public void onItemListClicked(NewsDao dao) {
        Intent intent = new Intent(MainActivity.this,AddActivity.class);
        intent.putExtra("dao",dao);
        startActivity(intent);
    }

3.เพิ่มคำสั่ง getIntent() ที่ AddActivity.java เพื่อรับค่า NewsDao

NewsDao dao = getIntent().getParcelableExtra("dao");

และส่ง NewsDao ต่อไปเปิดใน AddFragment

initFragment(savedInstanceState, dao);
   private void initFragment(Bundle savedInstanceState, NewsDao dao) {
        if (savedInstanceState == null) {
            getSupportFragmentManager().beginTransaction()
                    .add(R.id.contentContainer, AddFragment.newInstance(dao))
                    .commit();
        }
    }

เปิด AddFragment.java เพิ่มการรับค่า NewsDao

รับค่า NewsDao ที่เมธอด onCreate

Test Run App

ทดสอบ Click ปุ่มเพิ่มข้อมูลจะเปิดหน้าเพิ่มข้อมูลขึ้นมา  จากนั้น Click Up Button  เพื่อกลับหน้าหลัก

 

เนื่องจากตอน Clck ปุ่มเพิ่มข้อมูล NewsDao จะไม่มีข้อมูลจึงเปิดหน้าว่างขึ้นมา

ขั้นต่อไปเราจะมาทำเมื่อ Click  ที่ Listview ให้ส่งข้อมูลไปยัง AddFragment เพื่อแก้ไขข้อมูล

ที่ไฟล์ MainFragment เพิ่ม setOnClickListener ให้กับ Listview

               listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                    @Override
                    public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                        NewsDao dao = newsList.get(i);

                        FragmentListener listener = (FragmentListener) getActivity();
                        listener.onItemListClicked(dao);
                    }
                });

 

นำข้อมูลที่เก็บไว้ใน NewsDao  มาใส่ที่ Object และเช็คก่ีแสดงผลให้ปุ่ม Save , Update ,Delete

   private void checkData(){
        dao = getArguments().getParcelable("dao");

        id = dao.getNewsId();
        header = dao.getHeader();
        content = dao.getContent();
        path = dao.getImagePath();

        if (!TextUtils.isEmpty(header)) {
            getActivity().setTitle(header);
            edHeader.setText(header);
            edContent.setText(content);
            tvPath.setText(path);

            Glide.with(getContext())
                    .load(path)
                    .placeholder(default1)
                    .diskCacheStrategy(DiskCacheStrategy.ALL)
//                .skipMemoryCache(true)
                    .into(imgView);

            btnSave.setVisibility(View.GONE);
            btnUpdate.setVisibility(View.VISIBLE);
            btnDelete.setVisibility(View.VISIBLE);

        } else {
            btnSave.setVisibility(View.VISIBLE);
            btnUpdate.setVisibility(View.GONE);
            btnDelete.setVisibility(View.GONE);
        }
    }

ทดสอบ Run App  เมื่อกดที่  Listview จะเปิด AddFragment โดยมีข้อมูลแสดที่หน้าจอ

ต่อไปเป็นการเพิ่มรูปโดยการถ่ายรูปหรือเลือกรูปจาก

(ตัวอย่าง Code : https://github.com/thana19/testCamera )

เพิ่มเมธอด addImage ที่ AddFragment.java ดังนี้

   private void addImage() {
        final String[] items = new String[]{"Take from camera", "Select from gallery"};
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.select_dialog_item, items);
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());

        builder.setTitle("Select Image");
        builder.setAdapter(adapter, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int item) {
                //pick from camera
                if (item == 0) {
                    Log.d("camera", "camera");
                    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

                    try {
                        intent.putExtra("return-data", true);

                        startActivityForResult(intent, PICK_FROM_CAMERA);
                    } catch (ActivityNotFoundException e) {
                        e.printStackTrace();
                    }
                } else {
                    //pick from file
                    if (Build.VERSION.SDK_INT < 19) {
                        Intent intent = new Intent();

                        intent.setType("image/*");
                        intent.setAction(Intent.ACTION_GET_CONTENT);

                        startActivityForResult(Intent.createChooser(intent, "Complete action using"), PICK_FROM_FILE);

                    } else {

                        Intent intent = new Intent(Intent.ACTION_PICK);
                        intent.setType("image/*");

                        startActivityForResult(Intent.createChooser(intent, "Complete action using"), PICK_FROM_FILE);
                    }
                }
            }
        });

        final AlertDialog dialog = builder.create();
        dialog.show();
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode != -1) return;

        switch (requestCode) {
            case PICK_FROM_CAMERA:
                mImageCaptureUri = data.getData();
                doCrop();
                break;

            case PICK_FROM_FILE:
                mImageCaptureUri = data.getData();
                doCrop();
                break;

            case CROP_FROM_CAMERA:
                Bundle extras = data.getExtras();

                if (extras != null) {
                    bitmapCrop = extras.getParcelable("data");
                    imgView.setImageBitmap(bitmapCrop);
                }

                break;
        }
    }

    private void doCrop() {
        Intent intent = new Intent("com.android.camera.action.CROP");
        intent.setType("image/*");

        List<ResolveInfo> list = getActivity().getPackageManager().queryIntentActivities(intent, 0);

        int size = list.size();

        if (size == 0) {
            Toast.makeText(getActivity(), "Can not find image crop app", Toast.LENGTH_SHORT).show();
        } else {
            intent.setData(mImageCaptureUri);

            intent.putExtra("outputX", 600);
            intent.putExtra("outputY", 600);
            intent.putExtra("aspectX", 6);
            intent.putExtra("aspectY", 6);
            intent.putExtra("scale", true);
            intent.putExtra("return-data", true);

            Intent i = new Intent(intent);
            ResolveInfo res = list.get(0);
            i.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));

            startActivityForResult(i, CROP_FROM_CAMERA);
        }
    }

เพิ่มข้อมูลไปยัง Firebase Realtime Database & Storage

    private void addData() {
        id = firebase.getDatabase("news").push().getKey();
        header = edHeader.getText().toString();
        content = edContent.getText().toString();

        NewsDao dao = new NewsDao();
        dao.setNewsId(id);
        dao.setHeader(header);
        dao.setContent(content);
        dao.setDate(dateUtil.currentTimeStamp());

        uploadFromDataInMemory(dao);
    }

    private void uploadFromDataInMemory(final NewsDao dao) {
        // Get the data from an ImageView as bytes
        imgView.setDrawingCacheEnabled(true);
        imgView.buildDrawingCache();
        Bitmap bitmap = imgView.getDrawingCache();
        ByteArrayOutputStream baos = new ByteArrayOutputStream();

        bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
        byte[] data = baos.toByteArray();

        UploadTask uploadTask = firebase.getStorage("news/" + id + "/" + dateUtil.currentTimeStamp() + ".png").putBytes(data);
        uploadTask.addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>() {
            @Override
            public void onProgress(UploadTask.TaskSnapshot taskSnapshot) {
                @SuppressWarnings("VisibleForTests") double progress = (100.0 * taskSnapshot.getBytesTransferred()) / taskSnapshot.getTotalByteCount();
                Log.d("progress", "Upload is " + progress + "% done");

            }
        }).addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {

            }
        }).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
            @Override
            public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
                @SuppressWarnings("VisibleForTests") Uri downloadUrl = taskSnapshot.getDownloadUrl();
                tvPath.setText(downloadUrl.toString());
                dao.setImagePath(downloadUrl.toString());
                firebase.getDatabase("news").child(id).setValue(dao);

                Toast.makeText(getActivity(), "Upload Complete", Toast.LENGTH_LONG).show();
                getActivity().finish();
            }
        });

    }

 

 

ลบข้อมูล

   private void deleteData() {
        //removing
        firebase.getDatabase("news").child(id).removeValue();

        getActivity().finish();
        Toast.makeText(getActivity(), "ANews Deleted", Toast.LENGTH_LONG).show();
    }

 

Update ข้อมูล

   private void updateData() {
        if (bitmapCrop != null) {
            NewsDao dao = new NewsDao();
            dao.setNewsId(id);
            dao.setHeader(header);
            dao.setContent(content);
            dao.setDate(dateUtil.currentTimeStamp());

            uploadFromDataInMemory(dao);
        } else {
            Toast.makeText(getActivity(), "Do not change image", Toast.LENGTH_LONG).show();

            HashMap<String, Object> postValues = new HashMap<>();
            postValues.put("header", edHeader.getText().toString());
            postValues.put("content", edContent.getText().toString());

            firebase.getDatabase("news").child(id).updateChildren(postValues);

            getActivity().finish();
        }
    }

หลังๆไม่รู้จะอธิบายยังไง จริงๆขี้เกียจแล้ว 55555 ก็ขอตัดจบเพียงเท่านี้นะครับ สวัสดี

* ถ้าว่างๆจะกลับมา update เนื้อหาในส่วน firebase นะครับ

ตัวอย่าง code สามารถดาวน์โหลดไปแกะเล่นได้ที่ : https://github.com/thana19/FirebaseNews

 

 

สร้างแอป Android เพื่อทดสอบการใช้งาน Firebase Realtime Database & Firebase Storage

Comments

comments

Tagged on: