ȸ¿ø·Î±×ÀÎ
8³â Àü
½Ã½ºÅÛ Á¤º¸
StringBuffer buf = new StringBuffer();
buf.append("VERSION.RELEASE {"+Build.VERSION.RELEASE+"}");
buf.append("\\nVERSION.INCREMENTAL {"+Build.VERSION.INCREMENTAL+"}");
buf.append("\\nVERSION.SDK {"+Build.VERSION.SDK+"}");
buf.append("\\nBOARD {"+Build.BOARD+"}");
buf.append("\\nBRAND {"+Build.BRAND+"}");
buf.append("\\nDEVICE {"+Build.DEVICE+"}");
buf.append("\\nFINGERPRINT {"+Build.FINGERPRINT+"}");
buf.append("\\nHOST {"+Build.HOST+"}");
buf.append("\\nID {"+Build.ID+"}");
Log.d("build",buf.toString());
====================================================================================
UI
Screen
ȸé Å©±â °¡Á®¿À±â
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
screenWidth = metrics.widthPixels;
È¸é ¹à±â Á¶Á¤
WindowManager.LayoutParams lp = getWindow().getAttributes();
lp.screenBrightness = (float)progress/100.0f; // 1.0f = 100%
getWindow().setAttributes(lp);
Activity
È¸é ¹æÇâ(Screen Orientation) °íÁ¤
AndroidManifest.xml¿¡¼ ÇØ´ç Activity ¼Ó¼ºÀ» ´ÙÀ½°ú °°ÀÌ ¼öÁ¤.
<activity
android:screenOrientation="landscape"
...>
. . .
</activity>
Áï android:screenOrientation ¼Ó¼ºÀ» "landscape" ȤÀº "portrait" µîÀ¸·Î º¯°æ.
Title Bar Á¦°Å
onCreate() ¿¡¼ ó¸®ÇÏ´Â ¹æ¹ý
//Remove title bar
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
//Remove notification bar
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
//set content view AFTER ABOVE sequence (to avoid crash)
this.setContentView(R.layout.your_layout_name_here);
AndroidManifest.xml¿¡¼ ó¸®ÇÏ´Â ¹æ¹ý
<activity
android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen"
...>
. . .
</activity>
Content View °¡Á®¿À±â
setContentView() ·Î ÁöÁ¤ÇÑ ActivityÀÇ Content View¸¦ °¡Á®¿À´Â ¹æ¹ý.
this.getWindow().getDecorView().findViewById(android.R.id.content)
or
this.findViewById(android.R.id.content)
or
this.findViewById(android.R.id.content).getRootView()
¾×ƼºñƼ¿¡ ÆĶó¸ÅÅÍ Àü´Þ
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
Bundle b = new Bundle();
b.putInt("key", 1); //Your id
intent.putExtras(b); //Put your id to your next Intent
startActivity(intent);
finish();
Bundle b = getIntent().getExtras();
int value = b.getInt("key");
Back key·Î ¾×ƼºñƼ¸¦ ´ÝÀ» ¶§ÀÇ À̺¥Æ®
@Override
public void onBackPressed() { ... }
¹Ù±ù ÅÍÄ¡·Î ´ëÈ Ã¢ÀÌ ´ÝÈ÷Áö ¾Ê°Ô Çϱâ
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_yoptions);
// Activity¿¡¼ setFinishOnTouchOutside(false)·Î ¼Ó¼º º¯°æ.
this.setFinishOnTouchOutside(false);
}
private void showInfoDialog(int string_id) {
ProgressDialog dlg = new ProgressDialog(getActivity());
dlg.setTitle(R.string.login);
dlg.setMessage(getString(string_id));
dlg.setProgressStyle(ProgressDialog.STYLE_SPINNER);
// Dialog¿¡¼´Â ´ÙÀ½°ú °°ÀÌ ¼ÂÆÃ.
dlg.setCancelable(false);
dlg.setCanceledOnTouchOutside(false);
// . . .
}
Fragment (API 11)
http://muzesong.tistory.com/84
ÇÑ Activity ³»¿¡¼ ´Ù½Ã UI¿µ¿ªÀ» ºÐÇÒÇؼ °ü¸®ÇÒ ¼ö ÀÖ°Ô ÇØÁØ´Ù. Fragmentµµ Activiy¿Í ºñ½ÁÇÑ »ý¸íÁֱ⸦ °®´Â´Ù.
Fragment¿¡ ÆĶó¸ÅÅÍ Àü´Þ
/*** From Activity you send data with intent as: ***/
Bundle bundle = new Bundle();
bundle.putString("edttext", "From Activity");
// set Fragmentclass Arguments
Fragmentclass fragobj = new Fragmentclass();
fragobj.setArguments(bundle);
/*** in Fragment onCreateView method: ***/
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
String strtext = getArguments().getString("edttext");
return inflater.inflate(R.layout.fragment, container, false);
}
ViewPager
'½º¿ÍÀÌÇÁ·Î ÆäÀÌÁö Àüȯ' ¸·±â
public class CustomViewPager extends ViewPager {
private boolean enabled;
public CustomViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
this.enabled = true;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (this.enabled) {
return super.onTouchEvent(event);
}
return false;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
if (this.enabled) {
return super.onInterceptTouchEvent(event);
}
return false;
}
public void setPagingEnabled(boolean enabled) {
this.enabled = enabled;
}
}
<mypackage.CustomViewPager
android:id="@+id/myViewPager"
android:layout_height="match_parent"
android:layout_width="match_parent" />
À̹ÌÁö ó¸®
Bitmap
Bitmap bmImg = BitmapFactory.decodeFile("path of your img1");
imageView.setImageBitmap(bmImg);
Drawable
º¹Á¦
Drawable clone = drawable.getConstantState().newDrawable();
Note.png
ÁÖÀÇ!!
°°Àº ¸®¼Ò½ºID·ÎºÎÅÍ ¸¸µé¾îÁø ¸ðµç Drawable °´Ã¼´Â color filter µîÀÇ »óŸ¦ °øÀ¯ÇÏ°í ÀÖ´Ù. ¸¸¾à º¹Á¦ÀÇ ¸ñÀûÀÌ ÀÌ·± °øÀ¯µÈ »óÅ¿¡¼ ºÐ¸®½ÃÅ°·Á´Â °ÍÀ̶ó¸é, cloneÀ» ÇÏÁö¸»°í ´ÙÀ½°ú °°Àº Äڵ带 »ç¿ëÇÒ °Í!
// To make a drawable use a separate constant state
drawable.mutate();
Grayscale
public static Drawable convertToGrayscale(Drawable drawable) {
ColorMatrix matrix = new ColorMatrix();
matrix.setSaturation(0);
ColorMatrixColorFilter filter = new ColorMatrixColorFilter(matrix);
drawable.setColorFilter(filter);
return drawable;
}
Ä÷¯ º¯È¯
public static Drawable changeColor(Drawable drawable, int color) {
Drawable d = drawable.mutate();
d.setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
return d;
}
Drawable ³»¿ëÀ» Canvas¿¡ ±×¸®±â
Canvas canvas = new Canvas(lq);
Drawable drawable = drawImageView.getDrawable().mutate();
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
canvas.save();
Shape Drawable
http://www.androidpub.com/2113
XML·Î Á¤ÀÇÇÑ º¤ÅÍ À̹ÌÁö¸¦ Drawble °´Ã¼·Î È°¿ëÇÒ ¼ö ÀÖ´Ù.
<!-- »ç°¢Çü -->
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#FF0000FF"/>
<stroke android:width="4dp" android:color="#FFFFFFFF"
android:dashWidth="1dp" android:dashGap="2dp" />
<padding android:left="7dp" android:top="7dp"
android:right="7dp" android:bottom="7dp" />
<corners android:radius="4dp" />
</shape>
<!-- Ÿ¿ø -->
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
<solid android:color="#00000000"/>
<stroke android:width="4dp" android:color="#99000000"
android:dashWidth="4dp" android:dashGap="2dp" />
<padding android:left="7dp" android:top="7dp"
android:right="7dp" android:bottom="7dp" />
<corners android:radius="4dp" />
</shape>
<!-- Line -->
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="line">
<stroke android:width="1dp" android:color="#FF000000"
android:dashWidth="1dp" android:dashGap="2dp" />
</shape>
±×¶óµ¥ÀÌ¼Ç È¿°ú
<gradient android:startColor="#FFFF0000" android:endColor="#80FF00FF" android:angle="270"/>
ImageView
·ÎÄà ÆÄÀÏÀÇ À̹ÌÁö Ç¥½Ã
File imgFile = new File(¡°filepath¡±);
if(imgFile.exists()) {
ImageView myImage = new ImageView(this);
myImage.setImageURI(Uri.fromFile(imgFile));
}
À̹ÌÁö °»½Å
ImageViewÀÇ invalidate()¸¦ È£ÃâÇÏ¸é µÇ´Âµ¥, ¹Ýµå½Ã UI ¾²·¹µå¿¡¼ ½ÇÇàµÇ¾ß ÇÏ´Â °Í¿¡ ÁÖÀÇ.
runOnUiThread(new Runnable() {
@Override
public void run() {
imageView.setImageBitmap(BitmapFactory.decodeByteArray(imgArray, 0, imgArray.length));
imageView.invalidate();
}
});
WebView
http://developer.android.com/guide/webapps/webview.html
HTML View
String º¯¼ö¿¡ ´ã°ÜÀÖ´Â HTMLµ¥ÀÌÅ͸¦ WebView¸¦ ÅëÇؼ º¸¿©ÁÖ°íÀÚ ÇÒ ¶§, ¹®ÀÚ¿ ÀÎÄÚµù ¹®Á¦°¡ ¹ß»ýÇÒ ¼ö ÀÖ´Ù. ÀÌ °æ¿ì, WebViewÀÇ loadData() ¸»°í loadDataWithBaseURL() ¸Å¼µå¸¦ »ç¿ëÇÏÀÚ. loadData()¿¡¼´Â ÀÎÄÚµù ¼³Á¤ÀÌ Á¦´ë·Î µ¿ÀÛÇÏÁö ¾Ê´Â´Ù. (¹ö±×Àεí)
WebView htmlView = (WebView) rootView.findViewById(R.id.body_html);
htmlView.loadDataWithBaseURL(null, "<p>ù¼ª«ªÎ«Æ«¹«ÈªÇª¹¡£</p>", "text/html", "UTF-8", null);
WebView¿¡¼ ¸µÅ©°¡ »õâÀ¸·Î ¿¸®Áö ¾Ê°Ô
WebViewClient¸¦ ÁöÁ¤ÇØ ÁÖÁö ¾ÊÀ¸¸é, À¥ ºä ³»ÀÇ ¸µÅ©°¡ ¿ÜºÎ À¥ºê¶ó¿ìÁ®¸¦ ÅëÇؼ ¿¸®°Ô µÈ´Ù.
WebView webview = new WebView(this /*context*/);
webview.setWebViewClient(new WebViewClient());
webview.loadUrl("http://...");
Java Script
WebView¿¡¼ Java Script »ç¿ë°¡´É ÇÏ°Ô Çϱâ.
WebView webView = (WebView) findViewById(R.id.webview);
webView.getSettings().setJavaScriptEnabled(true);
Alert/Confirm µî È°¼ºÈ
WebChromeClient¸¦ ±¸ÇöÇØ ÁØ´Ù.
public class MainActivity extends Activity {
WebView webView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
webView = (WebView) findViewById(R.id.webview);
webView.getSettings().setDomStorageEnabled(true);
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setUserAgentString("IAA");
webView.getSettings().setAllowFileAccess(true);
webView.getSettings().setAllowContentAccess(true);
webView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
webView.setWebViewClient(new WebViewClient());
webView.setWebChromeClient(new WebChromeClient() {
@Override
public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
showAlert(message, result);
return true;
//return super.onJsAlert(view, url, message, result);
}
@Override
public boolean onJsConfirm(WebView view, String url, String message, JsResult result) {
return super.onJsConfirm(view, url, message, result);
}
@Override
public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {
return super.onJsPrompt(view, url, message, defaultValue, result);
}
public void onProgressChanged(WebView view, int progress) {
setProgress(progress * 1000);
}
});
webView.addJavascriptInterface(new WebAppInterface(this), "Android");
webView.loadUrl("http://www.ifanclub.jp/");
//webView.loadUrl("http://sizuha.iptime.org/");
Button btnReload = (Button) findViewById(R.id.btn_reload);
btnReload.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
reload();
}
});
Button btnBack = (Button) findViewById(R.id.btn_back);
btnBack.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
goBack();
}
});
}
void reload() {
webView.reload();
}
void goBack() {
webView.goBack();
}
void showAlert(String message, final JsResult result) {
AlertDialog dlg = new AlertDialog.Builder(this)
.setMessage(message)
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
result.confirm();
}
})
.create();
dlg.setCancelable(false);
dlg.setCanceledOnTouchOutside(false);
dlg.show();
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
goBack();
return true;
}
return super.onKeyUp(keyCode, event);
}
}
Javascript¿¡¼ Android ÄÚµå È£Ãâ
public class WebAppInterface {
Context mContext;
/** Instantiate the interface and set the context */
WebAppInterface(Context c) {
mContext = c;
}
/** Show a toast from the web page */
@JavascriptInterface
public void showToast(String toast) {
Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show();
}
}
webView.addJavascriptInterface(new WebAppInterface(this), "Android");
function showAndroidToast(toast) {
Android.showToast(toast);
}
ListView
ListView °»½Å
Adaptor¾È¿¡¼´Â notifyDataSetChanged()¸¦ È£ÃâÇÏ¸é µÇÁö¸¸, ListView ÀÚü¿¡¼´Â ´ÙÀ½°ú °°ÀÌ ÇÏ¸é µÈ´Ù.
mListView = (ListView) rootView.findViewById(android.R.id.list);
// . . .
mListView.invalidateViews();
¸®½ºÆ® ºä ¸Ç ¾Æ·¡¿¡ Footer Ãß°¡
// set list
mListView = (ListView) rootView.findViewById(android.R.id.list);
mListView.setAdapter(mAdapter);
// Adding Load More
View loadMoreView = inflater.inflate(R.layout.item_load_more, null);
mListView.addFooterView(loadMoreView);
Alert Dialog
AlertDialog.Builder alert = new AlertDialog.Builder(MyActivity.this);
alert.setPositiveButton("È®ÀÎ", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss(); //´Ý±â
}
});
alert.setMessage("Å×½ºÆ® ¸Þ¼¼Áö");
alert.show();
AlertDialog.Builder alert_confirm = new AlertDialog.Builder(MyActivity.this);
alert_confirm.setMessage("ÇÁ·Î±×·¥À» Á¾·á ÇϽðڽÀ´Ï±î?").setCancelable(false).setPositiveButton("È®ÀÎ",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// 'YES'
}
}).setNegativeButton("Ãë¼Ò",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// 'No'
return;
}
});
AlertDialog alert = alert_confirm.create();
alert.show();
ProgressDialog
http://seesaawiki.jp/w/moonlight_aska/d/%A5%D7%A5%ED%A5%B0%A5%EC%A5%B9%A5%D0%A1%BC%A4%F2%A5%C0%A5%A4%A5%A2%A5%ED%A5%B0%A4%CB%C9%BD%BC%A8%A4%B9%A4%EB
package com.moonlight_aska.android.progressdialog01;
import android.app.Activity;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.view.View;
public class ProgressDialog01 extends Activity {
¡¡¡¡private ProgressDialog dlg = null;
¡¡¡¡/** Called when the activity is first created. */
¡¡¡¡@Override
¡¡¡¡public void onCreate(Bundle savedInstanceState) {
¡¡¡¡¡¡¡¡super.onCreate(savedInstanceState);
¡¡¡¡¡¡¡¡setContentView(R.layout.main);
¡¡¡¡¡¡¡¡dlg = new ProgressDialog(this);
¡¡¡¡¡¡¡¡// «¿«¤«È«ë, ÜâÙþªòàâïÒ
¡¡¡¡¡¡¡¡dlg.setTitle("«×«í«°«ì«¹«Ðー");
¡¡¡¡¡¡¡¡dlg.setMessage("ª·ªÐªéª¯ªªÓâªÁª¯ªÀªµª¤.");
¡¡¡¡¡¡¡¡// «¹«¿«¤«ëªòàâïÒ
¡¡¡¡¡¡¡¡dlg.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
¡¡¡¡¡¡¡¡findViewById(R.id.button_id).setOnClickListener(new View.OnClickListener() {
¡¡¡¡¡¡¡¡¡¡¡¡@Override
¡¡¡¡¡¡¡¡¡¡¡¡public void onClick(View v) {
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡// TODO Auto-generated method stub
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡dlg.show();
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡new Thread(new Runnable() {
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡@Override
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡public void run() {
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡try {
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡for(int i=0; i<dlg.getMax(); i++) {
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡// òä捗áãªòÌÚãæ
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡dlg.setProgress(i);
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread.sleep(100);
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡}
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡} catch (InterruptedException e) {
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡// ÖÇèâ処×â
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡}
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡dlg.dismiss();
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡}
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡}).start();
¡¡¡¡¡¡¡¡¡¡¡¡}
¡¡¡¡¡¡¡¡});
¡¡¡¡}
}
ProgressBar
http://www.adakoda.com/android/000079.html
package com.adakoda.android.progressbarsample;
import android.app.Activity;
import android.os.Bundle;
import android.widget.ProgressBar;
import com.adakoda.android.progressbarsample.R.id;
public class ProgressBarSampleActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ProgressBar progressBar = (ProgressBar) findViewById(id.progressbar_horizontal);
// â©øÁ«×«í«°«ì«¹«ÐーªÎõÌÓÞö·ªòàâïÒª·ªÞª¹
progressBar.setMax(100);
// â©øÁ«×«í«°«ì«¹«ÐーªÎö·ªòàâïÒª·ªÞª¹
progressBar.setProgress(30);
// â©øÁ«×«í«°«ì«¹«ÐーªÎ«»«««ó«À«êö·ªòàâïÒª·ªÞª¹
progressBar.setSecondaryProgress(70);
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ProgressBar android:id="@+id/progressbar_horizontal"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:indeterminate="false"
style="?android:attr/progressBarStyleHorizontal" />
<ProgressBar android:id="@+id/progressbar_small"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:indeterminate="false"
style="?android:attr/progressBarStyleSmall" />
<ProgressBar android:id="@+id/progressbar"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
style="?android:attr/progressBarStyle" />
<ProgressBar android:id="@+id/progressbar_large"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
style="?android:attr/progressBarStyleLarge" />
</LinearLayout>
PopupMenu (API 11)
http://developer.android.com/reference/android/widget/PopupMenu.html
Text
Underline È¿°ú
Button°ú TextView¿¡¼ ¹ØÁÙ È¿°ú ³Ö±â.
public static void makeUnderlineText(TextView v) {
v.setPaintFlags(v.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG);
}
public static void makeUnderlineText(Button b) {
b.setPaintFlags(b.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG);
}
±âŸ
½Ç½Ã°£¿¡¼ UIÄÁÆ®·ÑÀÇ Size Á¶Á¤
LayoutParams¸¦ ÀÌ¿ëÇØ¾ß ÇÑ´Ù.
Button button = (Button) findViewById(view.getId());
LinearLayout rLGreen = ((LinearLayout) button.getParent());
rLGreen.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
====================================================================================
IO
Preference
// ContextÀÇ getSharedPreferences()·Î °´Ã¼¸¦ °¡Á®¿Â´Ù.
// »ç¿ëÇÒ ¼ö ÀÖ´Â MODE´Â ´ÙÀ½°ú °°´Ù.
// MODE_PRIVATE = öâªÎ«¢«×«êª«ªé«¢«¯«»«¹Üôʦ
// MODE_WPRLD_READABLE = öâªÎ«¢«×«êª«ªé読ªß込ªßʦÒö
// MODE_WORLD_WRITEABLE = öâªÎ«¢«×«êª«ªéßöª込ªßʦÒö
SharedPreferences pref = getSharedPreferences("«Õ«¡«¤«ëÙ£", MODE_PRIVATE);
// °ª °¡Á®¿À±â
pref.getString("key", "default value");
// °ª ¾²±â
SharedPreferences.Editor editor = pref.edit();
editor.putString("key", "value");
editor.commit();
´Ù¸¥ ¾Û¿¡¼ Shared Preference °¡Á®¿À±â
Context otherContext = createPackage("com.example.pref", mode);
settings = otherContext.getSharedPreferences("Name", mode);
File
ÆÄÀÏÀÌ Á¸ÀçÇÏ´ÂÁö È®ÀÎ
File file = this.getFileStreamPath("test.txt");
boolean isExists = file.exists();
µð·ºÅ丮 ¸¸µé±â
File dir = new File(context.getExternalFilesDirs() + "/Test/Test2");
if(!dir.exists()){
dir.mkdirs();
}
ÆÄÀÏ º¹»ç
private boolean copyFile(File file , String save_file){
boolean result;
if (file != null && file.exists()) {
try {
FileInputStream fis = new FileInputStream(file);
FileOutputStream newfos = new FileOutputStream(save_file);
int readcount=0;
byte[] buffer = new byte[1024];
while ((readcount = fis.read(buffer,0,1024)) != -1) {
newfos.write(buffer,0,readcount);
}
newfos.close();
fis.close();
} catch (Exception e) {
e.printStackTrace();
}
result = true;
} else {
result = false;
}
return result;
}
HTTP
Apache HTTP Client
Android 6¿¡¼ Apache HTTP Client ¶óÀ̺귯¸®°¡ Á¦°ÅµÇ¾ú´Ù. ´ë½Å HttpURLConnection À» ±ÇÀåÇÏ°í ÀÖ´Ù.
±×·¡µµ °è¼Ó »ç¿ëÇÏ°í ½Í´Ù¸é, App/build.gradle ÆÄÀÏÀÇ Ã¹ ºÎºÐÀ» ´ÙÀ½°ú °°ÀÌ ¼öÁ¤ÇÑ´Ù.
apply plugin: 'com.android.application'
android {
useLibrary 'org.apache.http.legacy'
.
.
.
ÆÄÀÏ ³»·Á¹Þ±â
public class FileDownloader extends AsyncTask<String, String, Integer> {
final static int BUFFER_SIZE = 4096;
private String storagePath = "";
public void setStagePath(String path) {
storagePath = path;
}
public static interface IOnDownloadEvent {
void onOneFileDownloadEnd(String filenameWithPath);
void onDownloadTotalEnd(int download_count);
}
public IOnDownloadEvent downloadEventRecv;
public boolean overwrite = false;
@Override
protected Integer doInBackground(String... urls) {
int dn_cnt = 0;
for (String url_str : urls) {
// Escape early if cancel() is called
if (isCancelled()) break;
File outFile = null;
try {
URL url = new URL(url_str);
final String out_filename = URLUtil.guessFileName(url_str, null, null);
final String out_filenameWithPath = Environment.getExternalStorageDirectory().toString() +
"/" + storagePath + "/" + out_filename;
outFile = new File(out_filenameWithPath);
if (!overwrite &&outFile.exists()) continue;
URLConnection connection = url.openConnection();
connection.connect();
outFile.mkdirs();
InputStream input = new BufferedInputStream(url.openStream(), BUFFER_SIZE);
OutputStream output = new FileOutputStream(outFile);
byte data[] = new byte[BUFFER_SIZE];
int read_count;
while ((read_count = input.read(data)) != -1) {
output.write(data, 0, read_count);
dn_cnt++;
}
output.flush();
output.close();
input.close();
if (downloadEventRecv != null) downloadEventRecv.onOneFileDownloadEnd(out_filenameWithPath);
}
catch (MalformedURLException e) {
e.printStackTrace();
continue;
}
catch (IOException e) {
e.printStackTrace();
if (outFile != null) outFile.delete();
continue;
}
}
return dn_cnt;
}
@Override
protected void onPostExecute(Integer dnCnt) {
if (downloadEventRecv != null) downloadEventRecv.onDownloadTotalEnd(dnCnt);
super.onPostExecute(dnCnt);
}
}
´Ù¿î ¹Þ±â Àü¿¡ ÆÄÀÏ Å©±â ¾Ë¾Æ³»±â
URL url = new URL("http://server.com/file.mp3");
URLConnection urlConnection = url.openConnection();
urlConnection.connect();
int file_size = urlConnection.getContentLength();
JSON
{
"sys":
{
"country":"GB",
"sunrise":1381107633,
"sunset":1381149604
},
"weather":[
{
"id":711,
"main":"Smoke",
"description":"smoke",
"icon":"50n"
}
],
"main":
{
"temp":304.15,
"pressure":1009,
}
}
String in;
JSONObject reader = new JSONObject(in);
JSONObject sys = reader.getJSONObject("sys");
country = sys.getString("country");
JSONObject main = reader.getJSONObject("main");
temperature = main.getString("temp");
JSONArray weather = reader.getJSONArray("weather");
SQLite
DB ÃʱâÈ/Open
public class LocalDbHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "test.db";
private static final int DATABASE_VERSION = 1;
public LocalDbHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
// create DB tables.
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
dbHelper = new LocalDbHelper(context);
// open
SQLiteDatabase db = dbHelper.getWritableDatabase();
// close
if (db != null) db.close();
if (dbHelper != null) dbHelper.close();
Data Types
NULL NULLö·
INTEGER ݬ号ÜõïÚ数¡£1, 2, 3, 4, 6, or 8 «Ð«¤«ÈªÇÌ«Ò¡¡£³¯Â¥ µîÀÇ Á¤º¸µµ ¼ýÀÚ·Î º¯È¯Çؼ ó¸®ÇØ¾ß ÇÑ´Ù.
REAL Ý©ÔÑá³数ïÃ数¡£8«Ð«¤«ÈªÇÌ«Ò¡
TEXT «Æ««¹«È¡£UTF-8, UTF-16BE or UTF-16-LEªÎª¤ªºªìª«ªÇÌ«Ò¡
BLOB Binary Large OBject¡£ìýÕô«Çー«¿ªòª½ªÎªÞªÞÌ«Ò¡
Create Table
db.execSQL("CREATE TABLE notice( " +
"id INTEGER " +
"title TEXT, " +
"contents_data TEXT, " +
"pub_date INTEGER, " +
"PRIMARY KEY(date DESC, id ASC)" +
");");
Query
Cursor cursor = db.query("DB_TABLE_NAME", new String[] { cols, ... },
"Selection Query", new String[] { query_params, ... }, "groupBy", "having", "orderBy", "limit");
while (cursor.moveToNext()) {
// TODO ...
}
cursor.close();
Insert/Update
»ðÀÔ Çϸé¼, ÀÌ¹Ì µ¥ÀÌÅÍ°¡ Á¸ÀçÇÏ´Â °æ¿ì´Â µ¤¾î¾²±â(update)¸¦ ¼öÇàÇÑ´Ù.
SQLiteDatabase db = dbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("column1", 0);
values.put("column2", "string");
values.put("column3", 0.0);
try {
db.insertWithOnConflict("TABLE_NAME", null, values, SQLiteDatabase.CONFLICT_REPLACE);
}
catch (IllegalStateException e) {
// DB is already closed.
}
Sound
MediaPlayer
public static void play(int sndResID, float speed) {
MediaPlayer mp = MediaPlayer.create(context, sndResID);
play(mp, speed);
}
public static void play(String uri, float speed) {
MediaPlayer mp = MediaPlayer.create(context, Uri.parse(uri));
play(mp, speed);
}
private static void play(MediaPlayer mp, float speed) {
if (Build.VERSION.SDK_INT >= 23 /* Android 6.0 */) {
PlaybackParams params = mp.getPlaybackParams();
params.setSpeed(speed);
mp.setPlaybackParams(params);
}
mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
mp.release();
}
});
mp.start();
}
Sound Pool
ÃʱâÈ
SoundPool sndPool;
if (Build.VERSION.SDK_INT < 21 /* Android 5.0 */) {
sndPool = new SoundPool(MAX_STREAMS, AudioManager.STREAM_MUSIC, 0);
}
else {
sndPool = new SoundPool.Builder()
.setMaxStreams(10)
.build();
}
Load
sndPool.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener() {
@Override
public void onLoadComplete(SoundPool soundPool, int soundId, int status) {
// TODO
}
});
int soundID = sndPool.load(audioPath, 1 /* priority */);
//--- or ---//
int res_id = 00000; // Resource ID
int soundID = sndPool.load(res_id, 1 /* priority */);
Play
boolean loop = false;
sndPool.play(sound_id, 1 /* Left Volume */, 1 /* Right Volume */, 1 /* priority */, loop ? -1 : 0, 1f /* play rate: 0.5f ~ 2.0f */);
====================================================================================
Date/Time
ÇöÀç ³¯Â¥/½Ã°£ °¡Á®¿À±â
Calendar calendar = Calendar.getInstance();
³¯Â¥/½Ã°£ ¼ÂÆÃ
Calendar calendar = Calendar.getInstance();
calendar.clear(); // Áß¿ä: set Çϱâ Àü¿¡ ¹Ýµå½Ã clear¸¦ ÇØÁÙ °Í!
calendar.set(year, month, day, hour, min, sec);
long datetile = calendar.getTimeInMillis();
====================================================================================
Threading
AsyncTask
http://developer.android.com/reference/android/os/AsyncTask.html
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalSize = 0;
for (int i = 0; i < count; i++) {
totalSize += Downloader.downloadFile(urls[i]);
publishProgress((int) ((i / (float) count) * 100));
// Escape early if cancel() is called
if (isCancelled()) break;
}
return totalSize;
}
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
protected void onPostExecute(Long result) {
showDialog("Downloaded " + result + " bytes");
}
}
new DownloadFilesTask().execute(url1, url2, url3);
AsyncTask's generic types
The three types used by an asynchronous task are the following:
1.Params, the type of the parameters sent to the task upon execution.
2.Progress, the type of the progress units published during the background computation.
3.Result, the type of the result of the background computation.
Not all types are always used by an asynchronous task. To mark a type as unused, simply use the type Void:
private class MyTask extends AsyncTask<Void, Void, Void> { ... }
Events
When an asynchronous task is executed, the task goes through 4 steps:
1.onPreExecute()
2.doInBackground(Params...)
3.onProgressUpdate(Progress...)
4.onPostExecute(Result)
ÁÖÀÇÇÒ Á¡
The AsyncTask class must be loaded on the UI thread. This is done automatically as of JELLY_BEAN.
The task instance must be created on the UI thread.
execute(Params...) must be invoked on the UI thread.
Do not call onPreExecute(), onPostExecute(Result), doInBackground(Params...), onProgressUpdate(Progress...) manually.
The task can be executed only once (an exception will be thrown if a second execution is attempted.)
====================================================================================
¾ÏÈ£È
SHA1
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class Sha1Hex {
public String makeSHA1Hash(String input) throws NoSuchAlgorithmException {
MessageDigest md = MessageDigest.getInstance("SHA1");
md.reset();
byte[] buffer = input.getBytes();
md.update(buffer);
byte[] digest = md.digest();
String hexStr = "";
for (int i = 0; i < digest.length; i++) {
hexStr += Integer.toString( ( digest[i] & 0xff ) + 0x100, 16).substring( 1 );
}
return hexStr;
}
}
====================================================================================
Reource
¸®¼Ò½º¸¦ ÂüÁ¶ÇØ Äڵ忡¼ ÅؽºÆ® Å©±â ¼³Á¤
<dimen name="text_medium">18sp</dimen>
Set the size in code:
textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimension(R.dimen.text_medium));
More Resource Types
http://developer.android.com/guide/topics/resources/more-resources.html
====================================================================================
Google Cloud Messaging (GCM)
API Key ¹ß±Þ¹Þ±â
´ç¿¬È÷ ±¸±Û °³¹ßÀÚ µî·ÏÀÌ ¸ÕÀú µÇ¾î ÀÖ¾î¾ß ÇÑ´Ù.
1. https://code.google.com/apis/console Á¢¼Ó
2. API Access > Create new Server Key ¸Þ´º·Î µé¾î°¨.
3. Çã°¡ÇÒ IP address¸¦ ÀÔ·ÂÇ϶ó°í ³ª¿À´Âµ¥, ¾Æ¹«°Íµµ ¾²Áö ¾ÊÀ¸¸é ¸ðµÎ Çã¿ë.
4. Create ¹öÆ°À» ´©¸£¸é Å° »ý¼º.
¿©±â¼ »ý¼ºµÈ Å°·Î ¼¹ö ¾îÇÃÄÉÀ̼ǿ¡¼ Ǫ½Ã ¸Þ¼¼Áö¸¦ º¸³¾ ¼ö ÀÖ´Ù.
Sender ID (Project ID)
Ŭ¶óÀ̾ðÆ®¿¡¼ GCM¿¡ µî·ÏÀ» ÇÒ ¶§ ÇÊ¿äÇÑ Sender ID·Î¼, Project ID°¡ ÀÖ¾î¾ß ÇÑ´Ù.
API Console»çÀÌÆ®ÀÇ URL¿¡¼ project: ÀÌÈÄ¿¡ ³ª¿À´Â ¼ýÀÚ°¡ Project IDÀÌ´Ù.
ÇÊ¿äÇÑ ¶óÀ̺귯¸®(Android)
1. SDK Manager > Extras/Google Play services ¶óÀ̺귯¸® ¼³Ä¡.
Clinet
App/build.gradle (Android Studio)
dependencies¿¡ compile "com.google.android.gms:play-services:4.0.+" Ç׸ñ Ãß°¡.
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:support-v4:21.0.+'
compile 'com.android.support:appcompat-v7:21.0.+'
compile 'com.android.support:recyclerview-v7:21.0.+'
compile "com.google.android.gms:play-services:4.0.+"
compile files('src/main/java/jp/co/xxxxxxxxx/pdf/jars/commons-io-2.4.jar')
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="ÆÐÅ°Áö_À̸§">
<!-- for GCM -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<permission
android:name="ÆÐÅ°Áö_À̸§.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission
android:name="ÆÐÅ°Áö_À̸§.permission.C2D_MESSAGE" />
<!-- END -->
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="ÆÐÅ°Áö_À̸§.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- for GCM -->
<receiver
android:name=".GCMBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="ÆÐÅ°Áö_À̸§" />
</intent-filter>
</receiver>
<service android:name=".GCMIntentService" />
<!-- END -->
</application>
</manifest>
GcmBroadcastReceiver
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.support.v4.content.WakefulBroadcastReceiver;
public class GcmBroadcastReceiver extends WakefulBroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// intentªòGcmIntentServiceªÇ処×⪹ªë
ComponentName comp = new ComponentName(context.getPackageName(), GcmIntentService.class.getName());
// «µー«Ó«¹ªòÑÃÔÑ¡¢«µー«Ó«¹ÔÑíÂñéªÏWakeLockªòÜÁò¥ª¹ªë
startWakefulService(context, (intent.setComponent(comp)));
setResultCode(Activity.RESULT_OK);
}
}
GcmIntentService
¹Ýµå½Ã GcmIntentService ¶ó´Â À̸§(´ë¼Ò¹®ÀÚ ÁÖÀÇ)À¸·Î class¸¦ ¸¸µé¾î¾ß ÇÑ´Ù.
import android.app.IntentService;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import android.widget.Toast;
import com.google.android.gms.gcm.GoogleCloudMessaging;
import java.util.Calendar;
public class GcmIntentService extends IntentService {
public GcmIntentService() {
super("MedportalGcmService");
}
@Override
protected void onHandleIntent(Intent intent) {
Log.e("GcmItentService", "onHandleIntent!");
Bundle extras = intent.getExtras();
for (String key : extras.keySet()) {
Object value = extras.get(key);
Log.i(Config.getAppTag(), "|" + String.format("%s : %s (%s)",
key, value.toString(),
value.getClass().getName()) + "|");
}
GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
String messageType = gcm.getMessageType(intent);
if(! extras.isEmpty())
{
if(GoogleCloudMessaging.MESSAGE_TYPE_SEND_ERROR.equals(messageType))
{
Log.e("GcmIntentService", "Send error : " + extras.toString());
}
else if(GoogleCloudMessaging.MESSAGE_TYPE_DELETED.equals(messageType))
{
Log.i("GcmIntentService", "Deleted messages on server : " + extras.toString());
}
else if(GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE.equals(messageType))
{
final String message = extras.getString("message");
Log.i("GcmIntentService", "Received : " + extras.toString());
showNoti(message);
}
}
// Release the wake lock provided by the WakefulBroadcastReceiver.
GcmBroadcastReceiver.completeWakefulIntent(intent);
}
void showNoti(String message) {
long id = Calendar.getInstance().getTimeInMillis();
showNoti((int)id, getApplicationContext(), "GCM Sample", message, message);
}
void showNoti(int notiID, Context context, String title, String message, String ticker) {
// ¹ÞÀº ¸Þ¼¼Áö¸¦ Notification¿¡ Ç¥½ÃÇÏ´Â ¿¹Á¦.
// ÀÌ ºÎºÐÀº »óȲ¿¡ ¸Â°Ô....
Intent intent = new Intent(context, LoginActivity.class);
// Intent ªÎíÂà÷
PendingIntent contentIntent = PendingIntent.getActivity(
context, REQUEST_CODE_MAIN_ACTIVITY, intent, PendingIntent.FLAG_UPDATE_CURRENT);
// LargeIcon ªÎ Bitmap ªòßæà÷
Bitmap largeIcon = BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_launcher);
// NotificationBuilderªòíÂà÷
NotificationCompat.Builder builder = new NotificationCompat.Builder(
context.getApplicationContext());
builder.setContentIntent(contentIntent);
// «¹«Æー«¿«¹«ÐーªËøúãƪµªìªë«Æ««¹«È
builder.setTicker(ticker);
// «¢«¤«³«ó
builder.setSmallIcon(R.drawable.ic_launcher);
// NotificationªòËÒª¤ª¿ªÈªªËøúãƪµªìªë«¿«¤«È«ë
builder.setContentTitle(title);
// NotificationªòËÒª¤ª¿ªÈªªËøúãƪµªìªë«µ«Ö«¿«¤«È«ë
builder.setContentText(message);
// NotificationªòËÒª¤ª¿ªÈªªËøúãƪµªìªë«¢«¤«³«ó
builder.setLargeIcon(largeIcon);
// ÷×ò±ª¹ªë«¿«¤«ß«ó«°
builder.setWhen(System.currentTimeMillis());
// ÷×ò±ãÁªÎëå・«Ð«¤«Ö・«é«¤«È
builder.setDefaults(Notification.DEFAULT_SOUND
| Notification.DEFAULT_VIBRATE
| Notification.DEFAULT_LIGHTS);
// «¿«Ã«×ª¹ªëªÈ««ã«ó«»«ë(Ἢ¨ªë)
builder.setAutoCancel(true);
// NotificationManagerªòö¢Ôð
NotificationManager manager = (NotificationManager) context.getSystemService(Service.NOTIFICATION_SERVICE);
// NotificationªòíÂà÷ª·ªÆ÷×ò±
manager.notify(notiID, builder.build());
}
}
MainActivity
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
setFinishOnTouchOutside(false);
context = getApplicationContext();
// Check device for Play Services APK. If check succeeds, proceed with GCM registration.
if (checkPlayServices()) {
gcm = GoogleCloudMessaging.getInstance(this);
regid = getRegistrationId(context);
if (regid.isEmpty()) {
registerInBackground();
}
}
else {
Log.i(Config.getAppTag(), "No valid Google Play Services APK found.");
}
// . . .
}
/////// GCM ///////////////////
private static final int PLAY_SERVICES_RESOLUTION_REQUEST = 9000;
/**
* Substitute you own sender ID here. This is the project number you got
* from the API Console, as described in "Getting Started."
*/
String SENDER_ID = "your Project ID (API Console)";
GoogleCloudMessaging gcm;
Context context;
String regid;
/**
* Check the device to make sure it has the Google Play Services APK. If
* it doesn't, display a dialog that allows users to download the APK from
* the Google Play Store or enable it in the device's system settings.
*/
private boolean checkPlayServices() {
int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if (resultCode != ConnectionResult.SUCCESS) {
if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) {
GooglePlayServicesUtil.getErrorDialog(resultCode, this,
PLAY_SERVICES_RESOLUTION_REQUEST).show();
} else {
Log.i(Config.getAppTag(), "This device is not supported.");
finish();
}
return false;
}
return true;
}
/**
* Stores the registration ID and the app versionCode in the application's
* {@code SharedPreferences}.
*
* @param context application's context.
* @param regId registration ID
*/
private void storeRegistrationId(Context context, String regId) {
// GCM µî·ÏÀÌ ¼º°øÇÒ ¶§ ¹ÞÀº registration ID¸¦ ¾îµò°¡¿¡ º¸°üÇØ µÐ´Ù.
Config.gcm_reg_id = regId;
Config.savePreference();
}
/**
* Gets the current registration ID for application on GCM service, if there is one.
* <p>
* If result is empty, the app needs to register.
*
* @return registration ID, or empty string if there is no existing
* registration ID.
*/
private String getRegistrationId(Context context) {
Config.loadPreference(context);
String registrationId = Config.gcm_reg_id;
if (registrationId.isEmpty()) {
Log.i(Config.getAppTag(), "Registration not found.");
return "";
}
// Check if app was updated; if so, it must clear the registration ID
// since the existing regID is not guaranteed to work with the new
// app version.
int registeredVersion = Config.app_ver;
int currentVersion = getAppVersion(context);
if (registeredVersion != currentVersion) {
Log.i(Config.getAppTag(), "App version changed.");
Config.app_ver = currentVersion;
Config.savePreference();
return "";
}
return registrationId;
}
/**
* Registers the application with GCM servers asynchronously.
* <p>
* Stores the registration ID and the app versionCode in the application's
* shared preferences.
*/
private void registerInBackground() {
new AsyncTask<Void, Void, String>() {
@Override
protected String doInBackground(Void... params) {
String msg = "";
try {
if (gcm == null) {
gcm = GoogleCloudMessaging.getInstance(context);
}
regid = gcm.register(SENDER_ID);
msg = "Device registered, registration ID=" + regid;
// You should send the registration ID to your server over HTTP, so it
// can use GCM/HTTP or CCS to send messages to your app.
sendRegistrationIdToBackend();
// For this demo: we don't need to send it because the device will send
// upstream messages to a server that echo back the message using the
// 'from' address in the message.
// Persist the regID - no need to register again.
storeRegistrationId(context, regid);
} catch (IOException ex) {
msg = "Error :" + ex.getMessage();
// If there is an error, don't just keep trying to register.
// Require the user to click a button again, or perform
// exponential back-off.
}
return msg;
}
@Override
protected void onPostExecute(String msg) {
// TODO ...
if (Config.DEBUG.SHOW_DEBUG_LOG) {
Log.i(Config.getAppTag(), msg);
}
}
}.execute(null, null, null);
}
/**
* @return Application's version code from the {@code PackageManager}.
*/
private static int getAppVersion(Context context) {
try {
PackageInfo packageInfo = context.getPackageManager()
.getPackageInfo(context.getPackageName(), 0);
return packageInfo.versionCode;
} catch (PackageManager.NameNotFoundException e) {
// should never happen
throw new RuntimeException("Could not get package name: " + e);
}
}
/**
* Sends the registration ID to your server over HTTP, so it can use GCM/HTTP or CCS to send
* messages to your app. Not needed for this demo since the device sends upstream messages
* to a server that echoes back the message using the 'from' address in the message.
*/
private void sendRegistrationIdToBackend() {
// ¼¹ö¿¡ registration ID¸¦ Àü¼ÛÇÒ ÇÊ¿ä°¡ ÀÖÀ» ¶§, ÀÌ°÷¿¡¼ ó¸®.
// ±»ÀÌ ¿©±â¼ ó¸®ÇÏÁö ¾Ê´õ¶óµµ, º¸°üÇصРregistration ID¸¦ ·Î±×ÀÎ °úÁ¤ µî¿¡¼ Àü´ÞÇصµ µÈ´Ù.
}
Server
https://android.googleapis.com/gcm/send ÀÌ URL·Î ´ÙÀ½°ú °°ÀÌ Çª½Ã ¸Þ¼¼Áö¸¦ ³¯¸°´Ù.
Content-Type:application/json
Authorization:key=¼¹öAPI_KEY
{
"registration_ids" : ["¸Þ¼¼Áö¸¦ Àü¼ÛÇÒ ClientÀÇ Registration ID", ...],
"data" : {
// key: value Çü½ÄÀ¸·Î ÀÚÀ¯·Ó°Ô ±¸¼ºÇÒ ¼ö ÀÖ´Ù.
...
},
}
JSON µ¥ÀÌÅÍ ºÎºÐÀÇ ÀÚ¼¼ÇÑ »ç¾çÀº ´ÙÀ½ ¸µÅ©¸¦ ÂüÁ¶.
ÂüÁ¶: http://www.techdoctranslator.com/android/guide/google/gcm/gcm
====================================================================================
Alarm ±¸Çö
/* MainActivity class */
public void setAlram(String title, String message, int year, int month, int day, int hour, int min, int sec) {
Intent alarmIntent = new Intent(this, AlarmReceiver.class);
alarmIntent.putExtra("title", title);
alarmIntent.putExtra("message", message);
if (Config.DEBUG_MODE) {
Log.i("PROJECT_D", "alarm: " + title + " | "+ message);
}
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
Calendar startTime = Calendar.getInstance();
startTime.set(Calendar.YEAR, year);
startTime.set(Calendar.MONTH, month-1);
startTime.set(Calendar.DAY_OF_MONTH, day);
startTime.set(Calendar.HOUR_OF_DAY, hour);
startTime.set(Calendar.MINUTE, min);
startTime.set(Calendar.SECOND, sec);
long alarmStartTime = startTime.getTimeInMillis();
alarmManager.set(AlarmManager.RTC_WAKEUP, alarmStartTime , pendingIntent);
}
public class AlarmReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String title = intent.getStringExtra("title");
String message = intent.getStringExtra("message");
UILib.showNoti(context, title, message, message);
}
}
public class UILib {
static final int REQUEST_CODE_MAIN_ACTIVITY = 1000;
public static int noti_id_start = 0;
public static void showNoti(Context context, String title, String message, String ticker) {
Intent intent = new Intent(context, MainActivity.class);
// Intent ªÎíÂà÷
PendingIntent contentIntent = PendingIntent.getActivity(
context, REQUEST_CODE_MAIN_ACTIVITY, intent, PendingIntent.FLAG_UPDATE_CURRENT);
//// LargeIcon ªÎ Bitmap ªòßæà÷
//Bitmap largeIcon = BitmapFactory.decodeResource(context.getResources(), R.drawable.app_icon);
// NotificationBuilderªòíÂà÷
NotificationCompat.Builder builder = new NotificationCompat.Builder(context.getApplicationContext());
builder.setContentIntent(contentIntent);
// «¹«Æー«¿«¹«ÐーªËøúãƪµªìªë«Æ««¹«È
builder.setTicker(ticker);
// NotificationªòËÒª¤ª¿ªÈªªËøúãƪµªìªë«¿«¤«È«ë
builder.setContentTitle(title);
// NotificationªòËÒª¤ª¿ªÈªªËøúãƪµªìªë«µ«Ö«¿«¤«È«ë
builder.setContentText(message);
// «¢«¤«³«ó
builder.setSmallIcon(android.R.drawable.ic_dialog_info);
// NotificationªòËÒª¤ª¿ªÈªªËøúãƪµªìªë«¢«¤«³«ó
//builder.setLargeIcon(largeIcon);
// ÷×ò±ª¹ªë«¿«¤«ß«ó«°
builder.setWhen(System.currentTimeMillis());
// ÷×ò±ãÁªÎëå・«Ð«¤«Ö・«é«¤«È
builder.setDefaults(Notification.DEFAULT_SOUND
| Notification.DEFAULT_VIBRATE
| Notification.DEFAULT_LIGHTS);
// «¿«Ã«×ª¹ªëªÈ««ã«ó«»«ë(Ἢ¨ªë)
builder.setAutoCancel(true);
// NotificationManagerªòö¢Ôð
NotificationManager manager = (NotificationManager) context.getSystemService(Service.NOTIFICATION_SERVICE);
// NotificationªòíÂà÷ª·ªÆ÷×ò±
manager.notify(noti_id_start++, builder.build());
if (noti_id_start >= Integer.MAX_VALUE) {
noti_id_start = 0;
}
}
}
AndroidManifest.xml
<application ...>
<service android:name=".GcmIntentService" />
</application>
====================================================================================
Tips
open URL
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http:// . . ."));
startActivity(browserIntent);
Locale ¼³Á¤ °¡Á®¿À±â
Locale systemLocale = getResources().getConfiguration().locale;
String strDisplayCountry = systemLocale.getDisplayCountry();
String strCountry = systemLocale.getCountry();
String strLanguage = systemLocale.getLanguage();
³×Æ®¿öÅ© »ç¿ë °¡´É ¿©ºÎ
// «Í«Ã«È«ïー«¯ïÈ続ü¬ìã
public static boolean networkCheck(Context context){
ConnectivityManager cm = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
if (cm == null) return false;
NetworkInfo info = cm.getActiveNetworkInfo();
if( info != null ){
return info.isConnected();
}
else {
return false;
}
}
Mac Address °¡Á®¿À±â
// need permission: "android.permission.ACCESS_WIFI_STATE"
public static String getMacAddr(Context context) {
WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
WifiInfo wInfo = wifiManager.getConnectionInfo();
String mac = wInfo.getMacAddress();
return mac;
}
È¸é ²¨Áü(ÀýÀü ¸ðµå) ¹æÁö
// Activity¿¡¼
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
====================================================================================
¹®Á¦ ¹× ÇØ°á
formatted stringÀ» strings.xml ¸®¼Ò½º·Î »¬ ¶§ÀÇ ¹®Á¦
http://androidgamepark.blogspot.jp/2013/05/multiple-substitutions-specified-in-non.html
String.format() µî¿¡¼ »ç¿ëÇÏ´Â Çü½Ä ¹®ÀÚ¿(formatted string)À» ±×´ë·Î xml ¸®¼Ò½º·Î »©³»¸é ´ÙÀ½°ú °°Àº ¿¡·¯°¡ ¹ß»ý.
Multiple substitutions specified in non-positional format; did you mean to add the formatted="false" attribute?
ÀÌÀ¯´Â %¹®ÀÚ°¡ xml¿¡¼ »ç¿ëµÇ´Â Ư¼ö ±âÈ£À̱⠶§¹®. ´ÙÀ½°ú °°ÀÌ Ã³¸®ÇÏÀÚ.
<!-- ÀÌ°ÍÀº ¿¡·¯ -->
<string name="msg_format_date">%4dÒ´%02dêÅ%02dìí</string>
<!-- ÀÌ·¸°Ô ÇÑ´Ù -->
<string name="msg_format_date">%1$4dÒ´%2$02dêÅ%3$02dìí [ãæó·号]</string>
1$, 2$ µîÀÇ Àǹ̴ 1¹ø° ÀÎÀÚ, 2¹ø° ÀÎÀÚ, ... ¸¦ ÀǹÌÇÑ´Ù.
ConnectivityManager.getNetworkInfo() ¹®Á¦
ICS ¹öÀü¿¡¼ ConnectivityManagerÀÇ getNetworkInfo() È£ÃâÀÌ nullÀÌ µÇ´Â °æ¿ì°¡ ÀÖ´Ù.
ConnectivityManager cm =
(ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo ni = cm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
3G ±â´ÉÀÌ ¾ø´Â ±â±âÀÏ ¶§, À§ Äڵ忡¼ ni´Â null °ªÀÌ µÇ¹ö¸°´Ù.
±×·¯´Ï ¹Ýµå½Ã getNetworkInfo()ÀÇ ¹Ýȯ°ªÀÌ nullÀÎÁö ¸ÕÀú È®ÀÎÇÏ°í ÁøÇàÇÒ °Í.
MapView Ãß°¡ÇÒ ¶§
MapActivity¿¡¼ supoer.onCreate()°¡ ¸ÕÀú È£ÃâµÈ ´ÙÀ½¿¡ MapView°¡ Ãß°¡µÇ¾î¾ß ¿À·ù°¡ ¹ß»ýÇÏÁö ¾Ê´Â´Ù.
layout.xml µîÀ¸·Î MapView¸¦ Ãß°¡ÇÒ ¶§µµ setContentView() È£ÃâÀÌ supoer.onCreate() ´ÙÀ½¿¡ µÇµµ·Ï ÁÖÀÇ.
Debug Certificate expired
¾î´À³¯ ÇÁ·ÎÁ§Æ®¸¦ ºôµåÇϴµ¥ Debug Certificate expired ¿À·ù°¡ ¶á´Ù. ÀÌ°Ç 뭥¹Ì?
ÇØ°á: clean project ÈÄ rebuild´Â ÀÌ¹Ì ½ÃµµÇØ º¸¾Ò°ÚÁö? ±×·¡µµ Àú ¿À·ù°¡ ¶á´Ù¸é debug.keystore ÀÎÁõ±â°£ÀÌ Áö³ °ÍÀÌ´Ù. (ÀÎÁõ±â°£ÀÌ 1³âÂ¥¸®¶ó°í ÇÑ´Ù. Âͽ÷´°Ô..) Windows '»ç¿ëÀÚ(Users)' Æú´õ ¹Ø¿¡ .android ¶ó´Â Æú´õ¿¡¼ debug.keystore ÆÄÀÏÀ» Áö¿öº¸°í ´Ù½Ã ºôµåÇÏ¸é µÈ´Ù.
³×Æ®¿öÅ© ½º·¹µå ¹®Á¦
Android 3.0 À̻󿡼 android.os.NetworkOnMainThreadException ¿À·ù¸¦ ¸¸³µ´Ù¸é, ÀÌ°ÍÀº ¸ÞÀÎ ½º·¹µå¿¡¼ ³×Æ®¿öÅ© ÀÛ¾÷À» ¼öÇàÇ߱⠶§¹®ÀÌ´Ù.
http://android-developers.blogspot.kr/2010/12/new-gingerbread-api-strictmode.html
http://www.androidpub.com/1123776 (¹ø¿ª)
¾Û ¿ì¼±¼øÀ§ ³ôÀ̱â
½Ã½ºÅÛ ÀÚ¿ø ºÎÁ·À¸·Î ÇÁ·Î¼¼½º ųÀÌ ÁøÇàµÉ ¶§, Á¶±ÝÀÌ¶óµµ ¿À·¡ »ì°í ½ÍÀ¸¸é Service(ºñ·Ï ¾Æ¹«Àϵµ ¾ÈÇÏ´õ¶óµµ)¸¦ ÀÌ¿ëÇؼ ¾ÛÀÇ ¿ì¼±¼øÀ§(Áß¿äµµ)¸¦ ³ô¿©¾ß ÇÑ´Ù.
³²¿ëÇÏÁö´Â ¸»ÀÚ. ¸®¼Ò½º¸¦ ¸¹ÀÌ »ç¿ëÇÏ´Â °ÔÀÓÀ̳ª ³×ºñ°ÔÀ̼Ç, ¿µ»ó ó¸® µîÀÇ ¾Û¿¡¼ »ç¿ëÇÏ´Â°Ô ÁÁÀ» µí.
¼ºñ½º ÀÛ¼º(¿¹½Ã)
public class NokillService extends Service {
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
setForgroundService();
return Service.START_STICKY;
}
void setForgroundService() {
final Intent it = new Intent(this, MainActivity.class);
PendingIntent pi = PendingIntent.getActivity(this, 0, it, 0);
Notification noti;
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
noti = new Notification.Builder(this)
.setContentTitle("AppTitle")
.setContentText("running...")
.setTicker("running...")
.setSmallIcon(R.drawable.ic_launcher)
.build();
}
else {
noti = new Notification(R.drawable.ic_launcher, "App Title", System.currentTimeMillis());
noti.setLatestEventInfo(this, "App Title", "running...", pi);
}
startForeground(1, noti);
}
}
Áß¿äÇÑ°Ç, ¼ºñ½º ³»¿¡¼ startForeground()¸¦ È£ÃâÇؼ foreground ¼ºñ½º·Î È°¼ºÈµÇ¾î¾ß ÇÑ´Ù´Â °Í.
foreground ¼ºñ½º·Î µî·ÏÇϱâ À§Çؼ´Â NotificationÀÌ Çʼö·Î Á¦°øµÇ¾î¾ß ÇÑ´Ù.
AndroidManifest.xml µî·Ï
<service android:name="com.qbigstudio.service.NokillService"/>
¼ºñ½º È£Ãâ ¹× Á¾·á(¿¹½Ã)
public void startNokillService() {
nokillServ = new Intent(this, NokillService.class);
startService(nokillServ);
}
public void stopNokillService() {
if (nokillServ != null)
stopService(nokillServ);
nokillServ = null;
}
̵̧ : 4756
̵̧
¸ñ·Ï