Attempt to invoke virtual method '...' on null object Reference - android

I have problem with my App ,, and want to solve it but i could not access to solution please help me ,,,
// Main_Activity Class
public class MainActivity extends Activity {
Button Open_play_list;
AccessPlayList accessPL;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Open_play_list = (Button)findViewById(R.id.btnShA);
accessPL = new AccessPlayList();
Open_play_list.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Calling method tht contain code for open playlist
try {
accessPL.openPlaylist();
}`enter code here`
catch (Exception ex) {
Toast.makeText(getBaseContext(), ex.getMessage().toString(), Toast.LENGTH_LONG).show();
}
}
});
}
// AccessPlayList Class
public class AccessPlayList extends Activity {
Intent intentPL;
int REQUEST_CODE = 1;
int PLAYLIST_ID = 2;
public void openPlaylist()
{
intentPL = new Intent(Intent.ACTION_PICK);
intentPL.setComponent(new ComponentName("com.android.music","com.android.music.PlaylistBrowserActivity"));
intentPL.setType("MediaStore.Audio.Playlist.CONTENT_TYPE");
intentPL.setFlags(0x10000000);
intentPL.putExtra("oneShot",false);
intentPL.putExtra("PlayList",PLAYLIST_ID);
startActivityForResult(intentPL,REQUEST_CODE);
}
}

Since you did not post which line of your code is where the error is occurring, the only thing I can tell you is that you need to check if the object causing the problem is null.
Try some validation like this:
if(object != null){
//do something
}

Related

Callbacks in Android

I am new to Android and programming as a whole and I need a little help with callbacks. I understand the gist of callbacks but I am unsure of how to go about implementing.
Context: I am writing a simple notetaking app that allows the user to write text and saving it to the app. The user can then request to read the file with a button. The text is then displayed on a textview in the main activity. There is an option to wipe this file and this is done with a confirmation pop up, which is another activity. This pop up contains 2 buttons, one to cancel and one to wipe. If the file is not empty it will wipe and does nothing if empty. I am not sure if this is the best way to implement it but I want to use the wipe button to callback to the main activity to clear the textview. The way I was thinking of was by using the callback to send a boolean value back. The main activity will check if the boolean is true and clear the textview if it is. I am unsure of how to implement the callback in my popup display to send this boolean value back to the main activity.
Code for main activity
public class MainActivity extends AppCompatActivity implements Popout.ClearTextView {
Button bnRead,bnWrite,bnClear;
TextView tvFileOP;
EditText etInput;
// private static final String INPUT_CONTENT = "inputContent";
public static final String TV_CONTENT = "textViewContent";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bnRead = (Button) findViewById(R.id.bnRead);
bnWrite = (Button) findViewById(R.id.bnWrite);
bnClear = (Button) findViewById(R.id.bnClear);
tvFileOP = (TextView) findViewById(R.id.tvFileOP);
etInput = (EditText) findViewById(R.id.etInput);
tvFileOP.setMovementMethod(new ScrollingMovementMethod());
final String fileName = "test_file";
String data;
bnRead.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try {
FileInputStream fIn = openFileInput(fileName);
int c;
String temp = "";
while ( (c=fIn.read()) != -1){
temp = temp + Character.toString((char) c);
}
tvFileOP.setText(temp);
Toast.makeText(getBaseContext(),"file successfully read", Toast.LENGTH_LONG).show();
} catch (Exception e) {
e.printStackTrace();
}
}
});
bnWrite.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String data = etInput.getText().toString();
try {
FileOutputStream fOut = openFileOutput(fileName,MODE_APPEND);
fOut.write(data.getBytes());
fOut.close();
etInput.setText("");
Toast.makeText(getBaseContext(),"file successfully written", Toast.LENGTH_LONG).show();
} catch (Exception e) {
e.printStackTrace();
}
}
});
bnClear.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startActivity(new Intent(MainActivity.this,Popout.class));
}
});
}
#Override
protected void onSaveInstanceState(#NonNull Bundle outState) {
outState.putString(TV_CONTENT,tvFileOP.getText().toString());
super.onSaveInstanceState(outState);
}
#Override
protected void onRestoreInstanceState(#NonNull Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
tvFileOP.setText(savedInstanceState.getString(TV_CONTENT));
}
#Override
public void clearTextView(Boolean clear) {
if (clear){
tvFileOP.setText("");
}
}
}
Code for popup confirmation menu
public class Popout extends AppCompatActivity {
Button bnClosepopup,bnWipe;
TextView tvConfirmation;
String fileName = "test_file";
TextView tvFileOP;
public interface ClearTextView {
public void clearTextView(Boolean clear);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.popupwindow);
bnClosepopup = (Button) findViewById(R.id.bnClosepopup);
bnWipe = (Button) findViewById(R.id.bnWipe);
tvConfirmation = (TextView) findViewById(R.id.tvConfirmation);
//HIDING THE TOOL BAR AT THE TOP OF THE SCREEN
this.getSupportActionBar().hide();
//GETTING THE SIZE OF THE SCREEN
DisplayMetrics displayMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
int height = displayMetrics.heightPixels;
int width = displayMetrics.widthPixels;
getWindow().setLayout((int) (width*0.8) , (int) (0.8*height));
bnClosepopup.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
finish();
}
});
bnWipe.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try {
File dir = getFilesDir();
File file = new File(dir, fileName);
boolean deleted = file.delete();
Toast.makeText(getBaseContext(),"file has been deleted",Toast.LENGTH_SHORT).show();
} catch (Exception e) {
Toast.makeText(getBaseContext(), e.getMessage(), Toast.LENGTH_LONG).show();
}
finish();
}
});
}
}
I am very new to android development and any tips on how to improve my code would be greatly appreciated :)
In this case there is no way to pass the interface to the other activity, because this is an activity to activity communication.
You have to use some other method, there is multiple ways to approach, the best way I can think of is to use startActivityForResult() to start the activity and then wait for a response to come back, and then query this response in the MainActivity by overriding the onActivityResult() method:
Example
In the MainActivity:
//on click of this button
bnClear.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this,Popout.class);
int requestCode = 12; //it could be whatever you want
startActivityForResult(intent , requestCode);
}
});
//override this method
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
//this is triggered when you finish the Popout Activity
if(requestCode == 12 && resultCode == Activity.RESULT_OK){
// get the boolean data returned from the Popout Activity
boolean deleted = data.getBooleanExtra("deleted_state" , false); //false is default if no value exists
}
}
In the Popout activity:
bnWipe.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try {
File dir = getFilesDir();
File file = new File(dir, fileName);
boolean deleted = file.delete();
//send the result to onActivtyResult() in MainActivity
Intent result = new Intent();
result.putExtra("deleted_state", deleted );
setResult(Activity.RESULT_OK, result);
Toast.makeText(getBaseContext(),"file has been deleted",Toast.LENGTH_SHORT).show();
} catch (Exception e) {
Toast.makeText(getBaseContext(), e.getMessage(), Toast.LENGTH_LONG).show();
}
finish();
}
});
UPDATE:
It will be like this:
// get the boolean data returned from the Popout Activity
boolean deleted = data.getBooleanExtra("deleted_state" , false);
if (deleted){
tvFileOP.setText("");
}
..........
As far as what if Understood your problem correctly: You want to control your 'Wipe' button click event from your activity. Here is the solution which may help you.
1: Make an overridden constructor of your dialog class.
2: Create one abstract method in the dialog class. (say - onWipeButtonClick)
You need to make your dialog class abstract as well.
3: Inside on Click Listener of 'Wipe' button, call onWipeButtonClick abstract method.
4: Create the instance of dialog in the main activity where ever you want. The compiler will give you an error because you haven't implemented the call back method.
do implement your onWipeButtonClick method and do needful for wipe data inside the method.
public abstract class WipeDialog extends Dialog{
private Context context;
public WipeDialog(Context context){
this.context = context;
}
public abstract void onWipeButtonClick(boolean isTextEmpty);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.<XML_FILE>);
<initialization>
btnWipe.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
onWipeButtonClick(<YOUR_BOOLEAN_CHECK>);
}
});
}
}
And now in Activity:
WipeDialog dialog = new WipeDialog(MainActivity.this) {
#Override
public void onWipeButtonClick(boolean isTextEmpty) {
//Do Need full with respected to your requirement on click of button 'WIPE'
}
};
Hope this will help.
Thanks!

Getting an error in Android studio when integrating the Helpshift API (null pointer exception)

I'm getting a null point exception in Android studio. I'm trying to integrate Helpshift into my current app. The null point is being called on the help button I think. The error I'm getting is:
java.lang.NullPointerException: Attempt to invoke interface method
'void com.helpshift.CoreApi.updateApiConfig(java.util.Map)' on a null object reference
My code looks like
package com.example.leoconnelly.connexus;
public class MainActivity extends AppCompatActivity {
ImageButton FindCareButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//THE PURPLE BUTTON!!!!!!!
FindCareButton = (findViewById(R.id.find_care_button));
FindCareButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
openFindCare();
}
});
/*
GetStartedButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
openSearchActivity();
}
});
*/
ImageButton helpButton = (ImageButton) findViewById(R.id.imageButton13);
helpButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
ApiConfig.Builder configBuilder = new ApiConfig.Builder();
configBuilder.setRequireEmail(true);
configBuilder.setEnableTypingIndicator(true);
com.helpshift.support.Support.showConversation(MainActivity.this, configBuilder.build() );
}
});
}
public void openFindCare () {
Intent mainActivityToFindCare = new Intent (this,
HealthCenterListActivity.class);
startActivity(mainActivityToFindCare);
}
}
I'm not exactly sure what it's pointing too. I'm trying to open FAQs from Helpshift.
You are missing the InstallConfig for the API. Try adding it in the Calling Activity.
import com.helpshift.Core;
import com.helpshift.All;
import com.helpshift.InstallConfig;
import com.helpshift.exceptions.InstallException;
Core.init(All.getInstance());
InstallConfig installConfig = new InstallConfig.Builder()
.setEnableInAppNotification(true)
.build();
try {
Core.install(getApplication(),
API_KEY,
DOMAIN,
APP_ID, installConfig);
} catch (InstallException e) {
android.util.Log.e("Helpshift", "install call : ", e);
}

What causes a fragment to get detached from an Activity?

I have a SignupActivity which will go through several fragments as users go through a signup process. On the last fragment, I'm calling
getActivity().setResult(Activity.RESULT_OK)
since SingupActivity intent was started for result. Some users are crashing at this point, because getActivity() is producing a NPE. I'm not able to figure out what is causing this. Screen rotation is disabled, so there is no reason that I know of for the fragment to detach from the Activity.
Any insight as to what may be causing this, and how I can resolve it?
public class SignupConfirmationFragment extends Fragment {
public static final String TAG = SignupConfirmationFragment.class.getSimpleName();
private User mNewUser;
private myAppClient mmyAppClient;
private Animation rotateAnimation;
private ImageView avatar;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mNewUser = ((SignUpActivity) getActivity()).getNewUser();
mmyAppClient = ((SignUpActivity) getActivity()).getmyAppClient();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View v = inflater.inflate(R.layout.fragment_signup_confirmation, null);
((TextView) v.findViewById(R.id.username_textView)).setText(((SignUpActivity) getActivity()).getNewUser().getName());
avatar = (ImageView) v.findViewById(R.id.avatar);
if (mNewUser.getAvatarImage() != null) {
avatar.setImageBitmap(mNewUser.getAvatarImage());
}
rotateAnimation = AnimationUtils.loadAnimation(getActivity(), R.anim.progress_rotate);
v.findViewById(R.id.progress_loading).startAnimation(rotateAnimation);
if (mNewUser.getAvatarImage() != null) {
startAvatarUpload();
} else if (mNewUser.getNewsletter()) {
setNewsletterStatus();
} else {
pauseForOneSecond();
}
return v;
}
private void startAvatarUpload() {
mmyAppClient.uploadUserAvatar(mNewUser.getAvatarImage(), new FutureCallback<JsonObject>() {
#Override
public void onCompleted(Exception e, JsonObject result) {
if (mNewUser.getNewsletter()) {
setNewsletterStatus();
} else {
updateFragment();
}
}
},
null,
null);
}
private void setNewsletterStatus() {
mmyAppClient.setNewsletter(mNewUser.getEmail(), mNewUser.getFirstName(), mNewUser.getLastName(), new FutureCallback<String>() {
#Override
public void onCompleted(Exception e, String result) {
//Log.d(TAG, "Result: " + result);
updateFragment();
}
});
}
private void pauseForOneSecond() {
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
updateFragment();
}
}, 1000);
}
private void updateFragment() {
rotateAnimation.cancel();
if (isAdded()) {
getActivity().setResult(Activity.RESULT_OK);
AnalyticsManager.logUIEvent("sign up completed");
getActivity().finish();
} else {
AnalyticsManager.logUIEvent("sign up failed");
}
}
}
According to Fragment lifecycle in Android OS, you cannot get the Activity associated with the fragment in the onCreateView, because the Activity with which the Fragment is associated will not be created at that stage.
See the figure below:
Also, refer to this link, http://developer.android.com/guide/components/fragments.html
As you can see the Activity is created in onActivityCreated which is after onCreateView, hence you'll get null if you try to call the Activity in the onCreateView. Try to call it in onActivityCreated or in onStart that should solve your problem.
I hope this helps.

App crash when I submit a new post to Parse

This is the only Place my app crashes and one of the more important features
The LogCat tells me:
java.lang.IllegalArgumentException: You must create this type of ParseObject using ParseObject.create() or the proper subclass.
at line 37.
I tried the ParseObject.create() however that just caused more problems (I may have done it incorrectly). How Should I code this?
Here is my newPost class:
public class newPost extends Activity {
private Button addButton;
private TextView postView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.newpost);
postView = ((EditText) findViewById(R.id.postView));
addButton = ((Button) findViewById(R.id.addButton));
addButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//line 37 Below
ParseObject post = new ParseObject("Posts");
post.put("content", postView);
post.saveInBackground(new SaveCallback () {
#Override
public void done(ParseException e) {
if (e == null) {
setResult(RESULT_OK);
finish();
} else {
Toast.makeText(getApplicationContext(),
"Error saving: " + e.getMessage(),
Toast.LENGTH_SHORT)
.show();
}
}
});
}
});
}
Replace this line
ParseObject post = new ParseObject("Posts");
with this
ParseObject post = ParseObject.create("Posts");
Ensure that you've added the below line in the Application.java class where Parse is initialised
ParseObject.registerSubclass(Message.class);
In my case I had to remove the '#ParseClassName' annotation in my model class. My understanding is that if I have a parse model class 'Posts' and I call 'registerSubclass(yourclassname)' in Application, then all I need is
Post obj = new Post();
You probably made a mistake in initialising Parse in your Application class. Or forgot to put android:name=".YourApplicationClass" in your Manifest file.
I got this error because I forgot to register my parse class as a subclass in my application extension:
public class App extends Application
{
#Override
public void onCreate()
{
super.onCreate();
App application = this;
ParseObject.registerSubclass(Posts.class); // <-- This is what you need
Parse.enableLocalDatastore(this);
Parse.initialize(new Parse.Configuration.Builder(getApplicationContext())
.applicationId(EnvironmentConfig.appID)
.server(EnvironmentConfig.serverName)
.enableLocalDataStore()
.build());
ParseInstallation.getCurrentInstallation().saveInBackground();
}
}

AsyncTask : passing value to an Activity (onCreate method )

Update1
activity:
public Integer _number = 0;
#Override
public void onCreate(Bundle savedInstanceState) {
if (_number >0)
{
Log.d("onSuccessfulExecute", ""+_number);
}
else
{
Log.d("onSuccessfulExecute", "nope empty songs lists");
}
}
public int onSuccessfulExecute(int numberOfSongList) {
_number = numberOfSongList;
if (numberOfSongList >0)
{
Log.d("onSuccessfulExecute", ""+numberOfSongList);
}
else
{
Log.d("onSuccessfulExecute", "nope empty songs lists");
}
return numberOfSongList;
}
end Update1
UPDATE: AsynchTask has its own external class.
How to pass an value from AsyncTask onPostExecute()... to activity
my code does returning value from onPostExecute() and updating on UI but i am looking for a way to set the activity variable (NumberOfSongList) coming from AsynchTask.
AsyncTask class:
#Override
public void onPostExecute(asynctask.Payload payload)
{
AsyncTemplateActivity app = (AsyncTemplateActivity) payload.data[0];
//the below code DOES UPDATE the UI textView control
int answer = ((Integer) payload.result).intValue();
app.taskStatus.setText("Success: answer = "+answer);
//PROBLEM:
//i am trying to populate the value to an variable but does not seems like the way i am doing:
app.NumberOfSongList = payload.answer;
..............
..............
}
Activity:
public Integer NumberOfSongList;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//Several UI Code
new ConnectingTask().execute();
Log.d("onCreate", ""+NumberOfSongList);
}
What about using a setter method? e.g.
private int _number;
public int setNumber(int number) {
_number = number;
}
UPDATE:
Please look at this code. This will do what you're trying to accomplish.
Activity class
public class TestActivity extends Activity {
public int Number;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.test);
Button btnDisplay = (Button) findViewById(R.id.btnDisplay);
btnDisplay.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Toast toast = Toast.makeText(v.getContext(), "Generated number: " + String.valueOf(Number), Toast.LENGTH_LONG);
toast.show();
}
});
new TestTask(this).execute();
}
}
AsyncTask class
public class TestTask extends AsyncTask<Void, Void, Integer> {
private final Context _context;
private final String TAG = "TestTask";
private final Random _rnd;
public TestTask(Context context){
_context = context;
_rnd = new Random();
}
#Override
protected void onPreExecute() {
//TODO: Do task init.
super.onPreExecute();
}
#Override
protected Integer doInBackground(Void... params) {
//Simulate a long-running procedure.
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
Log.e(TAG, e.getMessage());
}
return _rnd.nextInt();
}
#Override
protected void onPostExecute(Integer result) {
TestActivity test = (TestActivity) _context;
test.Number = result;
super.onPostExecute(result);
}
}
Just a word of caution: Be very careful when attempting to hold a reference to an Activity instance in an AsyncTask - I found this out the hard way :). If the user happens to rotate the device while your background task is still running, your activity will be destroyed and recreated thus invalidating the reference being to the Activity.
Create a listener.
Make a new class file. Called it something like MyAsyncListener and make it look like this:
public interface MyAsyncListener() {
onSuccessfulExecute(int numberOfSongList);
}
Make your activity implement MyAsyncListener, ie,
public class myActivity extends Activity implements MyAsyncListener {
Add the listener to the constructor for your AsyncTask and set it to a global var in the Async class. Then call the listener's method in onPostExecute and pass the data.
public class MyCustomAsync extends AsyncTask<Void,Void,Void> {
MyAsyncListener mal;
public MyCustomAsync(MyAsyncListener listener) {
this.mal = listener;
}
#Override
public void onPostExecute(asynctask.Payload payload) {
\\update UI
mal.onSuccessfulExecute(int numberOfSongList);
}
}
Now, whenever your AsyncTask is done, it will call the method onSuccessfulExecute in your Activity class which should look like:
#Override
public void onSuccessfulExecute(int numberOfSongList) {
\\do whatever
}
Good luck.

Categories

Resources