широковещательный приемник не принимает событие камеры

Я пытаюсь создать приложение, которое определяет, когда пользователь делает снимок. Я установил класс широковещательного приемника и зарегистрировал его в файле манифеста:

<receiver android:name="photoReceiver" >
  <intent-filter>
    <action android:name="com.android.camera.NEW_PICTURE"/>
      <data android:mimeType="image/*"/>
 </intent-filter>
</receiver>

Что бы я ни делал, программа не принимает трансляцию. Вот мой класс приемника:

public class photoReceiver extends BroadcastReceiver {
  private static final String TAG = "photoReceiver";

@Override
public void onReceive(Context context, Intent intent) {
    CharSequence text = "caught it";
    int duration = Toast.LENGTH_LONG;
    Log.d(TAG, "Received new photo");

    Toast toast = Toast.makeText(context, text, duration);
    toast.show();
 }
}

Если я удалю строку mimeType в манифесте и в своей деятельности, я отправлю свою собственную трансляцию, используя

Intent intent = new Intent("com.android.camera.NEW_PICTURE");
sendBroadcast(intent);

тогда я успешно получаю трансляцию и вижу окно журнала и тоста. Правильно ли я к этому подхожу? Есть что-нибудь, что мне нужно добавить?


person John    schedule 31.12.2010    source источник
comment
Откуда вы взяли com.android.camera.NEW_PICTURE? Из того, что я могу сказать после беглого просмотра sdk, этого действия не существует.   -  person techiServices    schedule 31.12.2010
comment
@sugarynugs Я нашел это в некоторых других темах. Вот один из них, видимо из источника камеры. stackoverflow.com/questions/3015448/…, когда делается снимок, он вызывает sendBroadcast (new Intent (com.android.camera.NEW_PICTURE, mLastContentUri));   -  person John    schedule 01.01.2011
comment
на какой версии андроида вы это тестируете?   -  person techiServices    schedule 01.01.2011
comment
@sugarynugs Тестирую прямо на своем HTC Evo с Froyo (2.2). Я также тестировал его на эмуляторе на 2.2, но безуспешно. Я пробовал много разных вещей, например, программно регистрировать приемник, и все равно не повезло. Есть ли другой способ, которым я могу отследить, когда был сделан снимок в фоновом режиме? Я хочу, чтобы мое приложение оставалось в фоновом режиме и слушало событие. Единственное, о чем я могу думать, - это настроить приемник в хранилище мультимедиа и прослушивать изображения, сохраняемые с камеры, но это было бы гораздо хлопотнее! Спасибо за помощь!   -  person John    schedule 02.01.2011
comment
@sugarynugs Кроме того, мне интересно, может ли HTC Sense каким-то образом изменить способ вещания камеры, но даже если это так, он должен работать на эмуляторе. Просто мысль.   -  person John    schedule 02.01.2011
comment
@John Пытаюсь сделать то же самое. Просто потому, что приложение камеры по умолчанию отправляет трансляцию, когда делается снимок, это не означает, что другое приложение камеры тоже отправит его. По крайней мере, существует соглашение о сохранении фотографий в / DCIM / 100MEDIA, хотя просмотр этого также ненадежен.   -  person siamii    schedule 07.03.2011
comment
Что вообще такое сахаринги?   -  person gonzobrains    schedule 25.05.2013
comment
@siamii Наблюдение за этим каталогом ненадежно, потому что вместо него можно использовать другие каталоги? Как насчет использования намерения Camera.ACTION_NEW_PICTURE?   -  person gonzobrains    schedule 25.05.2013


Ответы (5)


Я решил это, но другим методом. Вместо использования широковещательного приемника я установил файловый обозреватель для отдельных папок, в которые сохранялась камера. Это не так практично, как другой способ, но все равно работает нормально. Вот как я это настроил:

FileObserver observer = new FileObserver(android.os.Environment.getExternalStorageDirectory().toString() + "/DCIM/100MEDIA") { // set up a file observer to watch this directory on sd card
            @Override
        public void onEvent(int event, String file) {
            if(event == FileObserver.CREATE && !file.equals(".probe")){ // check if its a "create" and not equal to .probe because thats created every time camera is launched
                Log.d(TAG, "File created [" + android.os.Environment.getExternalStorageDirectory().toString() + "/DCIM/100MEDIA/" + file + "]");
                fileSaved = "New photo Saved: " + file;
            }
        }
    };
    observer.startWatching(); // start the observer
person John    schedule 03.01.2011
comment
Ницца! приятно видеть человека, который может думать самостоятельно; D. Я смотрел на источник камеры, и метод storeImage в классе ImageCapture отвечает за запуск этого намерения. Этот метод запускает намерение только в том случае, если !mIsImageCaptureIntent. Я не стал искать дальше, но я подумал, что это означает, что если захват изображения не произошел из-за намерения, сделайте следующее. Не уверен, как вы делаете снимок и использует ли приложение камеры намерение сделать снимок, но пищу для размышлений. - person techiServices; 04.01.2011
comment
Проблема с этим решением заключается в том, что приложение все время должно работать в фоновом режиме, чтобы наблюдать за файловой системой. Основная проблема и не очень хорошая игра. - person AlikElzin-kilaka; 16.07.2012
comment
Можете ли вы использовать это решение для мониторинга нескольких папок или вам нужно создать отдельный FileObserver для каждой папки, за которой вы хотите наблюдать? - person gonzobrains; 28.05.2013
comment
Вы должны создать наблюдателя для каждой папки, которую хотите отслеживать. - person Ruzard; 09.06.2013
comment
Опоздал на 2 года на вечеринку, но я попробовал решение, данное Танаем ниже, и оно действительно работает при захвате изображений! Есть возражения против того, почему я не должен его использовать? - person Snake; 02.12.2013

Я уверен, что этот способ работает на 100%. Я тщательно тестировал.

Зарегистрируйте свой широковещательный приемник в AndroidManifest. В большинстве ответов выше отсутствует категория android: name = "android.intent.category.DEFAULT". BroadcastReceiver не может запускаться без этого

  <receiver
    android:name=".CameraReciver"
    android:enabled="true" >
        <intent-filter>
            <action android:name="com.android.camera.NEW_PICTURE" />
            <action android:name="android.hardware.action.NEW_PICTURE" />
            <category android:name="android.intent.category.DEFAULT" />
            <data android:mimeType="image/*" />

        </intent-filter>
    </receiver>

И, наконец, вы создаете класс с именем «CameraReciver.java», наследующий от BroadcastReceiver, и этот мой код:

public class CameraReciver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
    // TODO Auto-generated method stub
    Log.i("INFO", "Enter BroadcastReceiver");



Cursor cursor = context.getContentResolver().query(intent.getData(),
                null, null, null, null);
        cursor.moveToFirst();
        String image_path = cursor.getString(cursor.getColumnIndex("_data"));
        Toast.makeText(context, "New Photo is Saved as : " + image_path, 1000)
                .show();



}

После этого разверните свой проект в эмуляторе (я использую genymotion), конечно, ничего не произошло, потому что ваш BroadCastReceiver работает без графического интерфейса. Позвольте вам открыть приложение камеры и нажать кнопку захвата. Если все в порядке, вы получите тост с содержанием вроде «Новое фото сохранено как: storage / emulated / 0 / DCIM / Camera / IMG_20140308.jpg». Пусть наслаждаются ^ _ ^

Спасибо "tanay khandelwal" (ответивший выше) за то, как получить путь к новой фотографии, снятой камерой ^ _ ^

Надеюсь помочь всем

person VO DUC HUY    schedule 08.03.2014
comment
Я пробовала, но мне это не помогло. Я тоже задал вопрос по этому поводу. Вот моя работа. stackoverflow.com/questions/24989221/ - person Amit Jayaswal; 28.07.2014
comment
Приведенный выше код идеально подходит для снятых фотографий. Есть идеи, как получить приемник для снятых видео? - person Shrikant; 03.11.2015
comment
Я использую камеру в своем приложении. Я получу тост, если пользователь сделал снимок (и был переведен на экран «Сохранить / Отменить»)? - person Harshit Gupta; 06.05.2016
comment
С android 7.0 это перестало работать :(. Есть ли какое-нибудь решение ?? - person Ujjwal; 16.05.2017

вы должны проверить здесь: ImageTableObserver и здесь PicasaPhotoUploader, как они это делают.

По сути, у них есть наблюдатель для Media.EXTERNAL_CONTENT_URI, который будет уведомлять обо всем, что происходит на SD-карте, а затем в Observer они проверяют, являются ли возвращенные данные фотографией.

camera = new ImageTableObserver(new Handler(), this, queue);
getContentResolver().registerContentObserver(Media.EXTERNAL_CONTENT_URI, true, camera);

По крайней мере, таким образом вам не нужно жестко кодировать каталог.

person Mortimer    schedule 03.09.2011

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

сначала создайте приемник для вашего события, скажем CameraEventReciver, и в этом случае вы можете реализовать свой код, я также даю вам путь к новому изображению, чтобы он был более полезен для вашего кода

    public class CameraEventReciver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {

    Cursor cursor = context.getContentResolver().query(intent.getData(),      null,null, null, null);
    cursor.moveToFirst();
    String image_path = cursor.getString(cursor.getColumnIndex("_data"));
    Toast.makeText(context, "New Photo is Saved as : -" + image_path, 1000).show();
      }
    }

А в Android Manifest вам просто нужно получить некоторые разрешения и зарегистрировать приемник с фильтром намерений и соответствующим действием для захвата изображения, а также включить Android-приемник.

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

   <receiver
        android:name="com.android.application.CameraEventReciver"
        android:enabled="true" >
        <intent-filter>
            <action android:name="com.android.camera.NEW_PICTURE" />
            <data android:mimeType="image/*" />
        </intent-filter>
    </receiver>
person tanay khandelwal    schedule 12.08.2013
comment
Я пробовал, но у меня не работает ... Вот мой вопрос, который я задал, пожалуйста, помогите мне. stackoverflow.com/questions/24989221/ - person Amit Jayaswal; 28.07.2014

Проблема в том, что вы поместили имя константы с пакетом в апострофы (в виде строки). Фактическая строковая константа имеет другое значение.

person ViliusK    schedule 26.12.2012