четверг, 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