Can anybody help me please? My question is that how to to display popup message on camera image capture using broadcast receiver.
I have register Receiver but it is not working.
Receiver class:
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,Toast.LENGTH_LONG).show();
}
}
Manifest file:
<receiver
android:name="com.example.abdullahnawaz.mycamera.CameraReciver"
android:enabled="true" >
<intent-filter>
<action android:name="com.android.camera.NEW_PICTURE" />
<data android:mimeType="image/*" />
<action android:name="android.intent.action.CAMERA_BUTTON" />
</intent-filter>
</receiver>
Starting from Android 7.0, please use JobInfo.Builder.addTriggerContentUri().
For older devices, you can listen to the ACTION_NEW_PICTURE or ACTION_NEW_VIDEO broadcast. These broadcasts are no long sent on 7.0 and above.
Related
I am trying to "listen" when a user take picture using the default camera app. I used the broadcast receiver solution as below
Manifest:
<receiver
android:name=".CameraEventReceiver"
android:enabled="true" >
<intent-filter>
<action android:name="com.android.camera.NEW_PICTURE" />
<action android:name="android.hardware.action.NEW_PICTURE" />
<data android:mimeType="image/*" />
</intent-filter>
</receiver>
The receiver:
public class CameraEventReceiver 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, Toast.LENGTH_SHORT).show();
Intent i = new Intent(context, MyAct.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
The problem is that the event is fired multiple times (twice). My breakpoint at where context.startActivity(i) is called twice and both with the action android.hardware.action.NEW_PICTURE.
Any reason why this is happening or how to prevent it?
Thank you
The stock Camera app on KitKat send both android.hardware.action.NEW_PICTURE and com.android.camera.NEW_PICTURE broadcasts (don't know for older versions), that may be why your receiver is notified twice.
If your app is only for ICS+ you can remove com.android.camera.NEW_PICTURE from your intent filter as it is not documented.
If you still want to handle this, your receiver should implement some logic to know the intent has already been handled for the data it receives. This logic depends on your application and what you do with the received data.
i try catch a call from standard dialpad using that code:
<action android:name="android.intent.action.CALL" />
<data android:scheme="tel" />
<category android:name="android.intent.category.DEFAULT" />
<action android:name="android.intent.action.CALL_PRIVILEGED" />
</intent-filter>
</activity>
Everything fine, when user dial from standard phone dialpad, my app opened.
But i don't find solution, how i can get a phone number, which user was dialed. That code inside PhonePadActivity activity onCreate block:
Intent intent = getIntent();
String number = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
Toast.makeText(this, "Call was made to-->>" + number, 5000).show();
gives me a null finally :(
tried to using brodacast receiver:
in manifest:
<receiver
android:exported="true"
android:name="com.myapps.android.DialBroadcastReceiver" >
<intent-filter >
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
</intent-filter>
</receiver>
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
this is class DialBroadcastReceiver:
package com.myapps.android;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
public class DialBroadcastReceiver extends BroadcastReceiver {
private static final String THIS_FILE = "PhonePadActivity";
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
Log.e(THIS_FILE,"In onReceive()");
if (intent.getAction().equals(Intent.ACTION_NEW_OUTGOING_CALL)) {
String number = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
Log.e(THIS_FILE,"Number is: "+number);
}
}
}
but logs nod fired, when user press dial
This works for me:
In Manifest:
<intent-filter>
<action android:name="android.intent.action.CALL"/>
<category android:name="android.intent.category.DEFAULT"/>
<action android:name="android.intent.action.CALL_PRIVILEGED"/>
<data android:scheme="tel"/>
</intent-filter>
In Activity:
String inputURI = this.getIntent().getDataString();
if (inputURI != null) {
Uri uri = Uri.parse(Uri.decode(inputURI));
if (uri.getScheme().equals("tel")) {
String calledNumber = uri.toString();
}
}
You are getting the number with incorrect code. Replace:
Intent intent = getIntent();
String number = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
Toast.makeText(this, "Call was made to-->>" + number, 5000).show();
With:
Uri data = getIntent().getData();
if (data != null && ("tel".equals(data.getScheme()))) {
String number = PhoneNumberUtils.getNumberFromIntent(getIntent(), this);
if (number != null) {
Toast.makeText(this, "Call was made to-->>" + number, 5000).show();
}
}
Add <intent-filter android:priority="9999"> to the intent-filter declaration in the manifest, to make sure you're first in line
Remove the com.myapps.android-part from the android:name property of the receiver declaration in the manifest (i.e. it should be: android:name=".DialBroadcastReceiver")
Register a BroadcastReceiver like this in Manifest file:
<!-- DIAL Receiver -->
<receiver
android:exported="true"
android:name="receivers.DialBroadcastReceiver" >
<intent-filter >
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
</intent-filter>
</receiver>
You need Permission for NEW_OUTGOING_CALL :
Eventually you can Receive the broadcast and retrieve the dialed number like this:
public class DialBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.v("DileBroadCastReceiver","In onReceive()");
if (intent.getAction().equals(Intent.ACTION_NEW_OUTGOING_CALL)) {
String number = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
Log.v("DialBroadcast Receiver","Number is: "+number);
}
}
}
I want to make an application in which once the application starts, it will show two button(start and stop button) and once the user clicks the start button the call function will be blocked for the time period till the user again start the application and click the stop button to stop this function. any help please its urgent
in short I Will tell I want to block the outgoing call from my phone by using this activity only
please is there any way to do so???
You can block the outgoing call using the setResultData(null) function in the onReceive method of the Broaadcast receiver.
public class BlockOutgoing extends BroadcastReceiver
{
String number;
#Override
public void onReceive(Context context, Intent intent)
{
Log.d("12280", "asdasNumber is-->> " + number);
number = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
setResultData(null);
Toast.makeText(context, "Outgoing Call Blocked" , 5000).show();
}
}
In the manifest file, you need to register the receiver like this,
<receiver
android:name=".BlockOutgoing"
android:label="#string/app_name" >
<intent-filter android:priority="1">
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
</intent-filter>
</receiver>
Also define the permission to intercept the outgoing call,
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
Edit-
To unregister a broadcast receiver, follow this link
public class BlockOutgoing extends BroadcastReceiver {
String number;
#SuppressLint("WrongConstant")
#Override
public void onReceive(Context context, Intent intent)
{
// Log.d("12280", "asdasNumber is-->> " + number);
number = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
setResultData(null);
Toast.makeText(context, "Outgoing Call Blocked" , 5000).show();
}
}
<receiver
android:name=".BlockOutgoing"
android:label="#string/app_name" >
<intent-filter android:priority="1">
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
</intent-filter>
</receiver>
I saw many posts in StackOverflow regarding how to listen to camera events, and got few information but still there are few questions remain in my mind please let me know the answers for these:
I have an application which have a broadcast receiver and my broadcast receiver will lauch my activity, but the main purpose of having broadcast receiver is to listen to camera photo/video capture intent.
I want to know which is the intent i have to listen for this, and is it possible to do in this way.
thanks
For Receiving camera photo capture intent, try following code
public class CameraEventReciver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "New Photo Clicked", Toast.LENGTH_LONG).show();
}
and in manifest, register the receiver:-
<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>
In your Android Manifest, you need to specify which intents you want to receive. For camera that'd be the following code (this goes within the <application> tags):
<receiver android:name="com.receiver.CameraReceiver">
<intent-filter android:priority="10000">
<action android:name="android.intent.action.CAMERA_BUTTON" />
</intent-filter>
</receiver>
In addition to that, you should add this to your <intent-filter> within the <activity> tags:
<category android:name="android.intent.category.DEFAULT" />
Finally, take care of the event in your activity's code like so:
#Override
public void onReceive(Context context, Intent intent) {
abortBroadcast();
//TODO: your code here
}
You can use thread that will control your directory camera like:
FileObserver observer =new FileObserver("/mnt/extSd/DCIM/Camera/"){
#Override
public void onEvent(int event, String file) {
// TODO Auto-generated method stub
if(event == FileObserver.CREATE ){
//Do Some things With The file
}
}};
} catch (FileNotFoundException e) {
e.printStackTrace();
}
observer.startWatching();
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?
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
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
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.
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>
The issue is that, you've put the constant name with package into apostrophes (as string). The actual string constant has different value.