카테고리 보관물: 안드로이드

안드로이드에는 Crop Intent가 없습니다.

com.android.camera.action.CROP사용하지 마세요.

No, Android Does *Not* Have a Crop Intent

일반적으로 사진을 간단히 편집해서 불러오려고 할 경우에 com.android.camera.action.CROP을 action으로 한 Intent로 startActivity()를 호출해서 처리하는 경우가 많습니다. 저도 그렇게 사용하고 있었고요.
AOSP 카메라앱에서 이 Intent를 처리할 수 있고 많은 기기들에서 이렇게 사용하는 것이 가능한게 사실이지만 동작하지 않는 기기들도 존재합니다. 그리고 그런 기기들에서는 앱이 Crash됩니다.
저 같은 경우에는 일본의 docomo arrows F-04E, F-05D 같은 기기들에서 동작하지 않는다는 리포트가 많았습니다. 저는 PackageManager로 Crop Intent를 처리할 수 있는 앱이 있는지 먼저 체크하고 있었음에도 처리가 되지 않고 있다고해서 조금 놀랐었네요.

그래서 저 글에서도 제안하고 있고 제가 처리한 방법도 오픈소스를 이용하는 방법이었습니다.
몇몇 github 라이브러리들이 존재하는데 AOSP 카메라앱에서 소스를 따온 것 들입니다.

https://github.com/lvillani/android-cropimage – 쓰기 좋게 example도 제공하고 develop 브랜치에서 빌드가 가능합니다.
https://github.com/MMP-forTour/cropimage

FacebookTwitterGoogle+

ADT 22 DDMS에서 Heap tab 안 뜨는 문제

Android SDK Tools 22 DDMS에서 Heap이나 Network 탭이 안뜨는 문제가 있다.

http://code.google.com/p/android/issues/detail?id=55454
http://code.google.com/p/android/issues/detail?id=55517
http://code.google.com/p/android/issues/detail?id=55394

안 그래도 메모리 디버깅 중인데ㅠㅠ

22.1에서 수정될 것이라고 하며 Standalone DDMS.bat를 사용하거나 21.1의 tools/lib/monitor* 디렉토리를 덮어씌우는 방법으로 해결 가능

21.1 SDK는 http://code.google.com/p/android/issues/detail?id=55394에서 플랫폼별로 받을 수 있다.

https://dl.google.com/android/android-sdk_r21.1-windows.zip
https://dl.google.com/android/android-sdk_r21.1-macosx.zip
https://dl.google.com/android/android-sdk_r21.1-linux.tgz

FacebookTwitterGoogle+

Java에서 Javascript의 encodeURIComponent 구현하기

자바에서는 URLEncoder를 사용해서 인코딩을 할 수 있는데 자바스크립트에서 사용하는 encodeURIComponent와 살짝 다르다.

Java의 URLEncoder:

  • literal characters (regex representation): [-a-zA-Z0-9._*]
  • the space character " " is converted into a plus sign "+".

JavaScript의 encodeURIComponent():

  • literal characters (regex representation): [-a-zA-Z0-9._*~'()!]

즉, 자바에서는 빈칸을 ‘+‘로 바꾸고 자바스크립트는 빈칸을 ‘%20‘으로 변환,
그리고 자바스크립트에서는 ~'()!을 그대로 두지만 자바에서는 각각 UTF-8 인코딩시킨다.

결국 빈칸과 ~'()!을 변환시키면 URLEncoder의 결과를 encodeURIComponent의 결과와 동일하게 만들 수 있다.

 

public static String encodeURIComponent(String s)
  {
    String result = null;
 
    try
    {
      result = URLEncoder.encode(s, "UTF-8")
                         .replaceAll("\\+", "%20")
                         .replaceAll("\\%21", "!")
                         .replaceAll("\\%27", "'")
                         .replaceAll("\\%28", "(")
                         .replaceAll("\\%29", ")")
                         .replaceAll("\\%7E", "~");
    }
 
    // This exception should never occur.
    catch (UnsupportedEncodingException e)
    {
      result = s;
    }
 
    return result;
  }

안드로이드에서 개발한 앱과 서버간의 통신이 제대로 안되어 헤맸었는데 빈칸이 다르게 변환되는 것이 문제였다.

Java equivalent to JavaScript’s encodeURIComponent that produces identical output?

FacebookTwitterGoogle+

안드로이드 장치에서 이메일 주소 읽어오기

안드로이드 앱에서 사용자의 이메일 주소를 읽어오는 방법입니다.

회원가입시에 미리 입력 시켜둬서 사용자 편의성을 높이는데 사용할 수 있으며 악용하진 말아야할 것 입니다.

 

1. AccountManager 사용하기 (API 5 이상)

AccountManager를 이용하면  기기에 등록된 모든 계정이름을 불러올 수 있고 계정이름이 이메일인 경우가 많기 때문에 활용할 수 있습니다.

Pattern emailPattern = Patterns.EMAIL_ADDRESS; // API level 8+
Account[] accounts = AccountManager.get(context).getAccounts();
for (Account account : accounts) {
    if (emailPattern.matcher(account.name).matches()) {
        String possibleEmail = account.name;
        ...
    }
}

AccountManager를 사용하려면 GET_ACCOUNTS 권한이 필요하니 AndroidManifest.xml에 권한을 추가해둬야 합니다.

<uses-permission android:name="android.permission.GET_ACCOUNTS" />

 

2. ContactsContract.Profile 이용하기 (API 14 이상)

ICS부터는 사용자의 프로필에 접근하여 이메일을 가져올 수 있습니다.

public class ExampleActivity extends Activity implements LoaderManager.LoaderCallbacks<Cursor> {
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        getLoaderManager().initLoader(0, null, this);
    }
 
    @Override
    public Loader<Cursor> onCreateLoader(int id, Bundle arguments) {
        return new CursorLoader(this,
                // Retrieve data rows for the device user's 'profile' contact.
                Uri.withAppendedPath(
                        ContactsContract.Profile.CONTENT_URI,
                        ContactsContract.Contacts.Data.CONTENT_DIRECTORY),
                ProfileQuery.PROJECTION,
 
                // Select only email addresses.
                ContactsContract.Contacts.Data.MIMETYPE + " = ?",
                new String[]{ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE},
 
                // Show primary email addresses first. Note that there won't be
                // a primary email address if the user hasn't specified one.
                ContactsContract.Contacts.Data.IS_PRIMARY + " DESC");
    }
 
    @Override
    public void onLoadFinished(Loader<Cursor> cursorLoader, Cursor cursor) {
        List<String> emails = new ArrayList<String>();
        cursor.moveToFirst();
        while (!cursor.isAfterLast()) {
            emails.add(cursor.getString(ProfileQuery.ADDRESS));
            // Potentially filter on ProfileQuery.IS_PRIMARY
            cursor.moveToNext();
        }
 
        ...
    }
 
    @Override
    public void onLoaderReset(Loader<Cursor> cursorLoader) {
    }
 
    private interface ProfileQuery {
        String[] PROJECTION = {
                ContactsContract.CommonDataKinds.Email.ADDRESS,
                ContactsContract.CommonDataKinds.Email.IS_PRIMARY,
        };
 
        int ADDRESS = 0;
        int IS_PRIMARY = 1;
    }
}

READ_PROFILEREAD_CONTACTS의 두 가지 권한이 필요합니다.

<uses-permission android:name="android.permission.READ_PROFILE" />
<uses-permission android:name="android.permission.READ_CONTACTS" />

참조 : How to get the Android device’s primary e-mail address

FacebookTwitterGoogle+