顯示具有 讀取 標籤的文章。 顯示所有文章
顯示具有 讀取 標籤的文章。 顯示所有文章

2015年7月15日 星期三

Android Volley Cache 緩衝 讀取 圖片

先下載資訊,在下滑ListView時,才進行網路讀取圖片。

1.先下載android-support-v4.jarvolley.jar,並在專案下建立libs資料夾,放入libs此資料夾

2.先建立一個list.json檔案,要存成UTF-8格式,並放入圖片url
[{
        "title": "鐵刀",
        "image": "http://terryyamg.3eeweb.com/test/pic/b01.JPG",
        "attack": 480,
        "attributes": "無",
        "material": ["燕雀石x3", "鐵礦石x8","大地的結晶x7", "砥石x12"]
    },
    {
        "title": "鐵刀【禊】",
        "image": "http://terryyamg.3eeweb.com/test/pic/b02.JPG",
        "attack": 528,
        "attributes": "無",
        "material": ["鐵礦石x10", "燕雀石x6", "大地的結晶x10"]
    },
    {
        "title": "鐵刀【神樂】",
        "image": "http://terryyamg.3eeweb.com/test/pic/b03.JPG",
        "attack": 576,
        "attributes": "無",
        "material": ["鐵礦石x15", "燕雀石x12", "大地的結晶x15"]
    },
    {
        "title": "斬破刀",
        "image": "http://terryyamg.3eeweb.com/test/pic/b04.JPG",
        "attack": 624,
        "attributes": "雷:250",
        "material": ["燕雀石x18", "大地的結晶x30", "電氣袋x3"]
    },
    {
        "title": "鬼斬破",
        "image": "http://terryyamg.3eeweb.com/test/pic/b05.JPG",
        "attack": 672,
        "attributes": "雷:380",
        "material": ["輝龍石x5", "燕雀石x20", "電氣袋x5"]
    },
    {
        "title": "鬼神斬破刀",
        "image": "http://terryyamg.3eeweb.com/test/pic/b06.JPG",
        "attack": 768,
        "attributes": "雷:490",
        "material": ["輝龍石x8", "靈鶴石x24", "電龍帶肉肋骨x2"]
    },
    {
        "title": "鬼神斬破刀【極】",
        "image": "http://terryyamg.3eeweb.com/test/pic/b07.JPG",
        "attack": 912,
        "attributes": "雷:620",
        "material": ["白鳩石x14", "電龍霜降肉x4", "祖龍角x1"]
    },
    {
        "title": "鐵刀【冰刃】",
        "image": "http://terryyamg.3eeweb.com/test/pic/b08.JPG",
        "attack": 528,
        "attributes": "冰:100",
        "material": ["鐵礦石x20", "冰結晶x12", "燕雀石x2"]
    },
    {
        "title": "白猿薙",
        "image": "http://terryyamg.3eeweb.com/test/pic/b09.JPG",
        "attack": 576,
        "attributes": "冰:150",
        "material": ["雪獅子的毛x6","鐵礦石x5","冰結晶x8"]
    },
    {
        "title": "白猿薙【中級】",
        "image": "http://terryyamg.3eeweb.com/test/pic/b10.JPG",
        "attack": 672,
        "attributes": "冰:250",
        "material": ["雪獅子王牙x3","雪獅子王的鬍鬚x5","冰結晶x20"]
    },
    {
        "title": "白猿薙【高級】",
        "image": "http://terryyamg.3eeweb.com/test/pic/b11.JPG",
        "attack": 864,
        "attributes": "冰:350",
        "material": ["雪獅子王的利牙x5","雪獅子的剛毛x8","雪獅子王尾x6"]
    },
    {
       "title": "白猿薙【驚嘆】",
        "image": "http://terryyamg.3eeweb.com/test/pic/b12.JPG",
        "attack": 1008,
        "attributes": "冰:560",
        "material": ["牙獸種的重牙x5","草食種的上皮x18","冰冷袋x3"]
    }]


3.AndroidManifest.xml先加入
uses-permission android:name="android.permission.INTERNET"

android:name=".AppController"


    
    

    
    

    
        
            
                
                

                
                
            
        
    


4./res/layout/activity_main.xml 主頁面放入ListView


    
    


5./res/layout/list.xml 建立客製化ListView項目


    
    

    

        
        

        

            
            

            
            
        

        
        
    




先建立AppControllerJsonArrayPostRequestLruBitmapCache三個檔案,此三個檔案不需要進行修改

6.AppController.java
package tw.android;

import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.Volley;

import android.app.Application;
import android.text.TextUtils;
import android.util.Log;


public class AppController extends Application {

 public static final String TAG = AppController.class.getSimpleName();

 private RequestQueue mRequestQueue;
 private ImageLoader mImageLoader;

 private static AppController mInstance;

 @Override
 public void onCreate() {
  super.onCreate();
  mInstance = this;
  Log.i("mInstance.this", mInstance+"");
 }

 public static synchronized AppController getInstance() {
  return mInstance;
 }

 public RequestQueue getRequestQueue() {
  if (mRequestQueue == null) {
   mRequestQueue = Volley.newRequestQueue(getApplicationContext());
  }
  return mRequestQueue;
 }

 public ImageLoader getImageLoader() {
  getRequestQueue();
  if (mImageLoader == null) {
   mImageLoader = new ImageLoader(this.mRequestQueue,
     new LruBitmapCache());
  }
  return this.mImageLoader;
 }

 public <T> void addToRequestQueue(Request<T> req, String tag) {
  // set the default tag if tag is empty
  req.setTag(TextUtils.isEmpty(tag) ? TAG : tag);
  getRequestQueue().add(req);
 }

 public <T> void addToRequestQueue(Request<T> req) {
  req.setTag(TAG);
  getRequestQueue().add(req);
 }

 public void cancelPendingRequests(Object tag) {
  if (mRequestQueue != null) {
   mRequestQueue.cancelAll(tag);
  }
 }
}
7.JsonArrayPostRequest.java 編碼
package tw.android;

import java.io.UnsupportedEncodingException;

import org.json.JSONArray;
import org.json.JSONException;

import com.android.volley.NetworkResponse;
import com.android.volley.ParseError;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.toolbox.HttpHeaderParser;

public class JsonArrayPostRequest extends Request<JSONArray> {

    private Response.Listener<JSONArray> mListener;
    public JsonArrayPostRequest(String url, Response.Listener<JSONArray> listener,
                                Response.ErrorListener errorListener){
        super(Method.GET, url, errorListener);
        mListener = listener;
    }

    @Override
    protected Response<JSONArray> parseNetworkResponse(NetworkResponse response) {
        try {

         /*utf-8 編碼 否則中文會出現亂碼*/
            String jsonString = new String(response.data, "UTF-8");
            return Response.success(new JSONArray(jsonString),
                    HttpHeaderParser.parseCacheHeaders(response));
        } catch (UnsupportedEncodingException e){
            return Response.error(new ParseError(e));
        } catch (JSONException je){
            return Response.error(new ParseError(je));
        }
    }
    @Override
    protected void deliverResponse(JSONArray response) {
        mListener.onResponse(response);
    }
}
8.LruBitmapCache.java 緩衝
package tw.android;

import android.graphics.Bitmap;
import android.support.v4.util.LruCache;

import com.android.volley.toolbox.ImageLoader.ImageCache;

/*緩衝*/
public class LruBitmapCache extends LruCache<String, Bitmap> implements
  ImageCache {
 public static int getDefaultLruCacheSize() {
  final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
  final int cacheSize = maxMemory / 8;

  return cacheSize;
 }

 public LruBitmapCache() {
  this(getDefaultLruCacheSize());
 }

 public LruBitmapCache(int sizeInKiloBytes) {
  super(sizeInKiloBytes);
 }

 @Override
 protected int sizeOf(String key, Bitmap value) {
  return value.getRowBytes() * value.getHeight() / 1024;
 }

 public Bitmap getBitmap(String url) {
  return get(url);
 }

 public void putBitmap(String url, Bitmap bitmap) {
  put(url, bitmap);
 }
}



再建立符合自己需要的清單
9.ListItem.java 清單資訊
package tw.android;

import java.util.ArrayList;

public class ListItem {

 private String title, thumbnailUrl,attributes;
 private int attack;
 private ArrayList material;

 public ListItem() {
 }

 public ListItem(String name, String thumbnailUrl, int attack, String attributes,
   ArrayList material) {
  this.title = name;
  this.thumbnailUrl = thumbnailUrl;
  this.attack = attack;
  this.attributes = attributes;
  this.material = material;
 }

 /* 名稱 */
 public String getTitle() {
  return title;
 }

 public void setTitle(String name) {
  this.title = name;
 }

 /* 縮圖 */
 public String getThumbnailUrl() {
  return thumbnailUrl;
 }

 public void setThumbnailUrl(String thumbnailUrl) {
  this.thumbnailUrl = thumbnailUrl;
 }

 /* 攻擊力 */
 public int getAttack() {
  return attack;
 }

 public void setAttack(int attack) {
  this.attack = attack;
 }

 /* 屬性 */
 public String getAttributes() {
  return attributes;
 }

 public void setAttributes(String attributes) {
  this.attributes = attributes;
 }

 /* 材料 */
 public ArrayList getMaterial() {
  return material;
 }

 public void setMaterial(ArrayList material) {
  this.material = material;
 }

}

10.CustomListAdapter.java 建立listview項目清單
package tw.android;

import java.util.List;

import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.NetworkImageView;

public class CustomListAdapter extends BaseAdapter {
 private Activity activity;
 private LayoutInflater inflater;
 private List items;
 ImageLoader imageLoader = AppController.getInstance().getImageLoader();

 public CustomListAdapter(Activity activity, List items) {
  this.activity = activity;
  this.items = items;
 }

 public int getCount() {
  return items.size();
 }

 public Object getItem(int location) {
  return items.get(location);
 }

 public long getItemId(int position) {
  return position;
 }

 public View getView(int position, View convertView, ViewGroup parent) {

  if (inflater == null)
   inflater = (LayoutInflater) activity
     .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
  if (convertView == null)
   convertView = inflater.inflate(R.layout.list, null);

  if (imageLoader == null)
   imageLoader = AppController.getInstance().getImageLoader();
  NetworkImageView thumbNail = (NetworkImageView) convertView
    .findViewById(R.id.thumbnail);
  TextView title = (TextView) convertView.findViewById(R.id.title);
  TextView attack = (TextView) convertView.findViewById(R.id.attack);
  TextView attributes = (TextView) convertView
    .findViewById(R.id.attributes);
  TextView material = (TextView) convertView.findViewById(R.id.material);

  // getting movie data for the row
  ListItem m = items.get(position);

  // 縮圖
  thumbNail.setImageUrl(m.getThumbnailUrl(), imageLoader);

  // 名稱
  title.setText(m.getTitle());

  // 攻擊力
  attack.setText("攻擊力: " + String.valueOf(m.getAttack()));

  // 屬性
  attributes.setText("屬性: " + m.getAttributes());

  // 材料
  String materialStr = "";
  for (String str : m.getMaterial()) {
   materialStr += str + ", ";
  }
  materialStr = materialStr.length() > 0 ? materialStr.substring(0,
    materialStr.length() - 2) : materialStr;
  material.setText(materialStr);

  return convertView;
 }

}

11.MainActivity.java 主頁面
package tw.android;

import java.util.ArrayList;
import java.util.List;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

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

import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.VolleyLog;

public class MainActivity extends Activity {// Log tag
 private static final String TAG = MainActivity.class.getSimpleName();

 // json檔案位置
 private static final String url = "http://terryyamg.3eeweb.com/test/list.json";

 private List listItem = new ArrayList();
 private ListView listView;
 private CustomListAdapter adapter;

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

  listView = (ListView) findViewById(R.id.list);
  adapter = new CustomListAdapter(this, listItem);
  listView.setAdapter(adapter); 
  
  // 取得資料並編碼
  JsonArrayPostRequest itemReq = new JsonArrayPostRequest(url,
    new Response.Listener() {

     public void onResponse(JSONArray response) {

      // 解析json
      for (int i = 0; i < response.length(); i++) {
       try {
        
        //取得回應物件
        JSONObject obj = response.getJSONObject(i);
        //取得對定標題並放入item內
        ListItem item = new ListItem();
        item.setTitle(obj.getString("title"));
        item.setThumbnailUrl(obj.getString("image"));
        item.setAttack(obj.getInt("attack"));
        item.setAttributes(obj.getString("attributes"));
        //多項目處理
        JSONArray materialArry = obj
          .getJSONArray("material");
        ArrayList material = new ArrayList();
        for (int j = 0; j < materialArry.length(); j++) {
         material.add((String) materialArry.get(j));
        }
        item.setMaterial(material);

        // 將所有項目item放入listItem陣列
        listItem.add(item);

       } catch (JSONException e) {
        e.printStackTrace();
       }

      }

      // 更新adapter數據
      adapter.notifyDataSetChanged();
     }
     
     
    }, new Response.ErrorListener() {

     public void onErrorResponse(VolleyError error) {
      VolleyLog.d(TAG, "Error: " + error.getMessage());

     }
    });

  // 使用AppController內的排序
  AppController.getInstance().addToRequestQueue(itemReq);
 }

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



}

1.檔案下載:
https://github.com/terryyamg/CacheImageTest
 2.參考連結:
http://www.androidhive.info/2014/07/android-custom-listview-with-image-and-text-using-volley/
http://dnakreatif.com/programming/android-volley-jsonarray-post-with-params/
http://stackoverflow.com/questions/19267616/why-does-volleys-response-string-use-an-encoding-different-from-that-in-the-res

2015年4月28日 星期二

Android Load Image From Camera Or Gallery 讀取照片從相機或圖片庫

利用相機拍照或從已經存在的圖片庫,讀取照片並紀錄,將其顯示在app上。
1.AndroidManifest.xml加入讀取與寫入權限
 
 
2./res/layout/activity_main.xml


    

        
    

    

        
        
    


3.MainActivity.java
package tw.android;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.provider.MediaStore.MediaColumns;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;

public class MainActivity extends Activity {

 private Button btnSelect;
 private ImageView ivImage;

 private int REQUEST_CAMERA = 0, SELECT_FILE = 1;
 private String selectedImagePath; // 圖片檔案位置

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  btnSelect = (Button) findViewById(R.id.btnSelectPhoto);
  ivImage = (ImageView) findViewById(R.id.ivImage);

  // 取出最後圖片檔案位置
  try {
   SharedPreferences preferencesGet = getApplicationContext()
     .getSharedPreferences("image",
       android.content.Context.MODE_PRIVATE);
   selectedImagePath = preferencesGet.getString("selectedImagePath",
     ""); // 圖片檔案位置,預設為空

   Log.i("selectedImagePath", selectedImagePath + "");

  } catch (Exception e) {
  }

  /* 選擇照片 */
  btnSelect.setOnClickListener(new OnClickListener() {

   public void onClick(View v) {
    selectImage();
   }
  });

  setImage();
 }

 /* 設定圖片 */
 private void setImage() {
  BitmapFactory.Options options = new BitmapFactory.Options();
  options.inJustDecodeBounds = false; // 不顯示照片
  BitmapFactory.decodeFile(selectedImagePath, options);
  final int REQUIRED_SIZE = 200;
  int scale = 1;
  /* 圖片縮小2倍 */
  while (options.outWidth / scale / 2 >= REQUIRED_SIZE
    && options.outHeight / scale / 2 >= REQUIRED_SIZE) {
   scale *= 2;
  }
  options.inSampleSize = scale;
  options.inJustDecodeBounds = false; // 顯示照片
  Bitmap bm = BitmapFactory.decodeFile(selectedImagePath, options);
  Log.i("selectedImagePath", selectedImagePath + "");
  ivImage.setImageBitmap(bm);// 將圖片顯示
 }

 private void selectImage() {
  final String item1, item2, item3;
  item1 = "拍一張照";
  item2 = "從圖庫選取";
  item3 = "取消";

  final CharSequence[] items = { item1, item2, item3 };

  AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
  builder.setTitle("新增照片視窗");
  builder.setItems(items, new DialogInterface.OnClickListener() {
   public void onClick(DialogInterface dialog, int item) {
    switch (item) {
    case 0: // 拍一張照
     Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
     startActivityForResult(intent, REQUEST_CAMERA);
     break;
    case 1: // 從圖庫選取
     Intent intent1 = new Intent(
       Intent.ACTION_PICK,
       android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
     intent1.setType("image/*");
     startActivityForResult(
       Intent.createChooser(intent1, "選擇開啟圖庫"),
       SELECT_FILE);
     break;
    default: // 取消
     dialog.dismiss(); // 關閉對畫框
     break;
    }

   }
  });
  builder.show();
 }

 /* 啟動選擇方式 */
 @Override
 public void onActivityResult(int requestCode, int resultCode, Intent data) {
  super.onActivityResult(requestCode, resultCode, data);

  if (resultCode == Activity.RESULT_OK) {
   if (requestCode == SELECT_FILE) // 從圖庫開啟
    onSelectFromGalleryResult(data);
   else if (requestCode == REQUEST_CAMERA) // 拍照
    onCaptureImageResult(data);
  }
 }

 /* 拍照 */
 private void onCaptureImageResult(Intent data) {
  Bitmap thumbnail = (Bitmap) data.getExtras().get("data");
  ByteArrayOutputStream bytes = new ByteArrayOutputStream();
  thumbnail.compress(Bitmap.CompressFormat.JPEG, 90, bytes);
  File destination = new File(Environment.getExternalStorageDirectory(),
    System.currentTimeMillis() + ".jpg"); // 輸出檔案名稱
  selectedImagePath = destination + ""; // 輸出檔案位置
  FileOutputStream fo;
  try {
   destination.createNewFile(); // 建立檔案
   fo = new FileOutputStream(destination); // 輸出
   fo.write(bytes.toByteArray());
   fo.close();
  } catch (FileNotFoundException e) {
   e.printStackTrace();
  } catch (IOException e) {
   e.printStackTrace();
  }

  ivImage.setImageBitmap(thumbnail); // 將圖片顯示
 }

 @SuppressWarnings("deprecation")
 private void onSelectFromGalleryResult(Intent data) {
  Uri selectedImageUri = data.getData();
  String[] projection = { MediaColumns.DATA };
  Cursor cursor = managedQuery(selectedImageUri, projection, null, null,
    null);
  int column_index = cursor.getColumnIndexOrThrow(MediaColumns.DATA);
  cursor.moveToFirst();

  selectedImagePath = cursor.getString(column_index); // 選擇的照片位置

  setImage(); // 設定圖片
 }

 /* 結束時 */
 @Override
 protected void onDestroy() {
  super.onDestroy();
  /* 紀錄圖片檔案位置 */
  SharedPreferences preferencesSave = getApplicationContext()
    .getSharedPreferences("image",
      android.content.Context.MODE_PRIVATE);
  SharedPreferences.Editor editor = preferencesSave.edit();
  editor.putString("selectedImagePath", selectedImagePath); // 紀錄最後圖片位置
  editor.commit();

  Log.i("onDestroy", "onDestroy");
 }

}



檔案下載:
https://github.com/terryyamg/loadImageFromGalleryTest
參考來源:
http://www.theappguruz.com/blog/android-take-photo-camera-gallery-code-sample/

2015年4月21日 星期二

Android Load Image From Url 讀取網址照片

從網址上讀取圖片,仿ptt app讀圖片功能
1.AndroidManifest.xml加入網路權限
    
    

2./res/layout/activity_main.xml


    

    

    
    


3.MainActivity.java
package tw.android;

import java.io.InputStream;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;

public class MainActivity extends Activity {

 private Button btUrl, btLoad;
 private String url;

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

  btUrl = (Button) findViewById(R.id.btUrl);
  btLoad = (Button) findViewById(R.id.btLoad);

  /* 顯示url */

  url = "http://i.imgur.com/WPydEEx.jpg"; // 圖片網址
  btUrl.setText(url); // 顯示網址
  btUrl.setOnClickListener(new Button.OnClickListener() {
   public void onClick(View v) {
    Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri
      .parse(url));
    startActivity(browserIntent); // 使用網頁開啟
   }
  });

  /* 下載圖片 */
  btLoad.setOnClickListener(new Button.OnClickListener() {
   public void onClick(View v) {
    btLoad.setVisibility(View.GONE); // 隱藏按鈕
    new DownloadImageTask((ImageView) findViewById(R.id.ivLoad))
      .execute(url); // 載入圖片

   }
  });

 }

 /* AsyncTask執行下載任務 */
 @SuppressLint("NewApi")
 private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
  ImageView bmImage;

  public DownloadImageTask(ImageView bmImage) {
   this.bmImage = bmImage;
  }

  protected Bitmap doInBackground(String... urls) {
   String urldisplay = urls[0];
   Bitmap mIcon11 = null;
   try {
    InputStream in = new java.net.URL(urldisplay).openStream(); // 從網址上下載
    mIcon11 = BitmapFactory.decodeStream(in);
   } catch (Exception e) {
    Log.e("Error", e.getMessage());
    e.printStackTrace();
   }
   return mIcon11;
  }

  protected void onPostExecute(Bitmap result) {
   bmImage.setImageBitmap(result); // 下載完成後載入結果
  }
 }
}


參考網址:
http://stackoverflow.com/questions/5776851/load-image-from-url