среда, 10 октября 2012 г.

#ifdef for android project

1. Плагин для eclipse


Antenna

2. Под проекты.


Общий код вынести в библиотеку.
Создать новые проекты и использовать библиотеку.

3. Системы автоматической сборки.


maven, ant


Links



четверг, 19 июля 2012 г.

Отключить кнопку HOME

Гугл не рекомендует этого делать. Пользователь всегда должен иметь возможность выйти из приложения.
Но иногда нужно.

Рабочее решение
Логичный шаг получить событие кнопки.


public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_HOME) {
     // делаем что-то полезное :)
     return true;
   } else {
     return super.onKeyDown(keyCode, event);
   }
 }


Магия, без которой не работает

public void onAttachedToWindow() {

this.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD);

super.onAttachedToWindow();

}




Ссылки
http://stackoverflow.com/questions/6693896/home-key-press-event-listener
http://stackoverflow.com/questions/2079691/overriding-the-home-button-how-do-i-get-rid-of-the-choice
http://stackoverflow.com/questions/4783960/call-method-when-home-button-pressed-on-android?rq=1

Две acvivity в Launcher

Две активити в ланчере. Одна для приложения, другая для настроек.

  <application
        android:name=".APP"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name">
       
        <activity
            android:name=".activity.Main"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>

        <activity
            android:name=".activity.Preferences"
            android:label="@string/set_preferences"
            android:noHistory="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
  </application>

ссылки
http://stackoverflow.com/questions/8927315/two-launcher-activities

Разные Android Context

Какая разница между context.




public class MyActivity extends Activity { 
  public void method() { 
    mContext = this; // since Activity extends Context 
    mContext = getApplicationContext(); 
    mContext = getBaseContext(); 
  } 
}



Если сделать Toast разными context, то:

Умрет вместе с активити.
Toast.makeText(this, "Text", Toast.LENGTH_SHORT).show();

Умрет вместе с приложением
Toast.makeText(getApplicationContext(), "SD card not found", Toast.LENGTH_SHORT).show();

Будет виден даже после завершения приложения.
Toast.makeText(getBaseContext(), "SD card not found", Toast.LENGTH_SHORT).show();

Обсуждение
http://stackoverflow.com/questions/1026973/android-whats-the-difference-between-the-various-methods-to-get-a-context

Поиск USB флешки


Рабочий вариант

Задача.
Поиск файлов на USB в специальной папке
FOLDER_NAME - имя папки
searchFileInFolder - функция проверке на наличие нужной информации в найденной папке.

Возвращает первую папку, с
private String searchSMILFileInMNT() {
Log.d(TAG,"[mnt] Scan start");

File mnt = new File("/mnt/");
File mntFileList[] = mnt.listFiles();

for(int i=0; i< mntFileList.length; i++){
File f = mntFileList[i];
Log.d(TAG,"[mnt] Scan dir "+f.getAbsolutePath());
if(f.isDirectory() && f.canRead()){
File smilDir = new File(f.getAbsolutePath()+File.separator+FOLDER_NAME);
String SDcardPath = Environment.getExternalStorageDirectory().getAbsolutePath();

if(smilDir.isDirectory() && smilDir.canRead() && (!smilDir.getAbsolutePath().equals(SDcardPath))){
String name = searchFileInFolder(smilDir.getAbsolutePath());
if(name!=null){
Log.d(TAG,"[mnt] Found file "+name);
return smilDir.getAbsolutePath()+File.separator + name;
}

}
}

}
Log.d(TAG,"[mnt] mothing found");
return null;
}

Как получить список всех примонтированых  USB устройств?

Приложение работает в емуляторе?

Проверка


boolean inEmulator = "generic".equals(Build.BRAND.toLowerCase());



http://stackoverflow.com/questions/2799097/how-can-i-detect-when-an-android-application-is-running-in-the-emulator

суббота, 14 июля 2012 г.

Android autostart application

При старте устройства можно сделать что-то полезное :)

права

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

Регистрация получателя


<receiver android:name="com.example.MyBroadcastReceiver">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED" />
    </intent-filter>
</receiver>


Получатель


package com.example;

public class MyBroadcastreceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Intent startServiceIntent = new Intent(context, MyService.class);
        context.startService(startServiceIntent);
    }
}


Как проверить?


open console/terminal and navigating to /platform-tools
type "adb shell" or on linux/mac "./adb shell"
in the shell type "am broadcast -a android.intent.action.BOOT_COMPLETED" or whatever action you want to fire

Проблемы
Если стартовать activity, то иногда activity выкидывает nullPointerException при доступе к context или getExternalCacheDir.
Решение: Thread.sleep(1000); перед context.startService(startServiceIntent); в BroadcastReceiver.




Пример

https://github.com/commonsguy/cw-advandroid/tree/master/SystemEvents/OnBoot

Ссылки

http://stackoverflow.com/questions/7317939/android-autostart-application?rq=1

http://stackoverflow.com/questions/5051687/broadcastreceiver-not-receiving-boot-completed

четверг, 12 июля 2012 г.

BroadcastReceiver событие при монтирование USB флешки в Android


Как узнать что USB флешка подключена?



Можно подписаться на события.

Способ 1. Ручками.


В activity в методе onCreate() например.

IntentFilter filter = new IntentFilter(Intent.ACTION_MEDIA_MOUNTED);

//filter.addAction(Intent.ACTION_MEDIA_UNMOUNTED);

//filter.addAction(Intent.ACTION_MEDIA_SCANNER_FINISHED);

filter.addDataScheme("file"); //В документации не написано, но без нее не работает

registerReceiver(myMountReceiver, filter);


В onDestroy()
unregisterReceiver(myMountReceiver);

ну и 

private MountBroadcastReceiver myMountReceiver;

Способ 2. В манифесте


В файл AndroidManifest.xml необходимо добавить

        <receiver
            android:name=".MountBroadcastReceiver"
            android:enabled="true"
            android:label="MountBroadcastReceiver" >
            <intent-filter>
                <action android:name="android.content.Intent.MEDIA_MOUNTED" />
                <data android:scheme="file" />
            </intent-filter>
        </receiver>

Класс MountBroadcastReceiver

public class MountBroadcastReceiver extends BroadcastReceiver { public MountBroadcastReceiver(){ super(); }
@Override public void onReceive(Context context, Intent intent) { String mountDir = intent.getDataString(); if (intent.getAction().equals(Intent.ACTION_MEDIA_MOUNTED)) { Toast.makeText(context,"Media mounted to"+mountDir, Toast.LENGTH_LONG).show(); }}

Права доступа

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

Ссылки


http://developer.android.com/reference/android/content/Intent.html#ACTION_MEDIA_MOUNTED
http://developer.android.com/reference/android/content/Intent.html#ACTION_UMS_CONNECTED


http://stackoverflow.com/questions/994746/android-broadcastreceiver-cant-receive-any-broadcast-events

http://stackoverflow.com/questions/8791282/android-how-to-detect-turn-on-usb-storage-broadcast
http://stackoverflow.com/questions/9340332/how-can-i-get-the-list-of-mounted-external-storage-of-android-device

http://stackoverflow.com/questions/5522963/usb-connection-notification

http://stackoverflow.com/questions/11281010/how-can-i-get-external-sd-card-path-for-android-4-0
http://stackoverflow.com/questions/7142987/media-mounted-broadcast-not-being-recieved
http://stackoverflow.com/questions/994746/android-broadcastreceiver-cant-receive-any-broadcast-events

четверг, 26 января 2012 г.

Установка и настройка NFS в Debian и Ubuntu

Настройка СЕРВЕРА


Устанавливаем NFS-сервер:

  $sudo apt-get install nfs-kernel-server nfs-common portmap

Настраиваем, какие именно директории мы хотим открыть для совместного пользования и кому. Все это делается в файле /etc/exports:

  $sudo nano -w /etc/exports

В приведенном ниже примере я выделил директорию /home/user (директория с данными на сервере) в совместное пользование компьютерам с IP – 192.168.24.1-255 правами чтения и записи:

/home/user 192.168.24.1/24(rw,subtree_check,async)

Опции:

ro – права только на чтение. Можно и не указывать, так как она установлена по умолчанию.

rw – дает клиентам право на запись.

no_root_squash – по умолчанию пользователь root на клиентской машине не будет иметь доступа к разделяемой директории сервера. Этой опцией мы снимаем это ограничение. В целях безопасности этого лучше не делать.

noaccess – запрещает доступ к указанной директории. Может быть полезной, если перед этим вы задали доступ всем пользователям сети к определенной директории, и теперь хотите ограничить доступ в поддиректории лишь некоторым пользователям.


Теперь нужно перезапустить дабы все заработало nfs-kernel-server:


  $sudo /etc/init.d/nfs-kernel-server restart

В дальнейшем при изменении конфигурационного файла будет достаточно перечитать конфигурационный файл тут все просто

  $sudo exportfs -a



Настройка КЛИЕНТА


Установка и настройка NFS-клиента.
Установка:
  $sudo apt-get install portmap nfs-common

Монтирование:
Создаем точку монтирования (папку к которой будет монтирована папка с сервера)
я лично предпочитаю все монтировать в каталог /media/
  $cd /media
  $sudo mkdir server.name_user

Монтирование NFS ресурса автоматически, для этого отредактируем файл /etc/fstab
  $sudo nano -w /etc/fstab
  192.168.24.100:/home/user /media/server.name_user nfs rw,hard,intr 0
  $sudo mount /media/hard

понедельник, 23 января 2012 г.


vsftpd: включение пользовательских директорий

Задача: предоставить пользователям доступ к файлам в домашней директории по ftp

cat /etc/vsftpd.conf | grep -v '#'
listen=YES
anonymous_enable=NO
local_enable=YES
write_enable=YES
local_umask=022
dirmessage_enable=YES
use_localtime=YES
xferlog_enable=YES
connect_from_port_20=YES
chroot_local_user=YES
secure_chroot_dir=/var/run/vsftpd/empty
pam_service_name=vsftpd
rsa_cert_file=/etc/ssl/private/vsftpd.pem



apache2: включение пользовательских директорий

В apache имеется удобная возможность публикации статических файлов прямо из домашней директории пользователей размещённых на вебсервер. Включить эту возможность по быстрому можно вот так:

sudo a2enmod userdir
sudo apache2ctl restart
mkdir ~/public_html
edit /etc/apache2/mods-available/php5.conf
comment lines 
#        <Directory /home/*/public_html>
#            php_admin_value engine Off
#        </Directory>


Вот и всё, по умолчанию модуль userdir публикует директории /home/*/public_html и это вполне достаточно чтобы выложить файлы для публикации

Чтобы получить доступ к опубликованным файлам необходимо пользоваться таким урлом

http://имя.сервера/~имя_юзера/