2015年4月14日 星期二

Android Battery Information 電池資訊

電池相關功能
1./res/layout/main.xml


    

    
    

    
    


2.Main.java
package tw.android;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.drawable.LevelListDrawable;
import android.os.BatteryManager;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;

public class Main extends Activity {
 private Button btBattery;
 private TextView tvBatteryInfo;
 private ImageView ivBattery;
 
 private String healthState,acOrUSB,batteryState;
 
 /** Called when the activity is first created. */
 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);

  btBattery = (Button) findViewById(R.id.btBattery);
  tvBatteryInfo = (TextView) findViewById(R.id.tvBatteryInfo);
  ivBattery = (ImageView) findViewById(R.id.ivBattery);
  
  btBattery.setOnClickListener(new Button.OnClickListener() {
   public void onClick(View v) {
    runInfo();
    
   }
  });
  
  
 }
 
 public void runInfo(){
  /*電池訊息*/
  this.registerReceiver(this.mBatInfoReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
 }
 
 private BroadcastReceiver mBatInfoReceiver = new BroadcastReceiver(){
     @SuppressWarnings("deprecation")
  @Override
     public void onReceive(Context ctxt, Intent intent) {
      int  health= intent.getIntExtra(BatteryManager.EXTRA_HEALTH,0); //健康狀態
   int  icon_small= intent.getIntExtra(BatteryManager.EXTRA_ICON_SMALL,0); //電池i-con圖
   int  level= intent.getIntExtra(BatteryManager.EXTRA_LEVEL,0); //目前電量
   int  plugged= intent.getIntExtra(BatteryManager.EXTRA_PLUGGED,0); //電流來源
   boolean  present= intent.getExtras().getBoolean(BatteryManager.EXTRA_PRESENT); //電池存在否
   int  scale= intent.getIntExtra(BatteryManager.EXTRA_SCALE,0); //電量最大值
   int  status= intent.getIntExtra(BatteryManager.EXTRA_STATUS,0); //充電狀態
   String  technology= intent.getExtras().getString(BatteryManager.EXTRA_TECHNOLOGY); //電池技術
   int  temperature= intent.getIntExtra(BatteryManager.EXTRA_TEMPERATURE,0); //目前溫度
   int  voltage= intent.getIntExtra(BatteryManager.EXTRA_VOLTAGE,0); //目前電壓
   
   /*判斷健康狀態*/
   switch (health) {  
            case BatteryManager.BATTERY_HEALTH_COLD:  
             healthState = "COLD";
                break;  
            case BatteryManager.BATTERY_HEALTH_DEAD:  
             healthState = "DEAD";
                break;  
            case BatteryManager.BATTERY_HEALTH_GOOD:  
             healthState = "GOOD";
                break;  
            case BatteryManager.BATTERY_HEALTH_OVERHEAT:  
             healthState = "OVERHEAT";
                break;  
            case BatteryManager.BATTERY_HEALTH_OVER_VOLTAGE:  
             healthState = "OVER_VOLTAGE";
                break;  
            case BatteryManager.BATTERY_HEALTH_UNKNOWN:  
             healthState = "UNKNOWN";
                break;  
            case BatteryManager.BATTERY_HEALTH_UNSPECIFIED_FAILURE:  
             healthState = "UNSPECIFIED_FAILURE"; 
                break;  
            default:  
                break;  
            }  
   
   /*電池i-con圖*/
   LevelListDrawable batteryLevel = (LevelListDrawable) getResources().getDrawable(icon_small);
   batteryLevel.setLevel(level);
         ivBattery.setBackgroundDrawable(batteryLevel);
   
   /*判斷電流來源*/
   switch (plugged) {  
            case BatteryManager.BATTERY_PLUGGED_AC:  
             acOrUSB = "使用AC";
                break;  
            case BatteryManager.BATTERY_PLUGGED_USB:  
             acOrUSB = "使用USB";
                break;  
            default:  
                break;  
            }  

   /*判斷充電狀態來源*/
    switch (status) {  
             case BatteryManager.BATTERY_STATUS_CHARGING:  
              batteryState = "充電中";
                 break;  
             case BatteryManager.BATTERY_STATUS_DISCHARGING:  
              batteryState = "取消充電";
                 break;  
             case BatteryManager.BATTERY_STATUS_FULL:  
              batteryState = "電量已滿";
                 break;  
             case BatteryManager.BATTERY_STATUS_NOT_CHARGING:  
              batteryState = "未充電";
                 break;  
             case BatteryManager.BATTERY_STATUS_UNKNOWN:  
              batteryState = "未知";
                 break;  
             default:  
                 break;  
             }  
   
    tvBatteryInfo.setText("健康狀態: "+healthState+"\n"+
      "目前電量: "+level+"% \n"+
      "電流來源: "+acOrUSB+"\n"+
      "電池存在: "+present+"\n"+
      "電量最大值: "+scale+"%\n"+
      "充電狀態: "+batteryState+"\n"+
      "電池技術: "+technology+"\n"+
      "目前溫度: "+temperature+"度\n"+
      "目前電壓: "+voltage+"\n");
     }
   };
   
   @Override
  protected void onDestroy() {
   super.onDestroy();
   //結束後要移除,否則會出現 Activity xxx has leaked IntentReceiver
   unregisterReceiver(mBatInfoReceiver);
  }
}

檔案下載:
https://github.com/terryyamg/JudgeBatteryTest
 參考來源:
http://mobiledevtuts.com/android/android-sdk-get-device-battery-information/
http://stackoverflow.com/questions/4891598/android-access-system-drawables
http://stackoverflow.com/questions/9781769/activity-has-leaked-intentreceiver

2015年4月13日 星期一

Android DragSortListView 拖動 自訂 排序

實作像facebook Messenger的貼圖自訂排序


1.下載檔案https://github.com/terryyamg/DragSortListViewTest
如果要看所有demo,請前往https://github.com/bauerca/drag-sort-listview下載

這裡舉demo裡有刪除的例子-簡化版
匯入library

File -> improt Existing Android Code Into Workspace -> Next

Browse...選擇下載的library -> 打勾Copy projects into workspace-> Finish


建立專案->在專案點右鍵-> Properties-> 點選Android ->Add

選擇library ->OK

出現綠色打勾,點選OK完成匯入

2./res/values/string.xml


    DragSortListViewTest

    
        Orioles
        Blue Jays
        Red Sox
        Yankees
        Tigers
        Indians
    


3./res/values/ids.xml

    
    

4./res/values/main.xml --主畫面(注意xmlns:dslv="http://schemas.android.com/apk/res/tw.android的package名稱要與自己的app相同)



5./res/values/list_item_checkable.xml --項目選項(注意tw.android.CheckableLinearLayout的package名稱要與自己的app相同)


    
    

    
    

    
    


6./res/drawable加入兩張圖片delete_x.png與drag.9.png

7.Main.java
package tw.android;

import java.util.ArrayList;
import java.util.Arrays;

import android.app.ListActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.ArrayAdapter;

import com.mobeta.android.dslv.DragSortListView;
import com.mobeta.android.dslv.DragSortListView.RemoveListener;

public class Main extends ListActivity {
 private ArrayAdapter<String> adapter;

 /*拖拉選項*/
 private DragSortListView.DropListener onDrop = new DragSortListView.DropListener() {
  public void drop(int from, int to) {
   Log.i("from", from+"");
   Log.i("to", to+"");
   if (from != to) { //選項有移動位置
    DragSortListView list = getListView();
    String item = adapter.getItem(from);
    adapter.remove(item); //移除初始A的位置
    adapter.insert(item, to); //將A加入到B的位置
    list.moveCheckState(from, to);
   }
  }
 };

 /*移除選項*/
 private RemoveListener onRemove = new DragSortListView.RemoveListener() {
  public void remove(int which) {
   Log.i("which", which+"");
   DragSortListView list = getListView();
   String item = adapter.getItem(which);
   adapter.remove(item); //移除選中位置
   list.removeCheckState(which);
  }
 };

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

  /*建立選單*/
  String[] array = getResources().getStringArray(R.array.mlb_team); //在res/valuse/string.xml 建立選單
  ArrayList<String> arrayList = new ArrayList<String>(
    Arrays.asList(array));

  adapter = new ArrayAdapter<String>(this, R.layout.list_item_checkable, //選單layout樣式
    R.id.text, arrayList);

  setListAdapter(adapter);

  DragSortListView list = getListView();
  list.setDropListener(onDrop);
  list.setRemoveListener(onRemove);
 }

 @Override
 public DragSortListView getListView() {
  return (DragSortListView) super.getListView();
 }

}
8.CheckableLinearLayout.java
package tw.android;

import android.content.Context;
import android.util.AttributeSet;
import android.widget.Checkable;
import android.widget.LinearLayout;

public class CheckableLinearLayout extends LinearLayout implements Checkable {

    private static final int CHECKABLE_CHILD_INDEX = 1;
    private Checkable child;

    public CheckableLinearLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        child = (Checkable) getChildAt(CHECKABLE_CHILD_INDEX);
    }

    public boolean isChecked() {
        return child.isChecked(); 
    }

    public void setChecked(boolean checked) {
        child.setChecked(checked);
    }

    public void toggle() {
        child.toggle();
    }
    
}
移除

檔案下載:
https://github.com/terryyamg/DragSortListViewTest
參考來源:
https://github.com/bauerca/drag-sort-listview

2015年4月10日 星期五

Android DatePicker Hide Year Month Day 日期選項 隱藏 年 月 日

隱藏原生的DatePicker的年或月
1./res/layout/main.xml


    

        

            
            

            
            

            
            

            
            

            
            

            
            
        
    


2.Main.java
package tw.android;

import java.lang.reflect.Field;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.DatePicker;

public class Main extends Activity {
 private DatePicker datePicker1, datePicker2;

 /** Called when the activity is first created. */
 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);

  datePicker1 = (DatePicker) findViewById(R.id.datePicker1);
  datePicker2 = (DatePicker) findViewById(R.id.datePicker2);

  try {
   /* 隱藏年 */
   Field f1[] = datePicker1.getClass().getDeclaredFields(); // 建立datePicker1
   for (Field field : f1) {
    Log.i("f1's all field", field.getName() + ""); // log出f1的所有元素
    if (field.getName().equals("mYearSpinner")) { // 取得的元素等於mYearSpinner
     field.setAccessible(true);
     Object yearPicker = new Object();
     yearPicker = field.get(datePicker1);
     ((View) yearPicker).setVisibility(View.GONE); // 隱藏年
    }

   }
   /* 隱藏年、月 */
   Field f2[] = datePicker2.getClass().getDeclaredFields(); // 建立datePicker2
   for (Field field : f2) {
    Log.i("f2's all field", field.getName() + ""); // log出f2的所有元素
    if (field.getName().equals("mYearSpinner")) { // 取得的元素等於mYearSpinner
     field.setAccessible(true);
     Object yearPicker = new Object();
     yearPicker = field.get(datePicker2);
     ((View) yearPicker).setVisibility(View.GONE); // 隱藏年
    }

    if (field.getName().equals("mMonthSpinner")) { // 取得的元素等於mMonthSpinner
     field.setAccessible(true);
     Object monthPicker = new Object();
     monthPicker = field.get(datePicker2);
     ((View) monthPicker).setVisibility(View.GONE); // 隱藏月
    }

   }
  } catch (Exception e) {
   Log.d("ERROR", e.getMessage());
  }
 }
}


參考來源:
http://stackoverflow.com/questions/10401915/hide-year-field-in-android-datepicker

2015年4月9日 星期四

Android CheckBox Text Up Left Right Bottom Location 核取方塊 文字位置

要改變checkbox的text位置需自訂圖片與選擇器
1.在/res/drawable/加入圖片checked.png與unchecked.png 


2./res/drawable/bottom.xml

    
    
        

3./res/layout/main.xml
android:button="@android:color/transparent" ----- 隱藏原核取方塊
android:drawableTop="@drawable/bottom" ----- 加入選擇器bottom.xml,文字在下方
android:drawableLeft ----- 文字在右方
android:drawableRight ----- 文字在左方
android:drawableBottom ----- 文字在上方


    

        
        
    

    

        
        
    

    

        
        
    

    

        
        
    


4.Main.java
package tw.android;

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

public class Main extends Activity {

 /** Called when the activity is first created. */
 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);

 }
 

}


參考來源:
http://stackoverflow.com/questions/27030629/android-how-to-align-the-checkbox-text-in-the-bottom
http://stackoverflow.com/questions/16063135/removing-the-box-from-the-checkbox-in-android

2015年4月2日 星期四

Android Compass Sensor 指南針 感應器

基本指南針感應器應用,需在實機上應用,如果手機無感應器,則LogCat會出現
 sensor or listener is null
1.加入圖片



2./res/layout/main.xml


    
    

    
    


3.Main.java
package tw.android;

import android.app.Activity;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.widget.ImageView;
import android.widget.TextView;

public class Main extends Activity implements SensorEventListener {

 private ImageView image;
 // 初始角度
 private float currentDegree = 0f;
 // 感應器管理
 private SensorManager mSensorManager;

 private TextView tvHeading;

 float[] mGravity;
 float[] mGeomagnetic;
 float Rotation[] = new float[9];
 float[] degree = new float[3];

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

  image = (ImageView) findViewById(R.id.imageViewCompass);
  tvHeading = (TextView) findViewById(R.id.tvHeading);
  mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
 }

 @Override
 protected void onResume() {
  super.onResume();

  // 註冊感應監聽器

  Sensor accelerometer = mSensorManager
    .getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
  Sensor magnetometer = mSensorManager
    .getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);

  mSensorManager.registerListener(this, accelerometer,
    SensorManager.SENSOR_DELAY_GAME);
  mSensorManager.registerListener(this, magnetometer,
    SensorManager.SENSOR_DELAY_GAME);
 }

 @Override
 protected void onPause() {
  super.onPause();

  // 停止感應監聽器
  mSensorManager.unregisterListener(this);
 }

 public void onSensorChanged(SensorEvent event) {

  if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
   mGravity = event.values;
  }
  if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
   mGeomagnetic = event.values;
  }
  if (mGravity != null && mGeomagnetic != null) {

   SensorManager.getRotationMatrix(Rotation, null, mGravity,
     mGeomagnetic);
   SensorManager.getOrientation(Rotation, degree);

   degree[0] = (float) Math.toDegrees(degree[0]);


   tvHeading.setText("Heading: " + (int) degree[0] + " degrees");

   // currentDegree-初始角度,-degree逆時針旋轉結束角度
   RotateAnimation ra = new RotateAnimation(currentDegree, -degree[0],
     Animation.RELATIVE_TO_SELF, 0.5f, // x座標
     Animation.RELATIVE_TO_SELF, 0.5f); // y座標

   // 轉動時間
   ra.setDuration(210);

   // 預設狀態結束後的動作設定
   ra.setFillAfter(true);

   // 將動作放入圖片
   image.startAnimation(ra);
   currentDegree = -degree[0];
  }
 }

 /* 改變經確度 */
 public void onAccuracyChanged(Sensor sensor, int accuracy) {
  // not in use
 }
}


檔案下載:
https://github.com/terryyamg/compassTest
參考來源:
http://www.javacodegeeks.com/2013/09/android-compass-code-example.html
http://www.codingforandroid.com/2011/01/using-orientation-sensors-simple.html

2015年3月27日 星期五

Android Customize Dialog 客製化 自製化 跳出 對話框

自製跳出對畫框Dialog
1.主畫面res/layout/main.xml



    

    
    


2.建立跳出Dialog畫面res/layout/dialog.xml


    

        
        

        
        
    

    

        
    


3.Main.java
package tw.android;

import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class Main extends Activity {
 
 final Context context = this;
 private Button btDialog,btConfirm;
 private TextView tvDialog;
 private EditText etDialog;
 private String message;
 
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        btDialog = (Button) findViewById(R.id.btDialog);
        
        tvDialog = (TextView) findViewById(R.id.tvDialog);
        
        btDialog.setOnClickListener(new OnClickListener() {

   public void onClick(View view) {

    final Dialog dialog = new Dialog(context);

    /*使用客製化layout*/
    dialog.setContentView(R.layout.dialog);
    dialog.setTitle("我出來啦");

    etDialog = (EditText) dialog.findViewById(R.id.etDialog); //客製化Dialog編輯文字
    btConfirm = (Button) dialog.findViewById(R.id.btConfirm); //客製化Dialog確認按鈕

    btConfirm.setOnClickListener(new OnClickListener() {
     public void onClick(View v) {
      message = etDialog.getText().toString(); //客製化Dialog輸入訊息的訊息
            tvDialog.setText(message); //顯示輸入訊息
      dialog.dismiss(); //關閉客製化Dialog
     }
    });

    dialog.show();
   }
  });
        
        
    }
}



檔案下載:
https://github.com/terryyamg/customDialogTest
參考來源:
http://examples.javacodegeeks.com/android/core/ui/dialog/android-custom-dialog-example/

2015年3月26日 星期四

Android jump DatePicker TimePicker 跳出 日期選項 時間選項

點選按鈕,跳出選擇日期、時間選項
1.res/layout/main.xml



    

       

        

        
    

    

        

        

        
    
 


2.Main.java
package tw.android;

import java.util.Calendar;

import android.app.Activity;
import android.app.DatePickerDialog;
import android.app.TimePickerDialog;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.TextView;
import android.widget.TimePicker;

public class Main extends Activity {
 private TextView tvDate, tvTime;
 private Button btDate, btTime;
 private int mYear, mMonth, mDay, mHour, mMinute;

 /** Called when the activity is first created. */
 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);

  tvDate = (TextView) findViewById(R.id.tvDate);
  tvTime = (TextView) findViewById(R.id.tvTime);

  btDate = (Button) findViewById(R.id.btDate);
  btTime = (Button) findViewById(R.id.btTime);

  btDate.setOnClickListener(new Button.OnClickListener() {
   public void onClick(View v) {
    showDatePickerDialog();
   }
  });
  btTime.setOnClickListener(new Button.OnClickListener() {
   public void onClick(View v) {
    showTimePickerDialog();
   }
  });
 }

 public void showDatePickerDialog() {
  // 設定初始日期
  final Calendar c = Calendar.getInstance();
  mYear = c.get(Calendar.YEAR);
  mMonth = c.get(Calendar.MONTH);
  mDay = c.get(Calendar.DAY_OF_MONTH);

  // 跳出日期選擇器
  DatePickerDialog dpd = new DatePickerDialog(this,
    new DatePickerDialog.OnDateSetListener() {
     public void onDateSet(DatePicker view, int year,
       int monthOfYear, int dayOfMonth) {
      // 完成選擇,顯示日期
      tvDate.setText(year + "-" + (monthOfYear + 1) + "-"
        + dayOfMonth);

     }
    }, mYear, mMonth, mDay);
  dpd.show();
 }

 public void showTimePickerDialog() {
  // 設定初始時間
  final Calendar c = Calendar.getInstance();
  mHour = c.get(Calendar.HOUR_OF_DAY);
  mMinute = c.get(Calendar.MINUTE);

  // 跳出時間選擇器
  TimePickerDialog tpd = new TimePickerDialog(this,
    new TimePickerDialog.OnTimeSetListener() {
     public void onTimeSet(TimePicker view, int hourOfDay,
       int minute) {
      // 完成選擇,顯示時間
      tvTime.setText(hourOfDay + ":" + minute);
     }
    }, mHour, mMinute, false);
  tpd.show();
 }

}


檔案下載:
https://github.com/terryyamg/jumpDatePickerTest
參考來源:
http://pulse7.net/android/date-picker-dialog-time-picker-dialog-android/