kitkat(4.4)ìì ë§ë¥ë¨ë¦° ì´ì ë° í´ê²°
ì ë°ì´í¸ ì¤âââìë ë´ì© ì¸ì ë°ê²¬íì ì´ìê° ìë¤ë©´ ëê¸ ë¨ê²¨ì£¼ì¸ì.Â
1. SMS ì´ì
ë³´íµ ìë¹ì¤ìì SMS를 ë³´ë´ë 기ë¥ì ì¬ì©í ê²½ì°ìë Intent.ACTION_SEND를 íµí´ì ë³´ë´ë ê²ì´ ì¼ë°ì ì´ë¤. ëí ì½ëììì 미리 ì íë²í¸ë¥¼ ëª ìíë ê²ì´ ìëë¼ ì¬ì©ìê° ì§ì SMSì ë³´ë´ë íë©´ìì ìëë°©ì ì íë²í¸ë¥¼ ì ë ¥íëê² ë³´íµì´ë¤.
ê·¸ëì ê°ë°ìë Uri.parse(âsmsto:ì íë²í¸")를 ì¬ì©í기보ë¤ë Uri.parse(âsms:â)를 íµíì¬ ì¬ì©ìê° ì§ì ë³´ë¼ì¬ëì ì ííëë¡íë¤. ê·¸ë¬ë 4.4ììë ì´ë°ë°©ìì¼ë¡ 문ì를 ë³´ë´ê²ëë©´(ì§ê¸ ë´ê° ì¬ì©íë ëí´í¸ SMSì±ì íììì´ë¤.) SMSì±ìì ê³ì ì íë²í¸ë¥¼ ê²ìíì¬ ë¬´íë¡ë© ìí©ì ë¹ ì§ê² ëë¤.
ì´ì ì´ë¬í ìí©ì í´ê²°í기 ìí´ ìëì ê°ì´ ë²ì ë³ ë¶ê¸°ì²ë¦¬ë¥¼ íë©´ ì ìì ì¼ë¡ ì¬ì©í ì ìê²ëë¤.
// 19(4.4)ì´ìë¶í°ë ìë¡ì´ ì½ë ì ì©
if (Build.VERSION.SDK_INT > 18) {
String defaultSmsPackageName = Telephony.Sms.getDefaultSmsPackage(getApplicationContext());
Intent sendIntent = new Intent(Intent.ACTION_SEND);
sendIntent.setType(âtext/plainâ);
sendIntent.putExtra(Intent.EXTRA_TEXT, âë³´ë¼ ë©ìì§â);
if (defaultSmsPackageName != null) {
sendIntent.setPackage(defaultSmsPackageName);
}
startActivity(sendIntent);
} else {
// 18ì´íë 기존ì½ë
Intent intent = new Intent(Intent.ACTION_SENDTO, Uri.parse(âsms:â));
intent.putExtra(âsms_bodyâ, âë³´ë¼ ë©ìì§â);
startActivity(intent);
}ì°¸ê³ ë¡ íììì´ ì ë°ì´í¸ ëë©´ì 4.3ì´íììë intentChooser를 íµí´ íììì ëí 문ìì±ì¼ë¡ ì¬ì©í ì ìê² ëììµëë¤.
ì ì½ë를 ì ì©íë©´ 4.4ì ê²½ì° ë¨¼ì ë³´ë¼ ì¬ì©ì를 ì ííê³ ê·¸ ì´íì ì¤ì í ë©ìì§ê° ì ìëì´ìë ë©ìì§ íë©´ì¼ë¡ ì§ì íë©° ë°ë¡ 문ì를 ë³´ë¼ ì ìê²ëë¤.
ì´ íìì í´ë¹ì±ì íì¼ë²ì ì´ 19ë³´ë¤ ë®ìë ë°ìíë íìì´ë¯ë¡ ê¼ ì²´í¬íì¬ì¼íë¤.
2. ì´ë¯¸ì§ ê°ì ¸ì¤ê¸° ì´ì
ë³´íµ ì´ë¯¸ì§ë¥¼ ê°ì ¸ì¤ê¸° ìí´ì Intent.ACTION_GET_CONTENT를 ì´ì©í´ intent chooserìì ì´ë¯¸ì§ 리ì¤í¸ë¥¼ ë³¼ ì ìë ì± í목 ì¤ ê°¤ë¬ë¦¬ë¥¼ íµí´ ì´ë¯¸ì§ë¥¼ ê°ì§ê³ ì¨ë¤.
ê·¸ë¬ë 4.4ìì ì´ë¥¼ ê·¸ëë¡ ì¬ì©í ê²½ì° 4.4ìì ì¶ê°ë âStorage access frameworkâìì ì ê³µíë UIê° ëíëê³ ì¬ê¸°ìì ì¬ì©í ì´ë¯¸ì§ë¥¼ í´ë¦í´ë í´ë¹ ì´ë¯¸ì§ë¥¼ ê°ì§ê³ ì¬ ì ìê²ëë¤.
기존ì ì¬ì©íë ACTION_GET_CONTENTê° Storage access frameworkì íµí©ëì기 ë문ì´ë¤. ê·¸ë ë¤ê³ í´ì ACTION_GET_CONTENTê° ìì í 4.4ì Storage access frameworkì ì´ì©íë¤ê³ 보기ë ì´ë µë¤. 4.4ì ìë¡ê² ìê°ë intentì¸ ACTION_OPEN_DOCUMENTìì ì°¨ì´ë ë¶ëª í ìë¤. ìì¸í ì¬íì âì¤í ë¦¬ì§ ì¡ì¸ì¤ íë ììì íµí´ íì¼ ë§ì¤í°ê° ëì!â를 참조íëë¡ íì.
ë¬¼ë¡ ì½ëìì ì íµí´ ìë¡ì´ UI를 ì´ì© ì´ë¯¸ì§ë¥¼ ê°ì§ê³ ì¤ê²íëë¡ íëê²ì´ ë§ì§ë§ ë¶ëì´íê² ìê°ì´ ìê±°ë ì´ì ê³¼ ê°ì ì¬ì©ì ê²½íì ì ê³µíê³ ì¶ë¤ë©´ ìëì ê°ì´ ACTION_GET_CONTENTìì ACTION_PICKì¼ë¡ ì½ë를 ìì íë¤.
intent.setAction(Intent.ACTION_GET_CONTENT);
ìì
intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
ì¼ë¡ ìì íë¤.
ì´ íìì í´ë¹ì±ì íì¼ë²ì ì´ 19ë³´ë¤ ë®ìë ë°ìíë íìì´ë¯ë¡ ê¼ ì²´í¬íì¬ì¼íë¤.
ì 그림ì²ë¼ í¬ë¡ í ì´ë¯¸ì§ë·°ì íì±í ëì§ ìë ì´ìê° ìì´ ë¶ìí´ ë³´ìëë ìëì ê°ì 문ì ê° ë³µí©ì ì¼ë¡ ì ì©ëì´ ììë¤.
3. íì¼í¨ì¤ ì´ì
ìëì ê°ì ë©ìë를 íµí´ íì¼ í¨ì¤ë¥¼ 참조íë ê²½ì°.
public static Uri getTempUri(){
return Uri.fromFile(new File(Environment.getExternalStorageDirectory() + â/tmp.jpgâ));
}
ê²°ê³¼ê°ì ì ìì ì¸ ê²½ë¡ì¸ file://storage/emulated/0/tmp.jpg ê° ìëë¼
file:///storage/emulated/0/tmp.jpg ì¼ë¡ ì ë¬ ë¨.
intent.putExtra(MediaStore.EXTRA_OUTPUT, getTempUri());
ì´ì ììê°ì´ ì´ë¯¸ì§ë¥¼ ì ì¥í기 ìí´ íì¼í¨ì¤ë¡ì í´ë¹ ë©ìë를 ì¬ì©í ê²½ì° 4.3ì´í ë²ì ì ê²½ì° ìê´ìì´ ëìíì§ë§ 4.4ì ê²½ì°ìë íì¼ì ì¥ì ì¤í¨íë¤.
4. ì´ë¯¸ì§ í¬ë¡ ì´ì
ì´ë¯¸ì§ë¥¼ í¬ë¡í ê²½ì° í¬ë¡í íì¼ì í¹ì ê²½ë¡ì ì ì¥í기 ìí´ì ìëì ê°ì´ 구íí ê²½ì°.
Intent intent = new Intent(âcom.android.camera.action.CROPâ);
intent.setDataAndType(CommonUtil.getTempUri(), âimage/*â);
intent.putExtra(âaspectXâ, "ëì´");
intent.putExtra(âaspectYâ, "ëì´");
intent.putExtra(MediaStore.EXTRA_OUTPUT, âì ì¥í íì¼ì ê²½ë¡â);
intent.putExtra(âoutputFormatâ, Bitmap.CompressFormat.JPEG.toString());
startActivityForResult(intent, REQ_PICK_FROM_CAMERA);
ì´ë¯¸ì§ê° ì ëë¡ ì ì¥ëì§ ìë ê²½ì°ê° ë°ìíë¤.
ì´ì í¬ë¡ë ì´ë¯¸ì§ë¥¼ ë²ë¤ì íµí´ ë¹í¸ë§µ íì¼ë¡ ì ë¬ ë°ë ë°©ìì¼ë¡ ë³ê²½íì¬ ì¬ì©íëë¡íë¤.
Intent intent = new Intent(âcom.android.camera.action.CROPâ);
intent.setDataAndType(CommonUtil.getTempUri(), âimage/*â);
intent.putExtra(âaspectXâ, "ëì´");
intent.putExtra(âaspectYâ, "ëì´");
// ë²ë¤ì íµí´ íì¼ì ì ë¬íë ë°©ìì¼ë¡ ë³ê²½
intent.putExtra(âreturn-dataâ, true);
startActivityForResult(intent, REQ_PICK_FROM_CAMERA);
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case REQ_PICK_FROM_CAMERA:
if (resultCode == RESULT_OK) {
Bundle extras = data.getExtras();
Bitmap cropImg = extras.getParcelable(âdataâ);
â¦
5. ì¹ë·° ì´ì
- ìºìì´ì â ìì¸í ì¬íì ì¶í ì 리
- mWebView.getSettings().setPluginsEnabled() ì¬ì©ë¶ê°, WebView.getSettings().setPluginState(WebSettings.PluginState.ON);ë¡ ëì²´íì¬ ì¬ì©í ì ìì¼ë ìì¼ë¡ Pluginsì ì체를 ì§ìíì§ ìì ìì ì.
6. ìì¤í íì ìë¬
contentResolver.insert(Images.Media.EXTERNAL_CONTENT_URI, values) 를 ì¬ì©í ë ì´ë¯¸ì§ ì ì¥ ìê°ì values.put(Images.Media.DATE_TAKEN, new Date().getTime()); ì ì¬ì©íë©´ kitkat ì´ì ë²ì ìì ì ëë¡ ë ìì¤í íìì´ ë¤ì´ìì¼ë kitkat ìì 0ì¼ë¡ ì ì¥ëë íìì´ ë°ìíë¤.
7. ì¸ì¥ ë©ëª¨ë¦¬ ì´ì
ë³´íµ second Sdcardë íì°©ì sdcardë¡ ì¸ì¥ë©ëª¨ë¦¬ë ì©ì´ë¡ ì¬ì©íëë° ê¸°ì¡´ìë ì´ê³³ì ë§ì ì±ë¤ì´ ë³ë° ì ì½ ìì´ ì¬ì©íì¼ë í·ìº£ë¶í°ë ì´ ê²ì íì©íì§ ìì¼ë©° ìì ì package-specificí ê³µê°ìë§ í¼ë¯¸ì ìì´ ìì ë¡ê² ì¬ì©ì´ ê°ë¥íë¤ê³ í©ëë¤.(ì¸ì¥/android/data/packagename/) ì´ ê³µê°ì íì¼ì ì°ì¤ë í´ë¹ í¨ì¤ì ì ê·¼í기 ìí´ 4.4ë¶í° ìë¡ ì ê³µíë getExternalFilesDirs() ë©ìë를 íµí´ì ì ê·¼íë©´ ë©ëë¤. í´ë¹ ë©ìë를 íµí´ ì ë¬ë°ë File[] ííì ê°ì¤ 0ë²ì§¸ê° 첫ë²ì§¸ ë´ì¥ë©ëª¨ë¦¬, 1ë²ì§¸ê° ëë²ì§¸ ì¸ì¥ ë©ëª¨ë¦¬ í¨ì¤ë¥¼ ì»ì ì ììµëë¤.
getExternalFilesDirs() ë 4.4 ë¶í° ì§ìíë¯ë¡ íìë²ì ìì í´ë¹ ë©ìë를 ì¬ì©íì기 ìí´ìë ContextCompat.getExternalFilesDirs()를 ì¬ì©íì기 ë°ëëë¤.
ì¬ì¤ ì´ íìì íë콤ëë¶í° ëíë íìì¼ë¡ ì ì¡°ì¬ìì í´ë¹ ë¶ë¶ì ì´ìê° ìëë¡ ìì íìì¼ë©° êµ¬ê¸ ëë°ì´ì¤ì ê²½ì° second Sdcard를 ì§ìíë ê²ì´ ìì기ì í´ë¹ ë¶ë¶ì ì¸ì§íì§ ëª»íê³ ììë ê²ì ëë¤.
ê·¸ë¼ ì 구ê¸ì second Sdcardì ëí ì ì± ì ë³ê²½íììê¹ì? ì¶ì¸¡íê±´ë° êµ¬ê¸ í¬ë¡¬ë¶ì²ë¼ ìµëí êµ¬ê¸ í´ë¼ì°ë를 ì´ì©íëë¡ ì ëí기 ìí´ ì´ë¬í ì ì± ì ì´ê±´ ìëê°í©ëë¤.
íì¸ê²°ê³¼ 구ê¸í ê°¤ëìS4ììë ëì¼íìì´ ë°ìëê³ ììµëë¤.
ê·¸ë ë¤ë©´ ê°ì기 G2ê° 4.4ë¡ ì ë°ì´í¸ ëë©´ì í´ë¹ ì´ìê° ë¶ì´ì¡ìê¹ì? ì ì¡°ì¬ìì ì´ì ì²ë¼ í´ë¹ë¶ë¶ì ë³ê²½íë©´ ë í ë°ì. 그건 ìë ê´ë ¨ ì¤ë ëìì ì¤ëª ëì´ ìë¯ì´ 4.4 í·ìº£ë¶í° 구ê¸ì´ CTS ê²ì¦ ì ì°¨ì ì´ ê²ì¬ í목ì ì¶ê°íê²ì¼ë¡ ì¶ì¸¡ë©ëë¤. (êµ¬ê¸ CTS ìì Fail ì´ ëë©´ ì ì¡°ì¬ë í´ë¹ ëë°ì´ì¤ë¥¼ ì¶ì를 í ì ììµëë¤) ë°ë¼ì ì´ì© ì ìì´ Read ë§ ê°ë¥íëë¡ ê·¸ë¥ ëëë ê²ì´ê² ì£ .
ì¡°ê¸ ë ì¤ëª í´ ë³´ìë©´ ìëë¡ì´ë ìì¤í ë´ë¶ë¥¼ ê²ìí´ ë³´ë©´ system/etc/permissions í´ëì ìë ì´ë¯¸ì§ì ê°ì ë´ì©ì platform.xmlë íì¼ì ì°¾ìì ììµëë¤.
ì´ ì´ë¯¸ì§ í목 ì¤ name= âandroid.permission.WRITE_EXTERNAL_STORAGEâ ì ë´ì©ì´ ë°ë¡ ì´ ë¬¸ì ì ìì¸ì¸ ë¶ë¶ì ëë¤. ì¼í¸ì´ ìì , ì¤ë¥¸í¸ì´ ì ì¡°ì¬ë¤ì´ ì´ì ê¹ì§ ìì í ë°©ë²ì ëë¤. ë§ì½ 루í ì íì ë¶ì´ ìë¤ë©´ í´ë¹ íì¼ì ì ì´ë¯¸ì§ì ê°ì´ ìì íì¤ ê²½ì° ì´ì ì²ë¼ 문ì ìì´ second Sdcard를 ì¬ì©íì¤ ì ìì¼ì¤ ê²ëë¤.
ES File Explorerì ê²½ì° second Sdcard ê´ë ¨ ìì ì´ ëìíë¤ë ê²ìë³´ë©´ ê°ë°ì ì¼ë¡ ì´ì ì²ë¼ ì¬ì©í ì ìë¤ë ë°©ë²ì´ ìë ê² ê°ê¸°ë í©ëë¤ë§ ì¢ ë íì¸í´ ë´ì¼ í ê² ê°ìµëë¤.
ë°ë¼ì í·ìº£ ë²ì ì´ìë¶í° Appìì ì¸ì¥ë©ëª¨ë¦¬ ê³µê° ì¬ì© ë°©ë²ê³¼ ì¬ì©ì ìë´íë ìë¹ì¤ ìëë¦¬ì¤ ë³ê²½ì´ íì í ë¯ í©ëë¤.
ê´ë ¨ ì¤ë ë :
ìì§ì g2 í·ìº£ ì¸ì¥ë©ëª¨ë¦¬ ì¬ì© 문ì
g2 ì´ì¸ì 4.4 ì¬ë¼ê° 기기ë¤ì ì¸ì¥ë©ëª¨ë¦¬ ì´ì ìëì
ì ë´ì©ì ì½ì´ë³´ì ì ìê² ì§ë§ ê°ë°ìë¶ë¤ê»ìë G2 í·ìº£ ì ë°ì´í¸ê° 본격ì ì¼ë¡ ì§íë기ì ì ì¸ì¥ë©ëª¨ë¦¬ ì´ìë íì¤í í ì¤í¸íì ì¼ í ê² ê°ìµëë¤. íê°ì§ ë ëª ì¬íì ì¼ í ê²ì ìë ì¬ì´í¸ì ëììë¯ì´
The WRITE_EXTERNAL_STORAGE permission must only grant write access to the primary external storage on a device. Apps must not be allowed to write to secondary external storage devices, except in their package-specific directories as allowed by synthesized permissions. Restricting writes in this way ensures the system can clean up files when applications are uninstalled.
기존ì ì´ì¼ê¸° íë ì¸ì¥ë©ëª¨ë¦¬ ê¶í ì´ììë ë¤ë¥¸ ì´ìë¼ë ì ì ëë¤. ì¦, WRITE_EXTERNAL_STORAGEê¶íì ì¶ê°í´ì í´ê²°ë ê²ì´ ìëë¼ë ê²ì´ì£ .
* ì°¸ê³ ë¡ ì ë ìì§ ì¤ ë¨ë§ìì í ì¤í¸ë 못í´ë³´ìì¼ë©° ì°ë ¤ê° ììë Immersive Modeë G2ìì ì ìëìí¨ì íì¸íìµëë¤. ëí ì´ë² ì´ìë ë¶ëì´ ìì´ ë¤ë¥¸ ë¶ë¤ì´ ê³µì í기 ì½ê² ìë¡ì´ í¬ì¤í¸ë¥¼ ë§ë¤ììµëë¤. https://medium.com/marojuns-android/59e57b9a14e7