2015年11月30日 星期一

Android - 目前GPS位置

參考網址:
http://cw1057.blogspot.tw/2011/11/android-locationmanager.html

我不太的寫範例,
只是會希望能夠快速開發,
所以這裡貼的程式碼,會是複製後馬上就能進行
是我改寫了文章內容後的結果


public class LocationActivity extends Activity {
private LocationManager locationMgr;
private double longitude = 0;
private double latitude = 0;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.locationMgr = (LocationManager) this.getSystemService(LOCATION_SERVICE);
}


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

// 取得位置提供者,不下條件,讓系統決定最適用者,true 表示生效的 provider
String provider = this.locationMgr.getBestProvider(new Criteria(), true);

if (provider == null) {
debug_log("沒有 location provider 可以使用");
return;
}

debug_log("取得 provider - " + provider);
debug_log("requestLocationUpdates...");

// 註冊 listener,兩個 0 不適合在實際環境使用,太耗電
this.locationMgr.requestLocationUpdates(provider, 0, 0, mLocationListener);

debug_log("getLastKnownLocation...");
Location location = this.locationMgr.getLastKnownLocation(provider);
if (location == null) {
debug_log("未取過 location");
return;
}
debug_log("取得上次的 location");
mLocationListener.onLocationChanged(location);
}


public LocationListener mLocationListener = new LocationListener() {

@Override
public void onLocationChanged(Location location) {
longitude = location.getLongitude();
latitude = location.getLatitude();

debug_log("onLocationChanged...");
String msg = "經度: " + location.getLongitude() + ", 緯度: "
+ location.getLatitude();
debug_log(msg);
}


@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
debug_log("onStatusChanged...");
// 當 location provider 改變時
}

@Override
public void onProviderEnabled(String provider) {
debug_log("onProviderEnabled...");
// 當 location provider 有效時
}

@Override
public void onProviderDisabled(String provider) {
debug_log("onProviderDisabled...");
// 當 location provider 無效時
}
};

private void debug_log(String msg) {
Log.e("log",msg);
}

@Override
protected void onPause() {
super.onPause();
this.debug_log("removeUpdates...");
this.locationMgr.removeUpdates(mLocationListener);
}
}

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.INTERNET" />


2015年11月29日 星期日

Android 實戰記錄 (4) - java.lang.NoSuchMethodError: android.widget.Button.setBackground

參考網址:
http://stackoverflow.com/questions/18559248/button-setbackgrounddrawable-background-throws-nosuchmethoderror

今天發生
java.lang.NoSuchMethodError: android.widget.Button.setBackground

主要原因為
Android 版本在 4.0.3
為小於 API 16

無法使用Button的setBackground
需改寫為
setBackgroundResource

2015年11月26日 星期四

Android - Load Image From Url

private Bitmap getBitmap(String path) throws Exception {
    if(!path.equals("")){
        URL u = new URL(path);
        HttpURLConnection conn = (HttpURLConnection)u.openConnection();
        conn.setDoInput(true); //        conn.connect();
        InputStream localInputStream;
        Bitmap localBitmap ;
        localInputStream = conn.getInputStream();
        localBitmap = BitmapFactory.decodeStream(localInputStream, null, null);
        return localBitmap;
    }
    return null;
}

Android 實戰記錄 (3) - OutOfMemory 引發問題原因

目前我所負責的APP的 OutOfMemory 引發問題原因有以下三點

1.  ImageView設定圖檔太大,加上使用BitmapFactory.decodeResource
   備註:遇到機型幾乎是「三星 Galaxy Note II」Android 4.4.2版,不知道是不是哪個使用者,非常無法接受很大的圖示處理。
2. android.view.InflateException: Binary XML file line ,主要XML裡有比較暫量的圖檔
3. 會發生在,呼叫完API,由於API文字過多所造成
java.lang.OutOfMemoryError
 at java.lang.AbstractStringBuilder.enlargeBuffer(AbstractStringBuilder.java:94)
 at java.lang.AbstractStringBuilder.append0(AbstractStringBuilder.java:145)
 at java.lang.StringBuilder.append(StringBuilder.java:216)

目前大致發生在這些問題上
第一個解決容易。
第二、三就不確定實際解法

2015年11月23日 星期一

Android 實戰記錄 (2) - ArrayAdapter - java.lang.IndexOutOfBoundsException: Invalid index

從錯誤訊息發現了這一個問題

我有使用一個ArrayList<T>的連結串列,

假設他的變數叫mList

在初始化的時候會
mList = new ArrayList<T>();

一般只會
mList.clear();
mList.addAll();
mList.get();

就沒有其它使用指派的指令。

懷疑,可能的原因在
未替ArrayAdapter設定getCount的動作,可能會影響到。

所以加入了,做特殊處理,避免發生問題。

@Overridepublic int getCount() {
   if(result!=null) {
      return result.size();
   } else {
      return 0;
   }
}

2015年11月22日 星期日

Android 實戰記錄 (1) - java.lang.OutOfMemoryError


這次遇到OutOfMemory  問題

可能原因在於導覽頁或說明頁,跳出滿版的圖片
而圖片大小是1080X1920,約10幾K才會
但經過decode成Bitmap後,可能就變成不止10幾K

原使用以下方式取得後再設定
Bitmap bmp = BitmapFactory.decodeResource(res,rid);
imageView.setImageBitmap(bmp );

但若用另一種方式
imageView.setImageResource(rid);

一樣會耗大量的記憶體處理
根據以下方式處理
http://givemepass.blogspot.tw/2011/11/blog-post_16.html

  1. 使用 BitmapFactory.decodeStream() 產生Bitmap
  2. 設定 BitmapFactory.Options inSampleSize,
         (inSampleSize值越大解析度越小,佔用memory也越小)
  3.  onPause/onStop/onDestory 時,將沒用到的Bitmap release(用recyle())


實作了之後,發現,記憶體初始佔量變小,
有20MB以上的差異效果。

可能在各種記憶體控管上(由其使用大圖)
需多注意,可能拉高記憶體,就容易發生之後的OutOfMemory問題。
可盡量的避免這樣的問題

其它參考網頁:
http://blog.xuite.net/ffc99a3b/ooxx/44391740-%5B%E8%BD%89%E8%BC%89%5D+Android+Out+Of+Memory(OOM)+%E7%9A%84%E8%A9%B3%E7%B4%B0%E7%A0%94%E7%A9%B6

------------
實作程式:
Bitmap bmp = getLocalBitmap(ctx,rid);

public Bitmap getLocalBitmap(Context ctx, int rid){
   InputStream inputStream = ctx.getResources().openRawResource(rid);
   return BitmapFactory.decodeStream(inputStream, null, getBitmapOptions(1));
}

public BitmapFactory.Options getBitmapOptions(int scale){
   BitmapFactory.Options options = new BitmapFactory.Options();
   options.inPurgeable = true;
   options.inInputShareable = true;
   options.inSampleSize = scale;
   return options;
}

---------------------------

也有其它OutOfMemory的錯誤訊息的顯示錯誤內容如下

Caused by: java.lang.OutOfMemoryError: Failed to allocate a 10240012 byte allocation with 9727265 free bytes and 9MB until OOM

java.lang.OutOfMemoryError: Failed to allocate a 4194316 byte allocation with 3346926 free bytes and 3MB until OOM

java.lang.OutOfMemoryError: (Heap Size=98304KB, Allocated=90289KB)