2015년 9월 19일 토요일

GPS 이용해 현재 위치 얻어오기

MainActivity.java



public class MainActivity extends Activity {
    ListView listView;
    ItemListAdapter adapter;
    List<OneItem> items;
    int cnt = 0;

    public class OneItem {
        String time;
        String content;
        public OneItem(String time, String content) {
            this.time = time;
            this.content = content;
        }
    }

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

        Button button01 = (Button) findViewById(R.id.button01);
        button01.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                startLocationService();
            }
        });

        items =  new ArrayList<OneItem>();

        listView = (ListView)findViewById(R.id.listView);
        adapter = new ItemListAdapter(this, R.layout.item_layout, items);
        listView.setAdapter(adapter);
    }

    class ItemListAdapter extends ArrayAdapter<OneItem> {
        private List<OneItem> items;
        private Context context;
        private int layoutResource;

        public void setContext(Context c) {
            this.context = c;
        }

        public ItemListAdapter(Context context, int layoutResource, List<OneItem> items) {
            super(context, layoutResource, items);
            this.context = context;
            this.items =  items;
            this.layoutResource = layoutResource;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            if (convertView == null) {
                LayoutInflater layoutInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                convertView = layoutInflater.inflate(layoutResource, null);
            }

            final OneItem oneItem = items.get(position);

            if (oneItem != null) {
                TextView content = (TextView) convertView.findViewById(R.id.content);
                TextView time = (TextView) convertView.findViewById(R.id.time);

                if (content != null){
                    content.setText(oneItem.content);
                }
                if (time != null){
                    time.setText(oneItem.time);
                }
            }
            return convertView;
        }
    }

    private void startLocationService() {
        LocationManager manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

        GPSListener gpsListener = new GPSListener();
        long minTime = 1000;
        float minDistance = 0;

        try {
            //최근에 알려진 위치 얻어오기
            Location lastLocation = manager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
            if (lastLocation != null) {
                Double latitude = lastLocation.getLatitude();
                Double longitude = lastLocation.getLongitude();

                Timestamp cur = new Timestamp(System.currentTimeMillis());
                items.add(new OneItem(cur.toString(), cnt + "\n(" + latitude + "," + longitude+")"));
                cnt++;
                listView.setAdapter(adapter);
            }

            //주기적으로 GPS 정보 받도록 요청
            manager.requestLocationUpdates(
                    LocationManager.GPS_PROVIDER,
                    minTime,
                    minDistance,
                    gpsListener);

            manager.requestLocationUpdates(
                    LocationManager.NETWORK_PROVIDER,
                    minTime,
                    minDistance,
                    gpsListener);
        }
        catch(SecurityException ex) {
            ex.printStackTrace();
        }
        catch(Exception ex) {
            ex.printStackTrace();
        }
    }

    private class GPSListener implements LocationListener {
        public void onLocationChanged(Location location) {
            Double latitude = location.getLatitude();
            Double longitude = location.getLongitude();

            Timestamp cur = new Timestamp(System.currentTimeMillis());
            items.add(new OneItem(cur.toString(), cnt + "\n(" + latitude + "," + longitude+")"));
            cnt++;

            listView.setAdapter(adapter);
        }

        public void onProviderDisabled(String provider) {}
        public void onProviderEnabled(String provider) {}
        public void onStatusChanged(String provider, int status, Bundle extras) {}
    }
}
activity_main.xml



<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent">

    <Button
        android:id="@+id/button01"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="위치 확인 시작"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true" />

    <ListView
        android:id="@+id/listView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_below="@+id/button01" />
</RelativeLayout>


item_layout.xml



<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <TextView
        android:id="@+id/content"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="content" />

    <TextView
        android:id="@+id/time"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/content"
        android:layout_below="@+id/content"
        android:text="Time" />

</RelativeLayout>

Android Studio 사용 Tip

이제 Android Studio를 가지 않을 수 없는 거스를 수 없는 흐름이 되었다.
왜냐면 구글 공식 설명이 대부분 Android Studio만을 설명하고 있기 때문이다. ㅠㅠ
이에 몇 가지 Tip을 정리해둔다.

Auto Import

File -> Settings 에서 import로 찾아보면
Auto Import 옵션을 바꿀 수 있다.

Optimize imports on the fly 와
Add unambiguous imports on the fly 를 체크해두자.

이걸로도 자동으로 import안되는 건 하나하나 찾아서
alt + Enter를 눌러서 해야 하는 듯.

이후 발견되는 데로 계속 업데이트 예정~~

Library 추가

File -> Project Structure 에서 app 에서 Dependencies
에서 추가를 하면 다양한 라이브러리들 추가가 가능

2015년 9월 12일 토요일

SurfaceView Simple


SimpleSurfaceView.java
public class SimpleSurfaceView extends SurfaceView implements SurfaceHolder.Callback, Runnable {

 private SurfaceHolder holder;
 private Thread thread;
 
 private Bitmap image;
 private int px = 0;
 private int py = 0;
 private int vx = 1;
 private int vy = 1;
 
 public SimpleSurfaceView(Context context) {
  super(context);
  
  Resources r = getResources();
  image = BitmapFactory.decodeResource(r, R.drawable.ic_launcher);
  
  holder = getHolder();
  holder.addCallback(this);
  holder.setFixedSize(getWidth(), getHeight());
 }

 public void surfaceCreated(SurfaceHolder holder) {
  thread = new Thread(this);
  thread.start();
 }

 public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
  
 }
 
 public void surfaceDestroyed(SurfaceHolder holder) {
  thread = null;
 }
 
 public void stopThread() {
  thread = null;
 }
 
 @Override
 public void run() {
  Canvas canvas;
  while (thread != null) {
   canvas = holder.lockCanvas();
   canvas.drawColor(Color.WHITE);
   canvas.drawBitmap(image,  px-40,  py-40, null);
   holder.unlockCanvasAndPost(canvas);
   
   if (px < 0 || getWidth() < px ) vx = -vx;
   if (py < 0 || getHeight() < py ) vy = -vy;
   
   px += vx;
   py += vy;
  }
 }
}

SimpleSurfaceViewActivity.java
public class SimpleSurfaceViewActivity extends Activity {
 SimpleSurfaceView surfaceView;
 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  requestWindowFeature(Window.FEATURE_NO_TITLE);
  getWindow().setFormat(PixelFormat.TRANSLUCENT);
  
  surfaceView = new SimpleSurfaceView(this);
  setContentView(surfaceView);
 }
 
 public void onPause() {
  super.onPause();
  surfaceView.stopThread();
  
 }
}

DB 사용하기

MyDBOpenHelper.java

public class MyDBOpenHelper extends SQLiteOpenHelper {

 private static final String DATABASE_NAME = "your_db_name";
 private static final int DATABASE_VERSION = 2;
 
 public static final String TABLE_NAME = "yout_table_name";
 
 public static final String ID = "id";
 public static final String VALUE = "value";
 
 
 public MyDBOpenHelper(Context context) {
  super(context, DATABASE_NAME, null, DATABASE_VERSION);
 }

 @Override
 public void onCreate(SQLiteDatabase db) {
  db.execSQL("CREATE TABLE dbTable (" + ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + VALUE + " TEXT);");
 }

 @Override
 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
  db.execSQL("DROP TABLE IF EXISTS dbTable");
  onCreate(db);
 }
}



DBActivity.java

public class DBActivity extends FragmentActivity implements DbAddDialogListener {
 MyDBOpenHelper myDBOpenHelper;
 SQLiteDatabase sqdb;

 ListView listView;
 DbAddEditDialog addEditDialog;
 FragmentManager fm;

 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  requestWindowFeature(Window.FEATURE_NO_TITLE);
  setContentView(R.layout.db_activity_layout);

  addEditDialog = new DbAddEditDialog();
  addEditDialog.setListener(this);
  fm = ((FragmentActivity)this).getSupportFragmentManager();

  myDBOpenHelper = new MyDBOpenHelper(this);
  sqdb = myDBOpenHelper.getWritableDatabase();

  updateList();

  Button addBtn = (Button)findViewById(R.id.addBtn);
  addBtn.setOnClickListener(new OnClickListener() {
   @Override
   public void onClick(View v) {
    try {
     addEditDialog.setMsg("");
     addEditDialog.setDbId(null);
     addEditDialog.show(fm, null);
    } 
    catch (ClassCastException e) { }
   }
  });
 }

 private void updateList() {
  List<MyItem> list = new ArrayList<MyItem>();

  Cursor c = sqdb.query(MyDBOpenHelper.TABLE_NAME, 
    new String[] {MyDBOpenHelper.ID, MyDBOpenHelper.VALUE}, 
    null, null,null,null,null);

  while (c.moveToNext()) {
   int id = c.getInt(c.getColumnIndex(MyDBOpenHelper.ID));
   String value = c.getString(c.getColumnIndex(MyDBOpenHelper.VALUE));
   
   MyItem item = new MyItem();
   item.setId(id);
   item.setTitle(value);
   list.add(item);
  }
  c.close();
  
  CustomAdapter adapter = new CustomAdapter(this, R.layout.db_list_view_item, list);
  listView = (ListView)findViewById(R.id.listView1);
  listView.setAdapter(adapter);
 }

 class MyItem {
  private Integer id;
  private String title;
  public Integer getId() { return id; }
  public String getTitle() { return title; }
  public void setId(Integer id) { this.id = id; }
  public void setTitle(String title) { this.title = title; }
 }

 class CustomAdapter extends ArrayAdapter<MyItem> {
  private List<MyItem> items;
  private int layoutResource;
  public CustomAdapter(Context context, int layoutResource, List<MyItem> items) {
   super(context, layoutResource, items);
   this.items =  items;
   this.layoutResource = layoutResource;
  }

  @Override        
  public View getView(int position, View convertView, ViewGroup parent) {
   if (convertView == null) {
    LayoutInflater layoutInflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    convertView = layoutInflater.inflate(layoutResource, null);
   }

   final MyItem myItem = items.get(position);                 
   if (myItem != null) {
    TextView title = (TextView)convertView.findViewById(R.id.textView1);                         
    if (title != null){                             
     title.setText(myItem.getTitle());           
    }
    Button editBtn = (Button)convertView.findViewById(R.id.editBtn);
    editBtn.setOnClickListener(new OnClickListener() {
     @Override
     public void onClick(View v) {
      addEditDialog.setMsg(myItem.getTitle());
      addEditDialog.setDbId(myItem.getId());
      addEditDialog.show(fm, null);
     }
    });
    Button deleteBtn = (Button)convertView.findViewById(R.id.deleteBtn);
    deleteBtn.setOnClickListener(new OnClickListener() {
     @Override
     public void onClick(View v) {
      sqdb.delete(MyDBOpenHelper.TABLE_NAME, MyDBOpenHelper.ID + " = ?", new String[] { String.valueOf(myItem.getId()) });
      updateList();
     }
    });
   }                 
   return convertView;         
  } 
 }

 @Override
 public void okClicked(String str, Integer id) {
  if (id == null) {
   ContentValues values = new ContentValues();  
   values.put(MyDBOpenHelper.VALUE, str);  
   sqdb.insert(MyDBOpenHelper.TABLE_NAME, null, values);  
  }
  else {
   ContentValues values = new ContentValues();  
   values.put(MyDBOpenHelper.ID, id);  
   values.put(MyDBOpenHelper.VALUE, str);  
   sqdb.update(MyDBOpenHelper.TABLE_NAME, values, MyDBOpenHelper.ID + " = ?", new String[] { String.valueOf(id) });
  }
  updateList();
 }
}



DbAddEditDialog.java

public class DbAddEditDialog extends DialogFragment {
 String msg;
 Integer dbId; 
 DbAddDialogListener listener;
 
 public Integer getDbId() { return dbId; }
 public String getMsg() { return msg; }
 public void setDbId(Integer dbId) { this.dbId = dbId; }
 public void setMsg(String msg) { this.msg = msg; }
 public void setListener(DbAddDialogListener listener) { this.listener = listener; }
 
 public interface DbAddDialogListener {
  public void okClicked(String str, Integer id);
 }
 
 @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        LayoutInflater li = LayoutInflater.from(getActivity());
  View promptsView = li.inflate(R.layout.dialog_layout, null);

  AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(getActivity());
  alertDialogBuilder.setView(promptsView);

  if (dbId != null) {
   TextView textView = (TextView)promptsView.findViewById(R.id.textView1);
   textView.setText("edit the db data");
  }
  
  final EditText userInput = (EditText) promptsView.findViewById(R.id.editTextDialogUserInput);
  userInput.setText(msg);
  alertDialogBuilder
   .setCancelable(false)
   .setPositiveButton("OK",new OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which) {
     listener.okClicked(userInput.getText().toString(), dbId);
    }
   })
   .setNegativeButton("Cancel",
     new DialogInterface.OnClickListener() {
       public void onClick(DialogInterface dialog,int id) {
        dialog.cancel();
       }
     });

  AlertDialog alertDialog = alertDialogBuilder.create();

  return alertDialog;
    }
}



dialog_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/layout_root"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    android:padding="10dp" >
 
    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Insert into DB"
        android:textAppearance="?android:attr/textAppearanceLarge" />
 
    <EditText
        android:id="@+id/editTextDialogUserInput"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >
 
        <requestFocus />
 
    </EditText>
 
</LinearLayout>



db_activity_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/header" >

        <Button
            android:id="@+id/addBtn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_alignParentTop="true"
            android:text="Add" />

        <TextView
            android:id="@+id/textView1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignBaseline="@+id/addBtn"
            android:layout_alignBottom="@+id/addBtn"
            android:layout_centerHorizontal="true"
            android:text="Database" />
        
    </RelativeLayout>

    <ListView
        android:id="@+id/listView1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >
    </ListView>

</LinearLayout>

프로그래밍 적으로 View 만들어 배치하기

@Override
public void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 requestWindowFeature(Window.FEATURE_NO_TITLE);
 
 RelativeLayout relativeLayout = new RelativeLayout(this);
 
 RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
   RelativeLayout.LayoutParams.WRAP_CONTENT, 
   RelativeLayout.LayoutParams.WRAP_CONTENT);
 
 params.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE);

 TextView textView = new TextView(this);
 textView.setText("Hello World");

 relativeLayout.addView(textView, params); 

 setContentView(relativeLayout);
}

Asset에서 파일 읽기


BufferedReader reader = null;
try {
 reader = new BufferedReader(new InputStreamReader(getAssets().open("filename"))); 

 while (true) {
  String line = reader.readLine(); 
  if (line == null) {
   break;
  }
 }
} 
catch (IOException e) {} 
finally {if (reader != null) {try {reader.close();} catch (IOException e) {}}}



2015년 9월 5일 토요일

안드로이드 개발 시 유용한 사이트들

1. 무료 이미지 얻을 수 있는 곳. (저작권 free)
https://pixabay.com

2. 공공 데이터 API
https://www.data.go.kr/

3. Do it 안드로이드 소스 자료실
http://www.android-town.org/

4. html 문서 안에 소스코드 넣고 싶을 때
http://hilite.me/



View의 알파 주기


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/pic2" >

    <RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:background="#50FFFFFF"
        android:layout_centerVertical="true" >

        <TextView
            android:id="@+id/textView1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="#000000"
            android:text="The real risk is doing nothing.\n\n진짜 위험한 것은 아무것도 하지 않는 것이다." />

    </RelativeLayout>

</RelativeLayout>



        android:background="#50FFFFFF"

여기에서 50이 알파값이다.

Naver Open API 사용하는 법

네이버에서 naver api로 검색하거나 아래 URL로 접속

http://developer.naver.com/wiki/pages/OpenAPI



WebRequestListView

public class WebRequestListView extends FragmentActivity {
 private FragmentManager fm;
 private LoadingDialog loadingDlg;
 private MyItemAdapter adapter;
 private ListView lv;

 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  requestWindowFeature(Window.FEATURE_NO_TITLE); 
  setContentView(R.layout.web_request_list_view);
  getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
    WindowManager.LayoutParams.FLAG_FULLSCREEN);

  fm = ((FragmentActivity)this).getSupportFragmentManager();
  lv = (ListView)findViewById(R.id.list);

  loadingDlg = new LoadingDialog();
  loadingDlg.setMsg("loading...");
  loadingDlg.setCancelable(false);
  loadingDlg.setNoBtn(true);

  loadingDlg.show(fm, null);
  retrieveContent();
 }

 private void retrieveContent() {
  new AsyncTask<Void, Void, List<MyItem>>() {
   @Override
   protected List<MyItem> doInBackground(Void... params) {
    return getDom("http://openapi.naver.com/search?key=c1b406b32dbbbbeee5f2a36ddc14067f&query=%EB%A6%AC%EB%B7%B0&display=10&start=1&target=blog&sort=sim");
   }

   @Override
   protected void onPostExecute(List<MyItem> items) {
    loadingDlg.dismiss();

    adapter = new MyItemAdapter(WebRequestListView.this, R.layout.list_view_item_rank, items);
    adapter.setContext(WebRequestListView.this);
    lv.setAdapter(adapter);
   }
  }.execute(null, null, null);
 }

 public class MyItemAdapter extends ArrayAdapter<MyItem>  {
  private List<MyItem> items;
  private Context context;
  private int layoutResource;

  public void setContext(Context c) {
   this.context = c;
  }

  public MyItemAdapter(Context context, int layoutResource, List<MyItem> items) {
   super(context, layoutResource, items);
   this.context = context;
   this.items =  items;
   this.layoutResource = layoutResource;
  }

  @Override        
  public View getView(int position, View convertView, ViewGroup parent) {
   final MyItem myItem = items.get(position);

   if (convertView == null) {
    LayoutInflater layoutInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    convertView = layoutInflater.inflate(layoutResource, null);
   }

   if (myItem != null) {
    TextView content = (TextView) convertView.findViewById(R.id.content);

    if (content != null){                             
     content.setTextSize(20);
     content.setTextColor(Color.BLACK);
     content.setText(myItem.getContent());           
    }          
   }                 
   return convertView;         
  }
 }

 public class MyItem {
  public String content;

  public String getContent() {
   return content;
  }

  public void setContent(String content) {
   this.content = content;
  }
 }

 public List<MyItem> getDom(String webpage) {
  List<MyItem> items = new ArrayList<MyItem>();

  DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();

  try {
   DocumentBuilder builder = builderFactory.newDocumentBuilder();

   URL url = new URL(webpage);

   HttpURLConnection conn = (HttpURLConnection) url.openConnection();
   conn.setRequestMethod("POST");
   conn.setDoInput(true);
   conn.setDoOutput(true);

   int resCode = conn.getResponseCode();

   InputStream instream = conn.getInputStream();

   Document document = builder.parse(instream);

   Element docEle = document.getDocumentElement();
   NodeList nodelist = docEle.getElementsByTagName("item");
   if ((nodelist != null) && (nodelist.getLength() > 0)) {
    for (int i = 0; i < nodelist.getLength(); i++) {
     
     Element entry = (Element)nodelist.item(i);
     String title = entry.getElementsByTagName("title").item(0).getTextContent();
     String description = entry.getElementsByTagName("description").item(0).getTextContent();
     
     MyItem item = new MyItem();
     //item.setContent(title);
     item.setContent(description);

     items.add(item);
    }
   }
  } catch (ParserConfigurationException e) {
   e.printStackTrace();
  }
  catch (SAXException e) {
   e.printStackTrace();
  }
  catch (MalformedURLException e) {
   e.printStackTrace();
  }
  catch (IOException e) {
   e.printStackTrace();
  }

  return items;
 }
}