Android call cameraApp from non-activity class issue - java

Though I found several similar answered questions, I couldn't solve my problem:
I use Fragment oFragment from where I want to call the Camera as a new Activity. Therefore I created a non-activity class Camera. When running I get the error:
java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.pm.PackageManager android.app.Activity.getPackageManager()' on a null object reference
oFragment is placed in a FrameLayout in MainActivity. I also tried the constructor of Camera with Context context.
Do you see any workarounds or mistakes? Thanks in advance!
Edit: The code works fine if implemented directly into oFragment.
Class Camera:
public class Camera {
static final int REQUEST_IMAGE_CAPTURE = 1;
Activity activity;
public Camera(Activity activity) {
this.activity = activity;
}
public void dispatchTakePictureIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(activity.getPackageManager()) != null) {
activity.startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
Snipped from oFragment:
public class OFragment extends Fragment {
Camera cam = new Camera(getActivity());
...
#Override
public void onClick(View v) {
cam.dispatchTakePictureIntent();
}

I just solved it. I had to add the line super(); to my constructer and it works fine!

Related

Call activity A method from Activity B Android

I'm a new to java and android. I was working on my own app but I'm having a problem in passing a method from Activity A to Activity B.
Here is what I did :
ActivityA has Demo() method.
public class ActivityA extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
protected void demo() {
// Do something
}
}
I created the below class to access the method of ActivityA to ActivityB:
public class External {
private ActivityA activitya;
private static External instance = null;
public External(ActivityA activitya) {
this.activitya = activitya;
}
static public External getInstance(ActivityA activitya) {
if (instance == null) {
instance = new MyntraExternal(activitya);
return instance;
} else {
return instance;
}
}
}
Now how can I proceed further? I'm having lots of problem in getting the method which is in ActivityA from ActivityB.
Please anybody help.
Edit :
ActivityB is my launcher class and I want some access from ActivityA's method in ActivityB. What to do ?
Since you are new to Android, I will tell you it's a bad practice call methods from Activity A to B or vice versa, you can pass parameters from one activity to another using intents and bundles and if you need to pass parameters from the second activity to the first you need to use the override method onActivityResults
Here are some usefull link about passing parameters from one activity to another:
https://www.dev2qa.com/passing-data-between-activities-android-tutorial/
In this link you can see a example of how things work.
Hope it helps.
--EDIT (if you need to call a function from B to A in case you want to change something in A upon creation this is the best and simplest way to do it):
In Activity B:
Intent intent = new Intent(this, ActivityA.class);
intent.putExtra("Work","doJump");
startActivity(intent);
In Activity A:
onCreate:
String extra = getIntent().getStringExtra("Work");
if(extra != null && extra.equals("doJump")){
jump();
}
make that method public and static and then access it using class name. e.g. In your 2nd activity, use ActivityB.demo()
Try using startActivityForResult
To start activity B from activity A
startActivityForResult(intent, SOME_CODE)
And to be called back on result you will need to add the following code the also in activity A
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
when(code){
SOME_CODE -> if (resultCode == Activity.RESULT_OK) doSomething()
}
}
To tell Activity A to call the method, in activity B you can say:
setResult(Activity.RESULT_OK)
finish()
After B is finished, onActivityResult in A will be executed
To go back to A without executing the "doSomething()" method,
setResult(Activity.RESULT_CANCELED)
finish()
Please try this way
public class ActivityA extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void demo() {
// Do something
}
}
public class ActivityB extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ActivityA activityA = new ActivityA(); // create object
activityA.demo(); //
}
}

Pass the context from a fragment inside an activity to another class

I have a fragment which is instantiated by an Activity. The issue that I'm having is that I have another class in the fragment which takes as a parameter an Activity context.
public class LocationQueries {
Activity context;
private static int REQUEST_CODE_RECOVER_PLAY_SERVICES = 200;
public LocationQueries(Activity context) {
this.context = context;
}
public boolean checkGooglePlayServices() {
int checkGooglePlayServices = GooglePlayServicesUtil
.isGooglePlayServicesAvailable(context);
if (checkGooglePlayServices != ConnectionResult.SUCCESS) {
/*
* google play services is missing or update is required
* return code could be
* SUCCESS,
* SERVICE_MISSING, SERVICE_VERSION_UPDATE_REQUIRED,
* SERVICE_DISABLED, SERVICE_INVALID.
*/
GooglePlayServicesUtil.getErrorDialog(checkGooglePlayServices,
context, REQUEST_CODE_RECOVER_PLAY_SERVICES).show();
return false;
}
return true;
}
}
I instantiate that class in my fragment like this
private LocationQueries locationQueries = new LocationQueries(getActivity());
but when I try to use locationQueries.checkGooglePlayServices();
I get Caused by: java.lang.NullPointerException: Attempt to invoke virtual method android.content.pm.PackageManager android.content.Context.getPackageManager() on a null object reference.
It looks like the LocationQueries(getActivity()) doesn't actually pass the activity context. How can I solve this ?
Edit: Everything is working if I do the same from an Activity -> LocationQueries(this);
It seems that you initiate LocationQueries at the wrong place. Indeed, I assume this:
private LocationQueries locationQueries = new LocationQueries(getActivity());
is called as a global variable in your Fragment class.
Instead you should keep your variable as global but set it into onCreate() or onResume(), as follows:
private class Frag extends Fragment {
private LocationQueries locationQueries;
...
#Override
public void onCreate(Bundle inState) {
locationQueries = new LocationQueries(getActivity());
}
}
Your Fragment appears not to be attached to an Activity.
I suspect you have instantiated your LocationQueries object before onAttach(Activity activity) has been called, or after onDetach() has been called on your Fragment.
In such a case, calling getActivity() will return null which is what you then pass to your LocationQueries object resulting in the NPE.

startActivity from a custom class

I have a menu and 5 activities. To avoid repeating the menu code, I have created a public class and call it in every activity:
Testclass testclass = new Testclass(Main.this);
...but unfortunately I can't use startActivity() in the class. This is my class code:
public class Testclass extends Activity {
public Testclass(Activity cc) {
Intent intent = new Intent(cc,Next.class);
startActivity(intent);
}
}
Try this and tell me if it helped you.
public class Testclass extends Activity {
public Testclass(Activity cc) {
final Context context = Testclass.this.getContext();
Intent intent = new Intent(context , Next.class);
context.startActivity(intent);
}
}
You misunderstood the concept of an Activity and its life cycle. You DON'T instantiate the Activity, the Activity has callback mechanisms (onCreate, onResume, etc.) that tell you exactly what to do. You never ever have to call new Activity().
The fact that you're doing
Testclass testclass = new Testclass(Main.this); shows that you have a misunderstanding of this concept: http://developer.android.com/training/basics/activity-lifecycle/index.html
To fix your error, read the docs and then it will be clear what is wrong with your approach.
Hint: Your Testclass already IS an Activity, because you inherit from Activity.
And next time please provide the whole error log to your problem, so it can give the whole picture of what can be wrong with your code.
Why not use this code?
startActivity(new Intent(Main.this, Next.class));
// "Main" is your current Activity
// "Next" is your next Activity to be opened.
I think, it's very simple to use without create a new public class. Please compare your codes with my code above, only one line.
I think you don't use the correct Context to start the Intent.
Instead try
{
public Testclass() {
Intent intent = new Intent(this,Next.class);
startActivity(intent);
}
}
if the this doesn't work either, try getApplicationContext() instead.
#you can used Weak Reference Objects to store Context of Activity class#
##in activity class##
public class Activity extends AppCompatActivity implements View.OnClickListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_view);
findViewById(R.id.toNext).setOnClickListener(this);
}
#Override
public void onClick(View v) {
Testclass thread = new Testclass(Activity.this,v);
new Thread(thread).start();
}
}
}
// in sub class
public class Testclass extends Activity implements Runnable {
View landingPage;
private Activity activity;
public Testclass (Activity activity, View landingPage){
WeakReference<Activity> ActivityWeakReference = new WeakReference<>(Activity);
this.landingPage = landingPage;
this.activity = activityWeakReference.get();
}
#Override
public void run() {
Intent activityIntent = new Intent(activity, Next.class);
activityIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
runOnUiThread(new Runnable() {
#Override
public void run() {
switch (landingPage.getId())
{
case R.id.Next.class:
activity.finish();
activity.startActivity(activityIntent);
break;
}
}
});
}
}

Refreshing parent activity from child?

guys, I'm pretty new to java android programming (that's the first app I'm making) and I have this question:
How can i refresh my Main Activity from another activity, which is called from the Main one?
I would also appreciate if you give me some examples, because I'm still not very orientated...
You can use startActivityForResult() for that purpose, instead of context.startActivity() call context.startActivityForResult() and then set result in launched activity before finishing it.
Here is the documentation for Context.startActivityForResult()
Sample code:
// Activity A
public class ActivityA extends Activity {
private static final int REQUEST_CODE_ACTIVITY_B_FOR_RESULT = 1; // or other int value
// sample code which starts Activity B
private void onSomeButtonClick() {
Intent intent = new Intent(this, ActivityB.class);
startActivityForResult(intent, REQUEST_CODE_ACTIVITY_B_FOR_RESULT);
}
// this method will be called when started activity finished
// and returned some result of its work
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent resultData) {
super.onActivityResult(requestCode, resultCode, resultData);
if (requestCode == REQUEST_CODE_ACTIVITY_B_FOR_RESULT) {
if (resultCode == RESULT_OK) {
// handle result ok and resultData here
} else {
// handle result canceled or other resultCode and its resultData here
}
}
}
}
// Activity B
public class ActivityB extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setResult(RESULT_CANCELED); // by default result of starting activity is negative
}
// some code which doing some action and setting result as ok
private void doSomething() {
Intent resultData = new Intent();
resultData.putExtra("SOME_EXTRA", "did it"); // or other result data
setResult(RESULT_OK, resultData);
finish(); // finishing this activity, result code and result data will be accessible in previous activity
}
}
How to call main activity from the sub activity. Use an interface.
1. Creata a public interface in the sub-activity
public class MapSettings extends DialogFragment implements
OnCheckedChangeListener {
public interface BestRidesSettingsDialogListener {
void onMapSettingsChange(int mapType);
}
2. Implement the interface in the main activity note right click on errors and select add imports add reference add unimplemented methods.
public class KmlReader extends ActionBarActivity implements
BestRidesSettingsDialogListener {
3. when the sub activity starts in the sub activity cast getActivity to the public interface
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// the activity may be null if this is called without implementing the
// BestRidesSettingsDialogListener (The settings object saves the
// setting so the
// call back may not be needed.
activity = (BestRidesSettingsDialogListener) getActivity();
4. Then in the sub activity when a button is clicked or some event happens call through to the interface method.
#Override
public void onCheckedChanged(RadioGroup rg, int checkId) {
// TODO Auto-generated method stub
int mapType = 0;
switch (checkId) {
case R.id.RDORoad:
mapType = GoogleMap.MAP_TYPE_NORMAL;
break;
case R.id.RDOHybrid:
mapType = GoogleMap.MAP_TYPE_HYBRID;
break;
case R.id.RDOSatelite:
mapType = GoogleMap.MAP_TYPE_SATELLITE;
break;
case R.id.RDOTerrain:
mapType = GoogleMap.MAP_TYPE_TERRAIN;
break;
}
// run the activity onchange
// if the activity is null there is no listener to take action on the
// settings
if (activity != null) {
activity.onMapSettingsChange(mapType);
}
5. if you've filled in the unimplemented methods stubs in your main activity your executing code directly in the main activity from the sub activity.
#Override
public void onMapSettingsChange(int mapType) {
if (mMap != null) {
mMap.setMapType(mapType);
}
}
sidebar for comments: The interface has always been my favorite part of java. You might call it a listener or a call back. Just right click on the errors and select add reference, add unimplemented methods there really are not too many keystrokes to do this. The interface is perhaps the easiest way to coordinate a team effort on making the next big thing.

Android - find out which context/activity user is currently in?

My application has a few activities, and a background service. My question is, if I have the context variable in the service, how can I tell which activity is currently open? I need to do this to direct the next action my service takes. For example,
if (context is activity_1) {
//take this action
} else if (context is activity_2) {
//do this instead...
}
That's the basic gist of what I'm trying to do.
Help much appreciated.
You could set a SharedPreferences entry in each onResume() method of your activities and read that value from the service. To keep it clean you could write an Activity that does that and then extend all your activities from it:
public class MyActivity extends Activity {
private static final String PREFS_NAME = "MyPrefsFile";
#Override
protected void onResume() {
getContext().getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)
.edit()
.putInt("activtiyIdRunning", getActivityId() )
.commit();
super.onResume();
}
abstract protected int getActivityId();
}
public class MyConcreteActivity1 extends MyActivity {
#Override
protected int getActivityId() {
return 1;
}
// your normal code
}
in your service than just call:
int currentActivity = getContext().getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)
.getInt("activityIdRunning",-1);

Categories