Памятка (шпаргалка) по ошибкам, коду для Android

Содержание

Android 9 — Включить режим разработчика

Режим разработчика в Android 9 включается в Настройках системы — About phone, необходимо найти раздел Build number, тапнуть по нему несколько раз, появится предупреждение — You are now N step away from being a developer:

Android 9 - Включить режим разработчика

После успешного включения, появится сообщение — You are now a developer!

Android 9 - Включить режим разработчика

Опции разработчика теперь доступны в разделе Настроек системы — System — Developer options

Android 9 - Включить режим разработчика

Отключить режим разработчика в Android

Отключается в разделе Настройки системы — System — Developer options

 

Указание системных переменных для Android SDK

Указание системных переменных для Android SDK в ОС Windows, полезно в случаях, когда папка с SDK была попросту скопирована с другого компьютера.

  1. Переменные указываются в настройках системных переменных — System Properties — Advanced — Environment Variables…
  2. Создать новую переменную в System variables с именем — ANDROID_SDK_HOME и указанием значения к папке с SDK — D:\Dev\Android\android-sdks
  3. Там же указать в переменной PATH путь к папке tools — ;D:\Dev\Android\android-sdks\tools
  • После произведенных действий AVD образы будут сохраняться в папке — D:\Dev\Android\android-sdks\.android\avd
  • После перезагрузки, в командой строке теперь можно к примеру почитать хелп выполнив команду — android —help

 

Памятка по созданию приложений под Android в Eclipse

Добавление ANDROID-SDK в Eclipse

  • Help — Install New Software
  • Add

В открывшемся окне, необходимо уазать имя и ссылку:

  • Имя к примеру — ADT
  • Ссылка — https://dl-ssl.google.com/android/eclipse/

По нажатию на кнопку Ok, в выпадающем списке Work with необходимо выбрать ADT и подождать пока подгрузятся запрашиваемые данные, после необльшого ожидания в окне ниже появится Developer Tools, отмечаем флажком, далее, принимаем лицензионное соглашение, устанавливаем, перезапускаем Eclipse. После перезапуска откроется диалог посредством которого можно установить Android-SDK, или указать путь к уже загруженному ранее. После указания и прниятия или отказа от сбора анонимной статистики Google, откроется Android SDK Manager в окне которого можно указать, какие компоненты необходимо загрузить и установить (моя папка с Android SDK на сегодняшний день весит почти 6Гб, так что можно налить горячего чаю или кофе, или холодненького пива и подождать пока будет происходить загрузка и установка компонентов).

После загрузки и установки SDK, можно создать вирутальное устройство (эмулятор) Android (Android Virtual Devise (AVD)) — Windows — Android Virtual Devise Manager, в открывшемся окне нажимаем кнопку — New, далее указываем параметры для используемой «машины».

Создание проекта

  • File — New — Project
  • В открывшемся окне выбираем — Android — Android Application Project

В окне создания проекта указываем:

  • имя проекта — Project Name (отображаемое в списке дерева проектов)
  • имя приложения — Application Name (имя программы отображаемое в списке установленных программ в системе)
  • имя пакета — Package Name (префикс для имени классов приложения)
  • минимальные требования к SDK — Minimum Reqired SDK (минимальная версия Android, под который будет запускаться приложение)
  • целевое SDK — Target SDK (под какую версию Android будет работать приложение, возможности какой ОС будут использоваться)
  • компиляция — Compile With (под какую версию Android компиллировать приложение)
  • тема — Theme (соотвественно выбор темы)

далее можно создать \ указать свою иконку, которая будет использоваться приложением, где будет созранен проект, выбор типа активити (для примера можно создать Blank Activity).

Структура приложения

после создания проекта в проводнике объектов будет отражена структура каталогов, опишу основные:

  • res, assets — здесь хранятся файлы-ресурсы
  • gen — автоматически сгенерированные средой файлы
  • src — здесь хранится весь созданный код
  • AndroidManifest — конфигурационный файл приложения

Запуск

Запуск приложения осуществляется нажатием кнопки Run (Ctrl + F11), эмулятор запустися автоматически, после запуска эмулятора, приложеие так же запустится автоматически с надписью Hello world!

Android — Layouts

Как известно Android приложение отображает на текущем экране в «окне» называемом Activity, в один момент времени может отражаться только одно Activity, содержимое Activity формируется из видов — View, видом может быть кнопка, тектовое поле для ввода текста и т.п. как правило виды размещаются в ViewGroup, одим из которых является Layout, основными видами Layout являются:

  • LinearLayout
  • TableLayout
  • RelativeLayout
  • AbsoluteLayout

В некоторых случаях метод разметки отдаленно напоминает разметку каскадной таблицы стилей:

  1. Absolute — явная позиция на экране, задается координатми или «ручной» установкой элемента на экране
  2. Relative — относительная позиция по отношению к другим элементам, слева (layout_toLeftOf), справа (layout_toRightOf), сверху (layout_above), снизу (layout_below), выравнивание по левому указанного элемента (layout_alignLeft), правому (layout_alignRight), верхнему (layout_alignTop), нижнему (layout_alignBottom), родителя layout_alignParentLeft, layout_alignParentRight, layout_alignParentTop, layout_alignParentBottom, выравнивание по центру относительно родителя layout_centerVertical, layout_centerHorizontal, layout_centerInParent
  3. Table — отображение в столбцах, строках формирубщих таблицу, приницип построения чем то похож на html, стоки — TableRow, содержат в себе виды организуют столбцы, максимальное количество видов в строке определяет количество столбцов во всей таблице, так же ширина столбца определяется шириной самого широкого элемента
  4. Linear — отображение в виде одной строки ориентированной по вертикали или горизонтали, изменяя ориетацию LinearLayout на horizontal, vertical расположение внутренних элементов изменяется в соовтествии с данной ориентацией.

 

Android — включение отладки на телефоне

— Настройки — Параметры разработчика в 4.2+

Включение

  1. Настройки — Приложения — Разработка, включаем — Отладка USB, Эмуляция расположения
  2. Проверяем параметры отладки при блокировке экрана — Настройки — GPS и Безопасность — Отключить отладку USB

После чего, к примеру в Eclipse, в представлении DDMS появится новое устройство, на котором можно отлаживать разрабатываемое приложение.

Памятка (шпаргалка) по ошибкам, коду для Android

Android 4 — включение опции разработчика (Developer options)

  • Настройки — General — About device
  • Находим строку Build number — нажимаем несколько раз
  • Выходим назад в General, любуемся появившемся — Developer options
  • Включаем возможность отладки по USB — Developer options — USB debugging

 

DPAD not enabled in avd

Проблема

При запуске AVD машины кнопки вправо, влево, вверх, вниз, центр — неактивны, над кнопками надпись:

DPAD not enabled in avd

В настройках машины, соотвествующие флажки отмечены, но темнеменее кнопки отключены.

Решение

Найти путь, по которому расположен виртуальный образ:

  • Android virtual device manager
  • Выбрать машину, нажать кнопку Details
  • В строке Path будет указан путь к образу, типа — /home/user/.android/Nexus.avd

Отредактировать конфиурационный файл:

  • Перейти в папку с машиной
  • Открыть файл config.ini
  • Изменить значение параметра hw.dPad=no на hw.dPad=yes
  • Перезапустить машину

 

Android — Int to String

Android перевод Integer в String, ниже пример:

int i = 5;
String iItems = String.valueOf(i);

 

Android установка apk на avd

Понадобилось установить на AVD машину пакет apk, данный пакет был расположен в интернете, при попытке загрузить его, этот пакет открывался браузером как текстовый файл, как быть? Оказывается данный пакет можно установить «оффлайн» используюя инструменты Android-SDK.

Открываем командную строку, переходим в папку с SDK

cd D:\Dev\Android\android-sdks\platform-tools

Смотрим запущенные машины

adb devices
List of devices attached
emulator-5556   device

Устанавливаем пакет

adb install d:\!prg\android\AndroidPack.apk
59 KB/s (343102 bytes in 5.597s)
        pkg: /data/local/tmp/Android+Terminal+Emulator+1.0.50.apk
Success

Используем установленный пакет на устройстве.

 

The method execute(Object[]) is ambiguous for the type

При попытке вызова асинхронной задачи, возникала ошибка:

The method execute(Object[]) is ambiguous for the type …

Метод вызывался следующим образом:

View.OnClickListener btnClk = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (btnGetData.getId() == ((Button) v).getId()) {

                new FetchTask(Main.this).execute(null);
            }
        }
    };

Ошибка исправляется указанием типа:

new FetchTask(Main.this).execute((Integer) null);

 

 

Activity not started, its current task has been brought to the front

При запуске \ запуске отладки приложения в Eclipse, приложение не запускается, в строке консоли появляется сообщение:

ActivityManager: Warning: Activity not started, its current task has been brought to the front

Решить вопрос можно сбросом «зависшего» приложения, для этого необходимо перейти в перспективу DDMS, в окне, где отображаются устройства:

  1. Необходимо найти свое устройство, на котором данное приложение запущено
  2. Выбрать свое приложение
  3. Завершить нажатием кнопки stop в панели инструментов

 

 

Andoid — добавление Activity \ переключение между Activity

Данный метод описывает процесс создания нового Activity, класса, кнопки позволяющей произвести переход с текущего на созданный Activity. Подразумевается, что проект уже создан (в Eclipse) и в данный проект необходимо добавить новое Activity, необходимо создать два файла, в папку res\layout\activity_second.xml:

  • ПКМ на папке res — New — Android XML file
  • В открывшемся окне необходимо выбрать Resource Type — Layout
  • Указать имя файла
  • Указать корневой элемент, по умолчанию LinearLayout
  • Finish

Второй файл, это класс посредством кторого будет отражено новое Activity src\kz\sys_admin\switchactivity\SecondActivity.java:

  • ПКМ на папке res — New — Class
  • В поле Name необходимо указать имя нового класса SecondActivity
  • Finish

Подправить файл AndroidManifest.xml, добавив в него строки перед тегом </application>:

<activity
            android:name="SecondActivity"
            android:label="@string/app_name"/>

Первая часть необходимых действий завершена, далее необходимо добавить код в файл SecondActivity, который в первоначальном состоянии выглядит следующим образом:

package kz.sys_admin.switchactivity;

public class SecondActivity extends Activity{

}

далее необходимо добавить метод onCreate, расширить класс SecondActivity, после правки код выглядит так:

package kz.sys_admin.switchactivity;

import android.app.Activity;
import android.os.Bundle;

public class SecondActivity extends Activity{
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
    }

}

Далее необходимо создать кнопку, которая позволит с первого Activity (activity_main.xml) совершить переход на второе (activity_second.xml), добавляем кнопку в activity_main.xml:

<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:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <Button
        android:id="@+id/button1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:text="Swith to Second" />

</RelativeLayout>

Далее открываем src\kz\sys_admin\switchactivity\MainActivity.java в который вставляем обработчик для кнопки:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        Button swith = (Button)findViewById(R.id.button1);
        swith.setOnClickListener(new OnClickListener() {
            
            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                Intent SecAct = new Intent(getApplicationContext(), SecondActivity.class);
                startActivity(SecAct);
            }
        });
    }

 

Готово, запускаем проект, проверяем.

 

Добавить кавычки в Java код

Недавно передо мной встал вопрос — как вставить кавычки ‘, » в Java код, например надо получить на выходе текст:

Simple’s code

Решается просто — добавлением слеша перед тем или иным знаком:

String text = "Simple\'s code"

так же и для » т.е. \’ или \».

 

 

Android — передача данных между Activity

Существует задача — передать данные значений одного из видов (View) из одного Activity в другое, делается это при помощи putExtra, getStringExtra (доп. инфо можно посмотреть ЗДЕСЬ) и так имеется два Activity, на первом есть пару видов — TextView и EditText, если EditText пустой, то данные передаются из TextView, если нет то из самого EditText.

MainActivity.java — OnCreate

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

        final EditText ed = (EditText) findViewById(R.id.editText1);
        final TextView tv = (TextView) findViewById(R.id.textView1);
        
        Button btnPut = (Button) findViewById(R.id.button1);
        btnPut.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                Intent secAct = new Intent(getApplicationContext(),
                        SecondActivity.class);
                // Get views data
                final String edStr = ed.getText().toString();
                final String str = tv.getText().toString();
                // Check data
                if (edStr.matches("")) {
                    secAct.putExtra("KEY", str);
                } else {
                    secAct.putExtra("KEY", edStr);
                }
                //Start intent
                startActivity(secAct);

            }
        });
    }

SecondActivity.java — onCreate

@Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        
        TextView tv = (TextView)findViewById(R.id.textView2);
        Intent intent = getIntent();
        tv.setText(intent.getStringExtra("KEY"));
        
        Button btnBack = (Button)findViewById(R.id.button2);
        btnBack.setOnClickListener(new View.OnClickListener() {
            
            @Override
            public void onClick(View v) {
                Intent firstAct = new Intent(getApplicationContext(), MainActivity.class);
                startActivity(firstAct);
                
            }
        });        
    }

}

 

 

Автоматическая генерациция Java классов для сервиса WCF (odata)

В этой статье я расскажу о том, как автоматически сгенерировать набор Java классов для приложения использующего WCF Data Service, данные классы могут использоваться к примеру в Android приложении, которое будет работать с данным сервисом.

Классы генерируются достаточно просто для этих целей мы будем использовать RESTLET FRAMEWORK, загружать необходимо Java SE, после загрузки и распаковки фреймворка, необходимо создать новый Java проект (я использую Eclipse поэтому все действия буду описываться именно под эту IDE):

далее добавить в проект некоторые библиотеки Restlet из папки lib, а именно:

  • org.restlet.jar
  • org.restlet.ext.odata.jar
  • org.restlet.ext.freemarker.jar
  • org.restlet.ext.atom.jar
  • org.restlet.ext.xml.jar
  • org.freemarker_2.3\org.freemarker.jar

библиотеки можно добавить нажатием кнопки Add external JARs…:

далее необходимо создать новый Java класс, назовем его main:

в папке проекта необходимо создать папку для генерируемых классов, назовем ее gens, в свойствах папки необходимо просмотреть и скопировать путь к этой папке, он нам еще пригодится, делее в созданный класс необходимо добавить следующий код:

public static void main(String[] args){
        
        Generator.main(new String[] {
                  "http://Server/northdata.svc/",
                  "D:\\Project\\gens"
                });
    }

где http://Server/northdata.svc/ — наш WCF сервис, D:\\Project\\gens — наш каталог, далее запустить проект, если все было сделано правильно, в консоли должен быть отражен статус успешной работы:

---------------------------
OData client code generator
---------------------------
step 1 - check parameters
step 2 - check the ouput directory
step 3 - get the metadata descriptor
Starting the internal [HTTP/1.1] client
Get the metadata for http://Server/northdata.svc/ at http://Server/northdata.svc/$metadata
Starting the internal [HTTP/1.1] client
step 4 - generate source code
Starting the internal [HTTP/1.1] client
Get the metadata for http://Server/northdata.svc/ at http://Server/northdata.svc/$metadata
Starting the internal [HTTP/1.1] client
The source code has been generated in directory: D:\Project\gens

Далее эти классы можно уже использовать в своем Android приложении.

 

Android — получение HTTP заголовков

Недавно понадобилась возможность распознавания Android клиентом HTTP заголовков, ниже приведу процедуру, которая позволяет данные заголовки получить с указанного URL.

public void getHeaders(String url){
        // инициализация клиента
        HttpClient client = new DefaultHttpClient();
        // GET запрос
        HttpGet httpGet = new HttpGet(url);
        HttpResponse response = null;
        try {
            // выполнение GET запроса
            response = client.execute(httpGet);
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        // получение HTTP заголовков
        org.apache.http.Header[] headers = response.getAllHeaders();
        // обработка, вывод результатов в LogCat
        for (int i = 0; i < headers.length; i++) {
            org.apache.http.Header header = headers[i];
            Log.d(log_tag, "HTTP Header - " + header.getName() + ": " + header.getValue());
        }
    }

Запуск, можно производить к примеру так:

getHeaders("http://MyServer");

 

 

Android — ошибка добавления текста в TextView во время выполнения doInBackground

Во время выполнения AsyncTask doinBackground в момент изменения содержания TextView приложение завершало работу с ошибкой:

thread exiting with uncaught exception (group=0x4001e578)

Оказывается эту «проблему» можно обойти, использовав конструкцию:

runOnUiThread(new Runnable() {
    public void run() {
        myTV.setText("Text changed in doinBackground!");
    }
});

в своем потоке.

 

 

Type mismatch: cannot convert from AsyncTask

При попытке использования AsyncTask методом:

private JSONObject goTask(String link){
 JSONObject j = null;
 j = new myTask().execute(link);
 return j;
 }

возникала ошибка:

Type mismatch: cannot convert from AsyncTask<String, String, JSONObject> to JSONObject

решается путем вызова get(), который необходим для возврата результата, в итоге имеем:

private JSONObject goTask(String link){
        JSONObject j = null;
        try {
            j = new myTask().execute(link).get();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ExecutionException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return j;
    }

 

 

Android — создание callback для AsyncTask

Ниже опишу процесс вызова callback из AsyncTask, этот метод очень полезен в сучае необходимости получения данных из задачи и использовании ProgressDialog без параметра .get(). Предположим проект уже существует, далее описывается сама «технология», добавляем в проект интерфейс:

public interface AsyncTaskCompleteListener {
    public void onTaskComplete(JSONObject result);
}

Создаем класс задачи, добавлем в него наш callback:

// callback
        private Activity activity;
        private AsyncTaskCompleteListener callback;
        private ProgressDialog dialog;
        
        public GetTask(Activity act){
            this.activity = act;
            this.callback = (AsyncTaskCompleteListener)act;
        }

в onPostExecute вызываем:

callback.onTaskComplete(result);

подключаем к своему активити:

public class Main extends Activity implements AsyncTaskCompleteListener{ ..... }

нас компилятор попросит добавить метод в класс Main:

@Override
public void onTaskComplete(JSONObject result) {
    // TODO Auto-generated method stub
}

В данном случае я вызываю задачу так:

void callTask(String link){
        task.new GetTask(this).execute(link);
    }

Смотрим результат к примеру так:

@Override
    public void onTaskComplete(JSONObject result) {
        // TODO Auto-generated method stub
        System.out.println(result);
    }

 

Only the original thread that created a view hierarchy can touch its views

Во время выполнения потока, задавался текст для TextView, в некоторых случаях работа потока завершалась ошибкой:

W/System.err(7094): android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

Ошибку можно исправить используя Handler, определяя его в методе OnCreate:

private Handler handler;
....
        // определяем handler
        handler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                String text = (String) msg.obj;
                tvExtarnalIpData.setText( text );
            }
        };

В потоке, где указывался текст для TextView:

tvExtarnalIpData.setText(ip);

Изменяем на:

Message msg = new Message();
msg.obj = ip;
handler.sendMessage(msg);

Либо можно заменить указание TextView на:

Handler handler = new Handler(getBaseContext().getMainLooper());
handler.post( new Runnable() {
    @Override
    public void run() {
        tvExtarnalIpData.setText(ip);
    }
} );

Android — добавление элементов в OptionsMenu

Элементы OptionMenu, это те самые элементы, которые отображаются при нажатии на кнопку Menu, в приложениях удобно использовать для кнопок настроек, выхода из приложения и т.п. ниже в краце расскажу о том, как добавить несколько кнопок в приложение и привязать к ним код.

Для начала необходимо отредактировать файл проекта …res\menu\main.xml, добавив в него элементы меню:

<menu xmlns:android="http://schemas.android.com/apk/res/android" >

    <item
        android:id="@+id/Toast1"
        android:orderInCategory="100"
        android:showAsAction="never"
        android:title="@string/Toast1"/>
    
    <item
        android:id="@+id/Toast2"
        android:orderInCategory="100"
        android:showAsAction="never"
        android:title="@string/Toast2"/>

</menu>

Далее добавить значения надписей для android:title в …res\values\strings.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <string name="app_name">ExitOptionMenu</string>
    <string name="hello_world">Hello world!</string>
    <string name="Toast1">Show Toast1</string>
    <string name="Toast2">Show Toast2</string>

</resources>

Теперь можно запустить приложение, проверить наличие созданных кнопок, далее привязываем код:

@Override
    public boolean onOptionsItemSelected(MenuItem item){
        
        switch (item.getItemId()) {
        case R.id.Toast1:
            Toast.makeText(this, "Toast1 pressed", Toast.LENGTH_SHORT).show();
            break;
        case R.id.Toast2:
            Toast.makeText(this, "Toast2 pressed", Toast.LENGTH_SHORT).show();
            break;
        default:
            break;
        }
        
        return super.onOptionsItemSelected(item);
        
    }

По нажатию на ту или иную кнопку, будет появляться всплывающее сообщение.

Примечание: элементы меню вызываются уже существующим кодом (который создается по умолчанию при создании проекта приложения):

@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

 

Возможно вам будет интересно — 50 лучших ресурсов для android-разработчиков.