2015年12月30日 星期三

Android-音量控制

參考資訊 : [多媒体] 音量调节
參考資訊 : [索引汇总帖] 【eoeAndroid社区索引】android设备功能之音量教程实例汇总
參考資訊 : How to capture key events from bluetooth headset with android

Android-MediaPlayer 音樂播放


import android.app.Activity;
import android.media.MediaPlayer;
import android.os.Bundle;

public class MainActivity extends Activity {

    private MediaPlayer mediaPlayer;

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

        try {
            mediaPlayer = new MediaPlayer();
            mediaPlayer = MediaPlayer.create(this, R.raw.lucky_star);
            mediaPlayer.start();
        } catch (IllegalStateException e) {
            e.printStackTrace();
        }

    }
}


參考資訊 : 使用多媒體播放器(MediaPlayer)播放MP3音樂
參考資訊 : 音樂播放器(MediaPlayer)

2015年12月26日 星期六

Android-ListView 和 CheckBox 問題

不知道是否有大大遇過類似以下情況 :
比如有 30 筆資料
點選第 1 筆後
竟然在 2X 筆突然出現被勾選的狀態
 If you check first checkbox and slide down, Actually the twentieth checkbox
was checked.

解決辦法 :
1 . 把被點選的位置記錄下來
2 . 生成 CheckBox 時去判斷是否要被勾選

import java.util.HashMap;
import java.util.List;
import android.annotation.SuppressLint;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.TextView;

public class MyAdapter extends BaseAdapter{

    private HashMap<Integer, Boolean> hashMap = new HashMap<Integer,Boolean>();
    .
    .
    .
    
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        Elements elements = null;  

        if (convertView == null) {  
            .
            .
            .
        } else {  
            .
            .
            .
        }  
        
        elements.checkBox1.setOnCheckedChangeListener(new OnCheckedChangeListener(){

            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if(isChecked)
                {  
                    hashMap.put(position, isChecked);
                }else{
                    hashMap.remove(position);
                }                
            }});
        elements.checkBox1.setChecked(hashMap.get(position)==null? false : true);
        
        return convertView; 
    }

}



參考資料 : ListView点击checkbox其他checkbox也被同时选中的问题

Android-Copy project and rename package

If you  want to create new project form the project ( A -> A' )
You must :
1 . rename package name
2 . AndroidManifest registered activity、service、package... must change package name
3 .Change def packageName on build.gradle
4 . rebuild project

2015年12月21日 星期一

Android-文字 轉 語音 TTS


import java.util.Locale;

import android.content.Context;
import android.speech.tts.TextToSpeech;

public class MyTTS implements TextToSpeech.OnInitListener{

    private Context context;
    private TextToSpeech mTextToSpeech = null;
    private boolean isLoaded = false;

    // initTTS
    public MyTTS(Context context){
        try {
            this.context = context;
            this.mTextToSpeech = new TextToSpeech(context, this);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onInit(int status) {
        if (status == TextToSpeech.SUCCESS) 
        {
            mTextToSpeech.setLanguage(Locale.US);
            isLoaded = true;
        } 
        else 
        {
            isLoaded = false;
        }        
    }

    // stop action about tts
    public void close(){
        if(mTextToSpeech != null)
        {
            mTextToSpeech.stop(); 
            mTextToSpeech.shutdown();
        }
    }
    
    public void queueSpeak(String text) {
        if (isLoaded)
            mTextToSpeech.speak(text, TextToSpeech.QUEUE_ADD, null);
    }

    public void flushSpeak(String text) {
        if (isLoaded)
            mTextToSpeech.speak(text, TextToSpeech.QUEUE_FLUSH, null);
    }
    
}


參考資料 : Android TextToSpeech Example

Android-防丟器為例













在還沒開始前,想必大家對 Bluetooth LE Scanner 不陌生吧
在開始編寫前可以先拿上方的應用程式操作看看




檢查手機版本和有無開啟藍芽
/** 初始化 */
public boolean initialize() {
    // For API level 18 and above, get a reference to BluetoothAdapter through
    // BluetoothManager.
    if (bluetoothManager == null) {
        bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
        if (bluetoothManager == null) {
            Log.e(TAG, "Unable to initialize BluetoothManager.");
            return false;
        }
    }
    bluetoothAdapter = bluetoothManager.getAdapter();
    if (bluetoothAdapter == null) {
        Log.e(TAG, "Unable to obtain a BluetoothAdapter.");
        return false;
    }
    return true;
}

裝置連線
/** 連線至藍芽裝置 */
public boolean connect(final String address) {
    if (bluetoothAdapter == null || address == null) {
        Log.w(TAG, "BluetoothAdapter not initialized or unspecified address.");
        return false;
    }
    // Previously connected device.  Try to reconnect.
    if (mBluetoothDeviceAddress != null && address.equals(mBluetoothDeviceAddress)
            && bluetoothGatt != null) {
        Log.d(TAG, "Trying to use an existing mBluetoothGatt for connection.");
        if (bluetoothGatt.connect()) {
            mConnectionState = STATE_CONNECTING;
            return true;
        } else {
            return false;
        }
    }
    final BluetoothDevice device = bluetoothAdapter.getRemoteDevice(address);
    if (device == null) {
        Log.w(TAG, "Device not found.  Unable to connect.");
        return false;
    }
    bluetoothGatt = device.connectGatt(this, false, mGattCallback);
    Log.d(TAG, "Trying to create a new connection.");
    mBluetoothDeviceAddress = address;
    mConnectionState = STATE_CONNECTING;
    return true;
}

與裝置離線
public void disconnect() {
    if (bluetoothAdapter == null || bluetoothGatt == null) {
        Log.w(TAG, "BluetoothAdapter not initialized");
        return;
    }
    bluetoothGatt.disconnect();
}

關閉藍芽
public void close() {
    if (bluetoothGatt == null) {
        return;
    }
    Log.w(TAG, "mBluetoothGatt closed");
    mBluetoothDeviceAddress = null;
    bluetoothGatt.close();
    bluetoothGatt = null;
}

連線後的回調
private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
    @Override
    public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
        if (newState == BluetoothProfile.STATE_CONNECTED) {
            mConnectionState = STATE_CONNECTED;
            broadcastUpdate(intentAction);
            Log.i(TAG, "Connected to GATT server.");
            Log.i(TAG, "Attempting to start service discovery:" +
                bluetoothGatt.discoverServices());
        } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
            mConnectionState = STATE_DISCONNECTED;
            Log.i(TAG, "Disconnected from GATT server.");
            disconnect();
            close();
        }
        broadcastUpdate(intentAction);
    }

    @Override
    public void onServicesDiscovered(BluetoothGatt gatt, int status) {
        if (status == BluetoothGatt.GATT_SUCCESS) {
                enableNotification();
        } else {
            Log.w(TAG, "onServicesDiscovered received: " + status);
        }
    }

    @Override
    public void onCharacteristicRead(BluetoothGatt gatt,
            BluetoothGattCharacteristic characteristic,
            int status) {
        Log.w(TAG, "onCharacteristicRead received: " + characteristic.getValue());
        
    }

    @Override
    public void onCharacteristicChanged(BluetoothGatt gatt,
            BluetoothGattCharacteristic characteristic) {
        Log.w(TAG, "onCharacteristicChanged received: " + characteristic.getValue());
    }

    @Override
    public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
        super.onCharacteristicWrite(gatt, characteristic, status);
        Log.w(TAG, "onCharacteristicWrite received: ");
    }
};

新增服務提醒
public void enableNotification()
{
    // is support SERVICE 
    BluetoothGattService Service = bluetoothGatt.getService(SERVICE_UUID);
    if (Service == null) {
        Log.w(TAG, "service not found!");
        return;
    }
    // is support Characteristic
    BluetoothGattCharacteristic Char = Service.getCharacteristic(CHARACTERISTIC_UUID);
    if (Char == null) {
        Log.w(TAG, "Tx charateristic not found!");
        return;
    }
    bluetoothGatt.setCharacteristicNotification(Char,true);
    BluetoothGattDescriptor descriptor = Char.getDescriptor(CCCD);
    final byte[] ENABLE_NOTIFICATION_VALUE__ = {0x01};
    descriptor.setValue(ENABLE_NOTIFICATION_VALUE__);
    bluetoothGatt.writeDescriptor(descriptor);
}

取得所有服務
for(BluetoothGattService bluetoothGattService: gatt.getServices())
{
    Log.w(TAG, "----------------------------------");
    Log.w(TAG, "BluetoothGattService : " + bluetoothGattService.getUuid() );
    for(BluetoothGattCharacteristic bluetoothGattCharacteristic: bluetoothGattService.getCharacteristics())
    {
        Log.w(TAG, "BluetoothGattCharacteristic : " + bluetoothGattCharacteristic.getUuid() );
        for(BluetoothGattDescriptor bluetoothGattDescriptro: bluetoothGattCharacteristic.getDescriptors())
        {
            Log.w(TAG, "BluetoothGattDescriptor : " + bluetoothGattDescriptro.getUuid());
            if(bluetoothGattDescriptro.getValue() != null)
                Log.w(TAG, "BluetoothGattDescriptor : " + bluetoothGattDescriptro.getValue());                
            
        }
    }
}

參考資料 : AndroidとBLE
參考資料 : NordicSemiconductor/Android-nRF-Toolbox
參考資料 : BLE Health Devices: First Steps with Android
參考資料 : Bluetooth Low Energy (or LE) is a very cool technology.
參考資料 : SensorTag User Guide_Android