Calling the camera from another Activity [duplicate] - java

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 6 years ago.
I have my main Activity in which I have a few Buttons.
One of them is supposed to open the Camera.
To make it cleaner I am using View.onClick(), so I will just have the Button on the main Activity and the rest will be managed by another other class (Camactivity).
In my main Activity :
Button btnrep = (Button)findViewById(R.id.button3);
btnrep.setOnClickListener(new Camactivity(this));
and in my
public class Camactivity extends Activity implements View.OnClickListener
private File imageFile;
private Context appContext;
public MainActivity_1(Context context)
{
appContext = context;
}
#Override
public void onClick(View view) {
Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);//use intent and pass in mediastore
//mediastore is a databases where image and video are stores and link
imageFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "BreedingGround.bmp");
/*link to a directory - pass in directory where you want to save the pictures and names of the file*/
Uri tempuri = Uri.fromFile(imageFile);//Convert imageFile to a Uri
intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, tempuri);//location where u want the image file to be save after taking photo
intent.putExtra(android.provider.MediaStore.EXTRA_VIDEO_QUALITY, 1);//quality of out image, 1 means high quality image
startActivityForResult(intent, 0);//Request code 0 to identify who send the request
}
However I am getting a null pointer error at startActivityForResult(intent, 0);
FATAL EXCEPTION: main Process: com.example.mohit.softeng, PID: 22075
java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.pm.PackageManager android.content.Context.getPackageManager()' on a null object reference
at android.content.ContextWrapper.getPackageManager(ContextWrapper.java:97)
at com.example.mohit.softeng.MainActivity_1.onClick(MainActivity_1.java:60)
at android.view.View.performClick(View.java:5697)
at android.widget.TextView.performClick(TextView.java:10826)
at android.view.View$PerformClick.run(View.java:22526)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:158)
at android.app.ActivityThread.main(ActivityThread.java:7225)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)

You are more than welcome to define a View.OnClickListener subclass, but
there's really no reason I see to have Camactivity at all, so just implement View.OnClickListener onto MainActivity.
Besides, you will likely want the result from startActivityForResult within MainActivity's onActivityResult, not Camactivity.
So, with that suggestion
Button btnrep = (Button)findViewById(R.id.button3);
btnrep.setOnClickListener(this);
If you already have your Activity implementing an OnClickListener, then add an if-statement to check which button is clicked.
#Override
public void onClick(View view) {
switch (v.getId()) {
case R.id.button3:
openCamera();
}
}
private void openCamera() {
// That other code in Camactivity
}
Alternative answer... still not using new to make an Activity class.
Button btnrep = (Button)findViewById(R.id.button3);
btnrep.setOnClickListener(new View.onClickListener() {
#Override
public void onClick(View v) {
Intent cam = new Intent(MainActivity.this, Camactivity.class);
startActivityForResult(cam, 0); // If you need the result in MainAcivity, pass it back from camActivity
// else, just startActivity(cam);
}
});
Then, update Camactivity to start the camera intent as soon as it is created.
public class Camactivity extends Activity {
private File imageFile;
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);//use intent and pass in mediastore
//mediastore is a databases where image and video are stores and link
imageFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "BreedingGround.bmp");
/*link to a directory - pass in directory where you want to save the pictures and names of the file*/
Uri tempuri = Uri.fromFile(imageFile);//Convert imageFile to a Uri
intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, tempuri);//location where u want the image file to be save after taking photo
intent.putExtra(android.provider.MediaStore.EXTRA_VIDEO_QUALITY, 1);//quality of out image, 1 means high quality image
startActivityForResult(intent, 0);//Request code 0 to identify who send the request
}
#Override
public void onActivityResult (int requestCode, int resultCode, Intent data) {
if (requestCode == 0) {
// TODO: Handle camera intent result
}
}
}

Related

How do I create a new object on every button click?

I am creating a notes app, and I've all but finished it. My app starts on the main activity, which shows a recylcerView displaying all of the saved notes. To create a new note, you press a button, which sends you to another activity where you write your note. You then press a button that saves the note as an instance of the Note class and sends that object instance back to the main activity where it updates the recyclerView.
My problem is, every time I press the save button for my note, it just updates the Note instance instead of creating an entirely new one. How do I get it to create a new instance of the Note class so that I can have more than one saved note?
Here is my code for the save button:
Intent intent = new Intent(AddNoteActivity.this, MainActivity.class);
String mTitle = title.getText().toString();
String mContent = content.getText().toString();
intent.putExtra("notePar", new Note(mTitle, mContent));
startActivity(intent);
Here is my code for the mainactivity:
Intent intent = getIntent();
Note sentParcNote = intent.getParcelableExtra("notePar");
if(sentParcNote != null) {
notes.add(sentParcNote);
}
You are using startActivity(intent) to navigate from AddNoteActivity to MainActivity, this method is used to start a new activity, which means, the system will create a new instance of MainActivity class and put it at the top of the activity stack. This way you will always have 0 or 1 note (when sentParcNote != null)
I would suggest to use startActivityForResult when you navigate from MainActivity to AddNoteActivity and call setResult in your AddNoteActivity
Example:
MainActivity:
Declare this static int at the top of your class (e.g: just before onCreate method)
private static final int ADD_NOTE_ACTIVITY_REQUEST_CODE = 2;
Then add this piece of code on your button action to start AddNoteActivity:
Intent addNoteIntent = new Intent(this, AddNoteActivity.class);
startActivityForResult(addNoteIntent, ADD_NOTE_ACTIVITY_REQUEST_CODE);
Then to catch the new note from AddNoteActivity
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == ADD_NOTE_ACTIVITY_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
Note sentParcNote = data.getParcelableExtra("notePar");
if(sentParcNote != null) {
notes.add(sentParcNote);
}
}
}
}
AddNoteActivity:
add this piece of code to your save button action
String mTitle = title.getText().toString();
String mContent = content.getText().toString();
Intent intent = new Intent();
intent.putExtra("notePar", new Note(mTitle, mContent));
setResult(RESULT_OK, intent);
// finish closes the current activity which means in this case it goes back to the MainActivity
finish();
I would suggest using local storage to save your notes otherwise if you restart the app you will always have 0 notes.

How to move reusable functionalities to a generic class and invoke another activity from there?

I am new to Android development and I am facing an issue in invoking an activity from a generic class where I have a reusable function.
I have MainActivity where I need to check if the application has Network connectivity and then check if the user is already signed in.
If the user is signed in I need to open the Rate activity otherwise I will open the Login activity.
I thought I can keep the logic that checks the Network connectivity and shows the popup reusable and move it to a Global class as below
public class Global extends AppCompatActivity {
public static boolean hasConnectivity = false;
public static boolean userSignedIn = false;
String TAG = "Debug Log - Helper";
Context context;
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
context = this;
}
private void networkConnectionErrorDialog(final Context context, final Class targetClass){
Log.d(TAG, "Show Alert Dialog");
new AlertDialog.Builder(context)
.setTitle(R.string.connection_error_title)
.setMessage(R.string.connection_error_message)
.setIcon(R.drawable.warning)
.setPositiveButton(
R.string.try_again,
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Log.d(TAG, "Trying Again");
isNetworkAvailable(context, targetClass);
}
}).show();
}
protected void isNetworkAvailable(Context context, Class targetClass) {
if(NetworkUtil.isConnected(context)){
Log.d(TAG, "Has connectivity");
if(targetClass != null){
Log.d(TAG, targetClass.toString());
Intent targetIntent = new Intent(context, targetClass);
startActivity(targetIntent);
}
hasConnectivity = true;
return;
}else{
Log.d(TAG, "Has no connectivity");
hasConnectivity = false;
networkConnectionErrorDialog(context, targetClass);
}
}
}
I pass in the targetClass as Login.class or Rate.class (based on user signed in state) from the MainActivity where isNetworkAvailable() is invoked.
I am getting the following error. Could someone help me fix the issue and help me understand if my approach needs improvement?
java.lang.RuntimeException: Unable to resume activity {com.solitontech.dayatsoliton/com.solitontech.dayatsoliton.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.app.ActivityThread$ApplicationThread android.app.ActivityThread.getApplicationThread()' on a null object reference
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3581)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3621)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2862)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.app.ActivityThread$ApplicationThread android.app.ActivityThread.getApplicationThread()' on a null object reference
at android.app.Activity.startActivityForResult(Activity.java:4488)
at android.support.v4.app.BaseFragmentActivityJB.startActivityForResult(BaseFragmentActivityJB.java:50)
at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:79)
at android.app.Activity.startActivityForResult(Activity.java:4445)
at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:859)
at android.app.Activity.startActivity(Activity.java:4806)
at android.app.Activity.startActivity(Activity.java:4774)
at com.solitontech.dayatsoliton.Global.isNetworkAvailable(Global.java:50)
at com.solitontech.dayatsoliton.MainActivity.onResume(MainActivity.java:68)
at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1355)
at android.app.Activity.performResume(Activity.java:7117)
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3556)
It looks like your application is experiencing a null pointer exception in your activity's onResume method. If you had called startActivityForResult, make sure that the data in
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{..}
is non null before processing it.
As for your question about starting an activity from your helper class Global, you can define a function like this.
private static void goToActivity(Context context, Class<?> activityClass){
Intent intent = new Intent(context, activityClass);
context.startActivity(intent);
}
You can call this method as below.
goToActivity(context,TargetActivity.class);
Good luck.
Intent targetIntent = new Intent(context, targetClass);
startActivity(targetIntent);
above code is wrong. You should pass your current activity and target activity here.
Intent intent = new Intent(CurrentActivity.this, TargetingActivity.class);
startActivity(intent);
As a example :
If you want to start ActivtyB form ActivtyA
Intent intent = new Intent(ActivityA.this, ActivityD.class);
startActivity(intent);
1st try to correct this error. then you can find some others.

My application crashes when getting uri from user

I have a problem. I want to get the user of my app to select an audio file from storage using ACTION_GET_CONTENT, and my mainActivity crashes at that point.
public void onClick(View v) {
Intent intent = new Intent();
intent.setType("audio/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(intent,1);
audioPath = intent.getData().getPath(); //This is were the crash happens
audio = Uri.parse(audioPath);
}
I'm new in android programming and there is surely something that I fail to understand. The error is as follows: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.net.Uri.getPath()' on a null object reference
You have to override on Activity Result in your activity. DO NOT use the same intent like you have done. You have to use the Intent returned in onActivityResult method. So your code should be:
This should be your method to Pick an Audio
public void onClick(View v) {
Intent intent = new Intent();
intent.setType("audio/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(intent,1); //This 1 is your request code remember it
}
Then Override the onActivityResult method as
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
//The intent from this method is the one you need to get data from!
if (requestCode == 1) {
// Make sure the request was successful
if (resultCode == RESULT_OK) {
audioPath = intent.getData().getPath();
audio = Uri.parse(audioPath);
}
}
}
For more information on this method and receiving data from Activity Result check this official training from Android. Happy Coding!

Back to previous activity in android

I have Activity A, B and C. In Activity C, it has an image and caption. The image and caption will be return to B when ok button is clicked. In activity b, it will return both to activity A.
Activity C
ok.setOnClickListener(new View.OnClickListener() // ok button to return image and caption to B
{
public void onClick(View arg0)
{
Intent returnIntent=new Intent();
text=t.getText().toString();
b.setDrawingCacheEnabled(true);
b.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
b.layout(0, 0, b.getMeasuredWidth(), b.getMeasuredHeight());
b.buildDrawingCache(true);
returnIntent.putExtra("text", text);
if (b.getDrawingCache() != null) {
Bitmap bitmap = Bitmap.createBitmap(b.getDrawingCache());
if (bitmap == null) {
Log.e("TAG", "getDrawingCache() == null");
}
Global.img = bitmap;
}
setResult(Activity.RESULT_OK, returnIntent);
finish();
}
});
Activity B
public void onActivityResult(int requestCode,int resultCode, Intent data)
{
if(requestCode==PROJECT_REQUEST_CODE) {
if(data!=null&&data.hasExtra("text")) {
c = data.getStringExtra("text");
txt1.setText(c); // caption can show in txt1
viewImage.setImageBitmap(Global.img); // image from C can show in viewImage
}
}
else if (requestCode==CAMERA_REQUEST_CODE)
{
}
}
b.setOnClickListener(new View.OnClickListener() { // button to return image and caption to A
public void onClick(View arg0) {
Intent returnIntent = new Intent();
returnIntent.putExtra("c",c); // return caption
returnIntent.putExtra("globalImg",Global.img);
setResult(Activity.RESULT_OK, returnIntent);
finish();
}
});
Activity A
public void onActivityResult(int requestCode, int resultCode, Intent data) {
Bitmap b = Global.img
if (requestCode==1) {
caption = data.getStringExtra("c"); // caption from A
v.setImageBitmap(Global.img) // image from C
}else if {.....}
}
Global.java
public class Global {
static Bitmap img;
}
When I click button b in Activity B, I get this
11-05 17:26:47.114 6031-6031/com.example.project.project
E/JavaBinder﹕ !!! FAILED BINDER TRANSACTION !!!
Provided what you are trying to do is simply to pass along the data returned from C->B on to A, why don't you just get the string again in your onClick and put it into your intent?
You could store the text in a String member, or, as the code looks now, even get it back from the TextView:
Intent returnIntent = new Intent();
returnIntent.putExtra("text", txt1.getText().toString);
setResult(Activity.RESULT_OK, returnIntent);
The image is being stored as a static in a global object, which honestly is horrible, but you could of course access that as well from your onClickListener. You should however seriously consider returning the bitmap data in some other way, the most straightforward probably being utilizing that Bitmaps implement the Parcelable interface, and Intents can hold Parcelables as extras, so in theory you can just do putExtra("img", bitmap) and on the receiving end do intent.getParcelableExtra("img").
However, if the bitmap is large this might fail, and it might be better to store the bitmap to a resource such as a file, and pass the location of the file instead. You may also get a way with something like what you did with your static member in the Global class, but 1) you must be careful to remove the object after passing it back or the static reference will waste memory and 2) make sure you don't use this reference incorrectly, e.g. from multiple places simulatenously. A more robust solution is to make sure you create a unique ID for each bitmap and store it in a cache (for example a HashMap with the Bitmaps hashCode() as the key) and identify it by id.
public class BitmapStore {
private static final HashMap<Integer, Bitmap> BITMAPS= new HashMap<>();
public static Bitmap getBitmap(int id) {
return BITMAPS.remove(id);
}
public static int putBitmap(Bitmap b) {
int id = b.hashCode();
BITMAPS.put(id, b);
return id;
}
}
Using this, you could put the ID of your bitmap in your intent:
intent.putExtra("imageId", BitmapStore.putBitmap(bitmap));
setResult(RESULT_OK, intent);
and in onActivityResult:
Bitmap b = BitmapStore.getBitmap(intent.getIntExtra("imageId", 0));
This bitmap store is not persistant but it should be pretty safe to use as an intermediate store in the transition between two activities. It's also possible to generalize to any kind of object implementing a valid hashCode/equals contract.
try comment this line:
//returnIntent.putExtra("globalImg",Global.img);
in your Activity B
You can use Global.img for all Activity and not use intent
Added:
v.setImageBitmap(Global.img); -> nullPointerExeption becouse v is not initialize
Added:
BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
bitmapOptions.inJustDecodeBounds = false;
bitmapOptions.inPreferredConfig = Config.RGB_565;
bitmapOptions.inDither = true;
For "Out of memory" error.

How do I access the camera on Android phones?

I've written a program in Java that takes in an image file and manipulates the image. Now I'm trying to access the camera so that I can take the photo and give it to the image processing program however I'm lost as to how to do this. I've read the information about the camera class and how to ask for permissions but I don't know how to actually take the photo. If anyone has any tips on where I should begin or if they know of a good tutorial I'd really appreciate it. Thanks!
Google is your best friend, here are some tutorials:
Using the camera
How-To Program The Google Android Camera To Take Pictures
Take Picture from Camera Emulator
camera
First edit your AndroidManifest.xml, add the camera permission:
<uses-permission android:name=”android.permission.CAMERA”/>
Camera service has to be opened and closed:
Camera camera = Camera.open();
//Do things with the camera
camera.release();
You can set camera settings, e.g.:
Camera.Parameters parameters = camera.getParameters();
parameters.setPictureFormat(PixelFormat.JPEG);
camera.setParameters(parameters);
To take a picture:
private void takePicture() {
camera.takePicture(shutterCallback, rawCallback, jpegCallback);
}
ShutterCallback shutterCallback = new ShutterCallback() {
public void onShutter() {
// TODO Do something when the shutter closes.
}
};
PictureCallback rawCallback = new PictureCallback() {
public void onPictureTaken(byte[] _data, Camera _camera) {
// TODO Do something with the image RAW data.
}
};
PictureCallback jpegCallback = new PictureCallback() {
public void onPictureTaken(byte[] _data, Camera _camera) {
// TODO Do something with the image JPEG data.
}
};
Do not forget to add the camera layout to your main layout xml.
there are many ways by which u can do this....
One of the better way which i think is the short and simple is to on Button Click u can call intent which opens ur inbuilt camera view... here is the sample code...
public class CameraDemo extends Activity {
Button ButtonClick;
int CAMERA_PIC_REQUEST = 2;
int TAKE_PICTURE=0;
Camera camera;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ButtonClick =(Button) findViewById(R.id.Camera);
ButtonClick.setOnClickListener(new OnClickListener (){
#Override
public void onClick(View view)
{
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, CAMERA_PIC_REQUEST);
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if( requestCode == CAMERA_PIC_REQUEST)
{
Bitmap thumbnail = (Bitmap) data.getExtras().get("data");
ImageView image =(ImageView) findViewById(R.id.PhotoCaptured);
image.setImageBitmap(thumbnail);
}
else
{
Toast.makeText(demo.this, "Picture NOt taken", Toast.LENGTH_LONG);
}
}
}
..............................................................
Go through it and, if u have any problem feel free to ask....
rakesh
There are two methods to take photo for your android application
1)Using Intent
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE); // create a file to save the image
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); // set the image file name
// start the image capture Intent
startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
2) Creating a customized camera activity. For that you need following steps
* Detect and Access Camera
* Create a Preview Class
* Build a Preview Layout
* Capture and Save Files
* Release the Camera
You may also refer the following links:
http://developer.android.com/guide/topics/media/camera.html
http://developer.android.com/reference/android/hardware/Camera.html
the most important method is:
Camera.PictureCallback mPictureCallback = new Camera.PictureCallback() {
public void onPictureTaken(byte[] imageData, Camera c) {
}
};
This method is called when a picture is taken.
Here is a good tutorial on this topic: http://www.brighthub.com/mobile/google-android/articles/43414.aspx
hmm... or maybe you need this one:
Camera mCamera;
...
public void onClick(View arg0) {
mCamera.takePicture(null, mPictureCallback, mPictureCallback);
}
Here is one more example: http://snippets.dzone.com/posts/show/8683

Categories