广播接收器不会收到相机事件

Posted

技术标签:

【中文标题】广播接收器不会收到相机事件【英文标题】:broadcast receiver won't receive camera event 【发布时间】:2011-06-02 01:40:59 【问题描述】:

我正在尝试制作一个可以检测用户何时拍照的应用。我设置了一个广播接收器类并通过以下方式将其注册到清单文件中:

<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);

然后我成功接收到广播并且可以看到日志和 toast 窗口。我以正确的方式接近这个吗?有什么需要补充的吗?

【问题讨论】:

你从哪里得到com.android.camera.NEW_PICTURE?快速浏览 sdk 后,我可以判断,该操作不存在。 @sugarynugs 我在其他一些线程上找到了它。这是其中之一,显然它来自相机的来源。 ***.com/questions/3015448/…,拍照时调用 sendBroadcast(new Intent("com.android.camera.NEW_PICTURE", mLastContentUri)); 你在哪个版本的 android 上测试这个? @sugarynugs 我正在使用 Froyo(2.2) 在我的 HTC Evo 上对其进行测试。我还在 2.2 的模拟器上测试了它,但没有运气。我一直在尝试很多不同的事情,比如以编程方式注册接收器,但仍然没有运气。您是否知道我可以通过其他方式跟踪在背景中拍摄照片的时间?我希望我的应用程序留在后台并监听事件。我唯一能想到的另一件事是设置一个媒体存储接收器并监听从相机保存的图像,但这会更麻烦!感谢您迄今为止的帮助! @sugarynugs 另外,我想知道 HTC 的 Sense 是否可以以某种方式改变相机的广播方式,但即使是这种情况,它也应该在模拟器上工作。只是一个想法。 【参考方案1】:

我解决了这个问题,但使用了不同的方法。我没有使用广播接收器,而是在相机保存到的单独文件夹上设置了一个文件观察器。它不像其他方式那样实用,但它仍然可以正常工作。以下是我的设置方式:

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

【讨论】:

不错!很高兴见到能独立思考的人;D。我正在查看相机源,ImageCapture 类中的方法storeImage 负责触发该意图。该方法仅在!mIsImageCaptureIntent 时触发意图。我没有进一步看,但我认为这意味着,如果由于意图而没有发生图像捕获,请执行以下操作。不确定您是如何拍照的,以及相机应用程序是否使用意图拍照但值得深思。 这个解决方案的问题是应用程序必须一直在后台运行才能观察文件系统。主要问题,打得不好。 您可以使用此解决方案来监控多个文件夹,还是必须为您希望观察的每个文件夹创建单独的 FileObserver? 您必须为要监控的每个文件夹创建一个观察者。 晚了 2 年,但我尝试了下面 Tanay 给出的解决方案,它实际上适用于图像捕捉!对我为什么不应该使用它有任何异议吗?【参考方案2】:

我确信这种方法 100% 有效。我仔细测试过。

在 AndroidManifest 中注册您的广播接收器。上面的大多数答案都错过了 "category 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 无需 GUI 即可工作。让您打开相机应用程序,然后单击捕获按钮。如果一切正常,您将获得一个内容,如“新照片另存为:storage/emulated/0/DCIM/Camera/IMG_20140308.jpg”。尽情享受吧^_^

感谢“tanay khandelwal”(上面已回答)如何获取相机拍摄的新照片的路径^_^

希望对大家有所帮助

【讨论】:

我试过了,但没有帮助。我也问过这个问题。这是我的工作。 ***.com/questions/24989221/… 以上代码非常适合拍摄的照片,知道我们如何获得拍摄视频的接收器吗? 我在我的应用程序中使用相机。如果用户已拍照(并已被带到保存/丢弃屏幕),我会得到烤面包吗? 从 android 7.0 开始,这已经停止工作 :( 。有什么解决方法吗??【参考方案3】:

您应该在这里查看: ImageTableObserver 和这里PicasaPhotoUploader 他们是怎么做到的。

基本上,他们有一个Media.EXTERNAL_CONTENT_URI 的观察者,它将通知 SD 卡上发生的任何事情,然后在观察者中,他们检查返回的数据是否是照片。

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

至少这样您不必对目录进行硬编码。

【讨论】:

【参考方案4】:

朋友们好,我也在尝试实现一些关于捕获事件的任务,经过研究和工作,我准备了这段代码,它运行良好,所以它可以帮助你

首先为您的事件创建一个接收器,例如 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 中,您只需要获取一些权限并使用 Intent 过滤器注册您的接收器,并为图像捕获采取适当的操作也使您的接收器启用 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>

【讨论】:

我试过了,但对我不起作用......这是我问的问题,请帮助我。 ***.com/questions/24989221/…【参考方案5】:

问题在于,您已将带有包的常量名称放入撇号(作为字符串)。实际的字符串常量有不同的值。

【讨论】:

以上是关于广播接收器不会收到相机事件的主要内容,如果未能解决你的问题,请参考以下文章

ACTION_CAMERA_BUTTON 的广播接收器永远不会被调用

Android 基础知识 -- BroadcastReceiver

Android广播:Broadcast与BroadcastReceiver

Android广播:Broadcast与BroadcastReceiver

广播接收器——接收系统广播

Android系统广播(Broadcast)注册,发送,接收流程解析