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

发布于 2024-10-10 12:03:52 字数 962 浏览 0 评论 0原文

我正在尝试制作一个应用程序来检测用户何时拍照。我设置了一个广播接收器类并将其注册在清单文件中:

<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 窗口。我以正确的方式处理这个问题吗?有什么我需要补充的吗?

I'm trying to make an app that detects when a user takes a photo. I set up a broadcast receiver class and registered it in the manifest file by:

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

No matter what I try to do the program won't receive the broadcast. Here is my receiver class:

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

If I remove the mimeType line in the manifest and in my activity I send my own broadcast using

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

then I successfully receive the broadcast and can see the log and toast window. Am I approaching this the right way? Is there any thing that I need to add?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

风吹过旳痕迹 2024-10-17 12:03:52

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

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

I solved this but by using a different method. Instead of using a broadcast receiver I set up a fileobserver on separate folders that the camera saved to. It's not as practical as the other way, but it still works fine. Here's how I set it up:

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
泡沫很甜 2024-10-17 12:03:52

我确信这种方法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>

最后,您创建一个从 BroadcastReceiver 扩展的名为“CameraReciver.java”的类
这是我的代码:

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”(上面回答)如何获取相机拍摄的新照片的路径^_^

希望对大家有帮助

I sure this way works 100% . I tested carefully.

Register your broadcast receiver in AndroidManifest. Most of answers above miss
"category android:name="android.intent.category.DEFAULT" . BroadcastReceiver can't start without this

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

And finally, you create a class named "CameraReciver.java" extend from BroadcastReceiver
and this my code :

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



}

After that, deploy your project to Emulator ( I use genymotion),of course nothing happened because your BroadCastReceiver works without GUI. Let you open camera app, and click capture button. If everything OK, you'll get a toast with content like "New Photo is Saved as : storage/emulated/0/DCIM/Camera/IMG_20140308.jpg". Let enjoy ^_^

Thanks "tanay khandelwal" (answered above) for how to get the path of new Photo captured by camera ^_^

Hope to help everyone

挽手叙旧 2024-10-17 12:03:52

你应该在这里查看:
ImageTableObserver 和此处 PicasaPhotoUploader
他们是如何做到的。

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

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

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

you should check out here:
ImageTableObserver and here PicasaPhotoUploader
how they do it.

Basically, they have an observer for Media.EXTERNAL_CONTENT_URI that will notify of whatever happens on the SD card, then in the Observer, they check if the data returned is a photo.

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

At least this way you don't have to hardcode the directory.

感性不性感 2024-10-17 12:03:52

你好,朋友们,我也尝试实现一些关于捕获事件的任务,经过研究和处理后,我准备了这段代码,该代码运行良好,因此它可以帮助您

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

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

Hello friends I was also trying to implement some task on capture event and after studying and working on it I prepared this code which is working fine so it may help you

first create a receiver for your event say CameraEventReciver and in that you can implement your code I m also giving you the path of the new image so it will be more useful to you for your code

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

And in Android Manifest you just have to take some permissions and register your reciever with intent filter and appropriate action for image capture also make your receiver android enabled

  <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>
撩心不撩汉 2024-10-17 12:03:52

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

The issue is that, you've put the constant name with package into apostrophes (as string). The actual string constant has different value.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文