Фестиваль 404 corporate blog
Development for Android
Comments 36
+3
Samsung GT-P7510
This item is not compatible with your device.

Asus Transformer Prime TF201
This item is not compatible with your device.

Samsung YP-G70
This item is not compatible with your device.
-1
да, это так. скорее всего, дело в разрешении <uses-permission android:name="android.permission.CALL_PHONE"/> в программе есть возможность звонить по номеру телефона, указанному в объявлении. предвосхищая ваш следующий вопрос, скажу, что когда мы её разрабатывали, мы о планшетах даже и не задумывались. в следующих версия ваше замечание обязательно учтём
+4
<uses-feature android:name=«android.hardware.telephony» android:required=«false»/> решит вопрос.
0
>чуть более 8 KLOC
Если уж очень хочется использовать мало кому известные единицы измерения, то потрудитесь хотя бы использовать единицы измерения, несущие хоть какую-то полезную нагрузку.
+5
1 KLOC = 1,000 строк кода

KLOC (тысячи строк кода) является мерой того, насколько большая компьютерная программа или как долго и сколько людей потребуется, чтобы написать эту программу. Как правило измеряется исходный код.
+2
боюсь вас расстроить, но эта единица измерения известна всем программистам уровня чуть выше джуниора. LOC — lines of code, то есть строк кода.
+11
Я программирую не первый год. Услышал об аббревиатуре «KLOC» впервые.
Впрочем это не отменяет второй и основной части моего «наезда»:)
0
пожалуйста
зная количество строк кода и особенности платформы, можно оценить трудоёмкость проекта в мифических человекочасах. а зная человекочасы, можно оценить бюджет. разумеется, с некоторой погрешностью, но порядок будет правильный, я гарантирую это
это достаточно полезная нагрузка?
+1
Тю, а почему прямым тектом не написать, что N человек трудились X времени?
А то вы предлагаете оценить пройденное расстояние по износу подошвы:)
0
во-первых, не уверен, что договор, подписанный мною с Парксис, позволяет мне это делать.
а во-вторых, количество строк я узнаю с помощью Metrics в пару кликов, а для того, чтобы узнать количество человек и времени, мне придётся поднимать кучу записей в Джире, делать какие-то выборки и тп. не стоит оно того
+2
Впервые услышав о такой аббревиатуре имеет смысл изучить ее историю и весь тот обширный спор который касается ее значимости как метрики. С 80х маститые дядьки вроде Брукса обсуждали этот вопрос годами. И в крупных компаниях пишущих более менее однородный код, она используется как коммерчески значимая. Я думаю большинство программистов которые знали что такое KLOC получили из числа 8 KLOC достаточно информации, начиная с того что проект небольшой (в среднем проекте такого масштаба новичок разберется довольно быстро), автор хочет показать что он достаточно легковесный и/или расширяемый. Из самого того факта что автор упоминает метрику, можно заключить что как он сам воспринимает проект.
0
Я думаю никто не против этой метрики. Просто достаточно указать в скобках, например, «количество строк», и все будет понятно. За всеми этими аббревиатурами, к тому же редкими, не угонишься.
+1
Меня вы тоже расстроили — пишу уже не первый и даже не третий год, но про эту аббревиатуру слышу впервые.
+1
Я программирую лет 15 уже… Конечно, я мерил код в количестве строк, ради фана, но никогда даже не думал мерить их в клоках.
0
> авторизация через Твиттер, так как на тот момент там не было собственного sdk
А сейчас есть? Я только неофициальные нашёл.
+2
1. Как раз с твиттером очень легко интегрироваться через oauth, просто подписываете callback в манифесте:
data android:scheme=«x-oauthflow-twitter» android:host=«callback» и ловите ответ в свем активити. Аналогично интегрируется фэйсбук. Плюс в том, что юзеру не нужно будет вводить в вашем приложении логин пароль от фэйсбука, твиттера, так как авторизовывать будет либо сайт либо соответствующее приложения а не вы.
2. Насколько я вижу воркэраунд с временным файлом — он кривой. Потестируйте например на самсунг галэкси таб 10.9. Значительный пул девайсов от самсунг не сохраняет фото в файл. Вот как обрабытывал интент от самсунгов я:
Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode==0) return;//TODO test samsung Log.d(TAG, "onactres "+resultCode+requestCode+mCurrentPhotoPath); if (requestCode==CHOOSE_PHOTO) { if(data != null){ Uri selectedImage = data.getData(); String[] filePathColumn = {MediaStore.Images.Media.DATA}; Cursor cursor = activity.getContentResolver().query(selectedImage, filePathColumn, null, null, null); cursor.moveToFirst(); int columnIndex = cursor.getColumnIndex(filePathColumn[0]); mCurrentPhotoPath = cursor.getString(columnIndex); cursor.close(); //жмакаем (если есть что) if (!Utils.compressBmp(mCurrentPhotoPath)) mCurrentPhotoPath = ""; } } if(requestCode==TAKE_PHOTO && !mCurrentPhotoPath.equals("")){ if (data!=null) { Log.d(TAG, data.toString()); } //TODO можно и отскалить конечно хотя с другой стороны фотографы будут злы а с другой стороны аут оф мемори не словить бы if (!Utils.compressBmp(mCurrentPhotoPath)) { //похуй на фотографов, на другой чаше весов канал, бабло и аутофмемори. фотографы на айфоне пусть залипают //Samsung devices have a bug with no picture result in intent //Nice блеать! Пидары, превед! final ContentResolver cr = activity.getContentResolver(); final String[] p1 = new String[] { MediaStore.Images.ImageColumns._ID, MediaStore.Images.ImageColumns.DATE_TAKEN }; Cursor c1 = cr.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, p1, null, null, p1[1] + " DESC"); if ( c1.moveToFirst() ) { String uristringpic = "content://media/external/images/media/" +c1.getInt(0); Uri newuri = Uri.parse(uristringpic); //нехуевый обходной суворовский маневр mCurrentPhotoPath =getRealPathFromURI(newuri); //жмакаем if (!Utils.compressBmp(mCurrentPhotoPath)) mCurrentPhotoPath = ""; } c1.close(); } } if(!mCurrentPhotoPath.equals("")){ String code = "var messages = API.photos.getProfileUploadServer({});" + "return {server: messages};"; Bundle params = new Bundle(); params.putString("code", code); restRequest(params,5,5,""); } mCurrentPhotoPath = ""; } private String getRealPathFromURI(Uri contentUri) { String[] proj = { MediaStore.Images.Media.DATA }; CursorLoader loader = new CursorLoader(activity, contentUri, proj, null, null, null); Cursor cursor = loader.loadInBackground(); int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); cursor.moveToFirst(); return cursor.getString(column_index); }
+5
Не пойму что с тегом code тут
    @Override
	public void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		if (resultCode==0) return;//TODO test samsung
		Log.d(TAG, "onactres "+resultCode+requestCode+mCurrentPhotoPath);
		if (requestCode==CHOOSE_PHOTO) {
			if(data != null){  
	            Uri selectedImage = data.getData();
	            String[] filePathColumn = {MediaStore.Images.Media.DATA};

	            Cursor cursor = activity.getContentResolver().query(selectedImage, filePathColumn, null, null, null);
	            cursor.moveToFirst();

	            int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
	            mCurrentPhotoPath = cursor.getString(columnIndex);
	            cursor.close();
	            //жмакаем (если есть что)
	            if (!Utils.compressBmp(mCurrentPhotoPath))
	            	mCurrentPhotoPath = "";
	        }
		}
		if(requestCode==TAKE_PHOTO && !mCurrentPhotoPath.equals("")){
			if (data!=null) {
				Log.d(TAG, data.toString());
			}
			//TODO можно и отскалить конечно хотя с другой стороны фотографы будут злы а с другой стороны аут оф мемори не словить бы
			if (!Utils.compressBmp(mCurrentPhotoPath)) {
				//похуй на фотографов, на другой чаше весов канал, бабло и аутофмемори. фотографы на айфоне пусть залипают

				//Samsung devices have a bug with no picture result in intent
				//Nice блеать! Пидары, превед!
				final ContentResolver cr = activity.getContentResolver();    
	            final String[] p1 = new String[] {
	                    MediaStore.Images.ImageColumns._ID,
	                    MediaStore.Images.ImageColumns.DATE_TAKEN
	            };                   
	            Cursor c1 = cr.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, p1, null, null, p1[1] + " DESC");     
	            if ( c1.moveToFirst() ) {
	               String uristringpic = "content://media/external/images/media/" +c1.getInt(0);
	               Uri newuri = Uri.parse(uristringpic);
	               //нехуевый обходной суворовский маневр
	               mCurrentPhotoPath =getRealPathFromURI(newuri);
	               //жмакаем
	               if (!Utils.compressBmp(mCurrentPhotoPath))
		            	mCurrentPhotoPath = "";
	            }
	            c1.close();
			}
		}
		if(!mCurrentPhotoPath.equals("")){
			String code = "var messages = API.photos.getProfileUploadServer({});" +
	        		"return {server: messages};";
			Bundle params = new Bundle();
		    params.putString("code", code);
			restRequest(params,5,5,"");
		}
		mCurrentPhotoPath = "";
    }

    private String getRealPathFromURI(Uri contentUri) {
        String[] proj = { MediaStore.Images.Media.DATA };
        CursorLoader loader = new CursorLoader(activity, contentUri, proj, null, null, null);
        Cursor cursor = loader.loadInBackground();
        int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        cursor.moveToFirst();
        return cursor.getString(column_index);
    }
+2
Вот вы пишете
Также Selloby дал нам возможность почувствовать, пускай и в миниатюре, как устроен Твиттер

а где подробности про внутренности вашего проекта то?
0
я могу только про мобильный клиент под андроид рассказать. собственно всё, что мне показалось достойным внимания, я написал. если вас ещё что-то интересует — спрашивайте.
про серверную часть ничего говорить не возьмусь, но если сильно попросить, то кто-нибудь из наших бек-енд разработчиков раскажет :)
+1
Программа вроде для андроида, а интерфейс какой-то айфоно-подобный. Вот зачем так делать?

А идея очень нравится!
0
спасибо)
да, есть такая проблема, я о ней уже писал в предыдущем посте. у наших дизайнеров тогда ещё не было опыта рисования макетов под андроид, поэтому тупо копировали айфон с минимальными модификациями. позже мы осознали ошибку и примерно нашли пути решения, но, ввиду предстоящих изменений, переделывать дизайн Селлобая смысла не увидели.
да и гайдлайны в начале 2011 ещё не были опубликованы
-2
а по-моему — интерфейс прекрасен, тенюшечки, скругления, отступы — все по сеточке — смотрю на скрины и наслаждаюсь.
Я отлично представляю себе какая это колосальная работа — нарисовать классные виджеты под андроид. Респект дизайнерам и тому человеку, который все это кропотливо найнпатчил
-2
эти люди — Артём in_balance Московских и Алексей Синиченко (его, насколько я знаю, нет на хабре)
+1
Он красив, но непривычен андроид юзерам. Меню снизу сильно сбивает с толку. Отсутствие action bar ведет к большим проблемам у телефонов без кнопки menu. Тенюшечки спорны, в оригинальном интерфейсе holo их нет.
+1
Меню снизу прекрасно знакомо как пользователям android 2.x, так и пользователям 4.x (им оно известно как split action bar).

Тени-градиенты-иконки да, не родные, но по расположению пользователя с толку не собъет. По крайней мере не больше, чем переход 2.х-4.х (Гугль с интерфейсами вообще непоследователен, гайдлайны меняются с каждой версий андроида, иногда даже с минорными).

Мне holo очень нравится, это я так, справедливости ради.
0
Сорри, не меню, а переключение между табами. Оно всегда было наверху, начиная с 1.x
+1
и до него всегда было неудобно тянуться большим пальцем правой руки…
Иногда мне кажется что некоторые вещи в андроиде сделаны не удобства для, а исключительно из духа противоречия
0
Типичная проблема многих программ, на хабре об этом недавно было.
0
Текущий город может быть определён автоматически по GPS-координатам. Это одна из тех фишек, которая использовалась нами в дальнейших разработках. На сервере у нас хранится словарь населённых пунктов. С помощью простого веб-сервиса мы посылаем туда наши текущие координаты и получаем название и айдишник города. Ну или деревни :)

А почему вы не стали использовать обратный геокодинг, которые предоставлять Google Maps API?
0
нам же нужно знать не только название, но и внутренний айдишник населённого пункта
Only those users with full accounts are able to leave comments., please.