2015年12月18日 星期五

Android-判斷手機 網路 藍芽 狀態

手機裝置狀態
Check Cellphone State : Bluetooth、NetWork

權限
<!-- 藍芽 -->
<uses-permission android:name="android.permission.BLUETOOTH" />

<!-- 網路 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />


import android.bluetooth.BluetoothAdapter;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
/**
 * 裝置狀態
 */
public class DeviceState {

    /** 網路是否連線 */
    public static boolean isNetWorkConnection(Context context){

        boolean isConnection = false;

        ConnectivityManager mConnectivityManager = 
                (ConnectivityManager) context.getApplicationContext()
                .getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo mNetworkInfo = mConnectivityManager.getActiveNetworkInfo();

        if(mNetworkInfo != null)
            if(mNetworkInfo.isConnected())
                isConnection = true;

        return isConnection;
    }

    /** 裝置是否支援低功率藍芽 */
    public static boolean isSupportBle(){

        boolean isSupport = false;

        BluetoothAdapter mBluetoothAdapter = 
                BluetoothAdapter.getDefaultAdapter();

        if (mBluetoothAdapter != null) 
            isSupport = true;

        return isSupport;
    }

}

參考資料 : 【Android】檢查網路連線狀態 Connectivity Network Active State

歡迎轉載,請註明出處。

2015年12月17日 星期四

Android-RecyclerView Sample 範例 Kotlin

更新日期:20189116 新增範例( kotlin )

雖然有 ListView 和 GridView 顯示資訊
但還要另外寫選配器
Google 又另外推出 RecyclerView
聞說效率比前 2 個 View 效率更高
話不多說

先來個簡單流程說明吧
1 . 首先設計要顯示表格的畫面內容
2 . 將剛剛設計的內容格式放置選配器內
3 . 將資料放置選配器中
4 . 依照不同的需求顯示

直接來個範例

1 . build.gradle 先匯入以下
compile 'com.android.support:cardview-v7:26.1.0'
compile 'com.android.support:recyclerview-v7:26.1.0'

2 . 新增元素介面
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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">

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


        <ImageView
            android:id="@+id/item_record_1_img"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            app:srcCompat="@mipmap/ic_launcher" />

        <TextView
            android:id="@+id/item_record_1_text"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center"
            android:text="TextView" />
    </LinearLayout>

</LinearLayout>

3 . 設定頁面參數
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;

import com.light.blue.counter.R;

public class MyViewHolder_1 extends RecyclerView.ViewHolder {

    public ImageView mImageView;
    public TextView mTextView;

    public MyViewHolder_1(View view) {
        super(view);
        // 添加預設的模組
        mImageView = view.findViewById(R.id.item_record_1_img);
        mTextView = view.findViewById(R.id.item_record_1_text);
    }
}


4 . 設定選配器
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.light.blue.adpater.view.MyViewHolder_1;
import com.light.blue.counter.R;

import java.util.List;

public class MyAdapter_1 extends RecyclerView.Adapter<MyViewHolder_1> {

    private List<String> mList;

    public MyAdapter_1(List<String> list) {
        mList = list;
    }

    @Override
    public int getItemCount() {
        return mList.size();
    }

    @Override
    public void onBindViewHolder(MyViewHolder_1 holder, int position) {
        holder.mTextView.setText(mList.get(position).toString());
    }

    @Override
    public MyViewHolder_1 onCreateViewHolder(ViewGroup viewGroup, int viewType) {
        View view = LayoutInflater.from(viewGroup.getContext())
                .inflate(R.layout.item_record_1, viewGroup, false);

        return new MyViewHolder_1(view);
    }

}

5 . 在主畫面宣告
<?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">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycleView_recyclerList"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scrollbars="vertical">

    </android.support.v7.widget.RecyclerView>

</android.support.constraint.ConstraintLayout>

6 .
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.support.v7.widget.LinearLayoutManager
import com.light.blue.adpater.MyAdapter_1
import com.light.blue.sql.until.MyDatabaseHandler
import kotlinx.android.synthetic.main.activity_recycleview.*
import java.util.*

class RecycleListActivity : AppCompatActivity() {

    private lateinit var myDatabaseHandler: MyDatabaseHandler;

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_recycleview)

        myDatabaseHandler = MyDatabaseHandler(this);

        var listStr = ArrayList<String>();
        listStr.add("小明");
        listStr.add("小王");
        listStr.add("小黃");
        listStr.add("小黑");
        listStr.add("小白");

        recycleView_recyclerList.layoutManager = LinearLayoutManager(this);
        // recycleView_recyclerList.layoutManager = GridLayoutManager(this, 3);
        recycleView_recyclerList.adapter = MyAdapter_1(listStr);

    }

}


( LinearLayoutManager )






















(GridLayoutManager)




參考資料 : Creating Lists with RecyclerView in Android
參考資料 : RecyclerView使用详解(一)

2015年12月16日 星期三

Android-Create New Project

想必各位大大心目中有一些想實踐的App
但要如何開始?
建議 : 不要一想到就直接開始動工
不然後繼無力就很容易失去原有的方向

不做申論只需簡單問自己
然後以最簡短的一句話寫在紙上

首先,先分析 3W1H !!!
1 . Why?
為甚麼要寫此 App?

2 . Who?
此 App 使用對象為?

3 . What?
未來展望?想要的目的?

4 . How?
要如何做?

如果此問題都能回答出來
因該就算是踏出第一步了
--------------------------------------------------
接下來就是實作分析
1 . Functional Map
2 . Flow
3 . UI design

Android-水波紋特效 ripple

20170311 新增:ImageButton has ripple effect

Google 在 5.0 有新增一些特效
最明顯的例子 : 按鍵有水波紋特效
至於能不能讓使用者接受
只能見仁見智了

1 . 在專案內 新增 drawable-v21
2 . 用 ripple 包覆元素
3 . 物件套用剛剛客製的 drawable

注意 : 最小 SDK 版本為 21

<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="@color/white">
    <item android:drawable="@drawable/ic_l"/>
</ripple>

參考資訊 : Lollipop RippleDrawable vs Selector for Pre-Lollipop
參考資訊 : How to Add Ripple Effect/Animation to a Android Button
參考資料:Apply Material Design Touch Ripple to ImageButton?

--------------------------------------------------------
如果手機版本比較低可以參考 :
參考資訊 : material-ripple
參考資訊 : RippleEffect
參考資訊 : 內有連結

2015年12月14日 星期一

Android-Take Photo and save file

1 . 新增權限
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

2 . 設定 RequestCode
public static final int TAKE_PHOTO_IMAGE_CODE = 1234;

3 . 開啟相機
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
startActivityForResult(intent, TAKE_PHOTO_IMAGE_CODE);    

4 . 接收拍照結果
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == TAKE_PHOTO_IMAGE_CODE) 
    {
        //Check if data in not null 
        if (data != null)
        {
            Bitmap bitmap = (Bitmap)data.getExtras().get("data");
            imageView.setImageBitmap(bitmap);
        
        }
    }
}

5 . 如果要有儲存照片功能
public static final String FileName = "Hello";

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    //Check that request code matches ours:
    if (requestCode == TAKE_PHOTO_IMAGE_CODE) 
    {
        // 建立資料夾
        File imageStorageFolder = 
            new File(Environment.getExternalStorageDirectory()+File.separator + FileName);
            
        if (!imageStorageFolder.exists())
        {
            imageStorageFolder.mkdirs();
            Log.d(TAG , "Folder created at: "+imageStorageFolder.toString());
        }
        //Check if data in not null 
        if (data != null)
        {
            String imageName = "image";
            String fileNameExtension = ".jpg";
            File sdCard = Environment.getExternalStorageDirectory();
            String strImageStorageFolder = File.separator + FileName + File.separator;
            File destinationFile = 
                new File(sdCard, strImageStorageFolder + imageName + fileNameExtension);
            Log.d(TAG, "the destination for image file is: " + destinationFile );
            if (data.getExtras() != null)
            {
                Bitmap bitmap = (Bitmap)data.getExtras().get("data");
                //判斷照片為橫向或者為直向,並進入ScalePic判斷圖片是否要進行縮放
                if(bitmap.getWidth()>bitmap.getHeight())
                    ScalePic(bitmap,mPhone.heightPixels);
                else 
                    ScalePic(bitmap,mPhone.widthPixels);
                try
                {
                    FileOutputStream out = new FileOutputStream(destinationFile);
                    bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
                    out.flush();
                    out.close();
                } 
                catch (Exception e) 
                {
                    Log.e(TAG, "ERROR:" + e.toString());
                }
                
            }
        }
    }
}

private void ScalePic(Bitmap bitmap,int phone)
{
    //縮放比例預設為1
    float mScale = 1 ;
    //如果圖片寬度大於手機寬度則進行縮放,否則直接將圖片放入ImageView內
    if(bitmap.getWidth() > phone )
    {
        //判斷縮放比例
        mScale = (float)phone/(float)bitmap.getWidth();
        Matrix mMat = new Matrix() ;
        mMat.setScale(mScale, mScale);
        Bitmap mScaleBitmap = Bitmap.createBitmap(bitmap,
                0,
                0,
                bitmap.getWidth(),
                bitmap.getHeight(),
                mMat,
                false);
        imageView.setImageBitmap(mScaleBitmap);
    }
    else imageView.setImageBitmap(bitmap);
}


參考資料 : Android : Use Camera Activity for Thumbnail and FullSize Image
參考資料 : 【Android】開啟相機-照相功能與相簿-相片集並讀取相片匯入至程式

歡迎轉載,請註明出處。

Java-時間 日期 增減


DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
Calendar calendar = Calendar.getInstance();
calendar.setTime(new Date());
calendar.add(Calendar.DATE, 3);
String date = dateFormat.format(calendar.getTime());
System.out.println(date);

歡迎轉載,請註明出處。