I am very new to android. I have a counter on some SomeActivity, but when I get to the page corresponding to SomeActivity, my app crashes :
final TextView counter = (TextView) findViewById(R.id.laws_counter);
ImageView handDown = (ImageView) findViewById(R.id.handViewDown);
counter.setText("" + 0);
I want that on click of the handown, the counter is idented by -1. Here's
handDown.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(NewsActivity.this,
"The favorite list would appear on clicking this icon",
Toast.LENGTH_LONG).show();
setDown();
}
private void setDown() {
String count = counter.getText().toString();
int now_count = Integer.parseInt(count) +1;
counter.setText(String.valueOf(now_count));
}
});
Is this code correct ?
Update : here's the logcat
10-22 00:18:05.579: ERROR/AndroidRuntime(378): FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.donnfelker.android.bootstrap/com.donnfelker.android.bootstrap.ui.NewsActivity}: java.lang.NullPointerException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1647)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663)
at android.app.ActivityThread.access$1500(ActivityThread.java:117)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:123)
at android.app.ActivityThread.main(ActivityThread.java:3683)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at com.donnfelker.android.bootstrap.ui.NewsActivity.onCreate(NewsActivity.java:41)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611)
... 11 more
There are many ways that you can implement that functionality but think this would be an easy solution.
Make a helper method:
public class PreferencesData {
public static void saveInt(Context context, String key, int value) {
SharedPreferences sharedPrefs = PreferenceManager
.getDefaultSharedPreferences(context);
sharedPrefs.edit().putInt(key, value).commit();
}
public static int getInt(Context context, String key, int defaultValue) {
SharedPreferences sharedPrefs = PreferenceManager
.getDefaultSharedPreferences(context);
return sharedPrefs.getInt(key, defaultValue);
}
}
Then simply call the putInt method to save the counter in any Activity and getInt to get it again in any other Activity. As long as you use the same key both places.
Related
This question already has answers here:
How exactly does the android:onClick XML attribute differ from setOnClickListener?
(17 answers)
Closed 6 years ago.
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.juliandrach.eatfit, PID: 2223
java.lang.IllegalStateException: Could not find method aldirindersalami(View) in a parent or ancestor Context for android:onClick attribute defined on view class android.support.v7.widget.AppCompatButton
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.resolveMethod(AppCompatViewInflater.java:327)
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:284)
at android.view.View.performClick(View.java:4438)
at android.view.View$PerformClick.run(View.java:18422)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5017)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
at dalvik.system.NativeStart.main(Native Method)
Basically the error occurs when I am updating a variable by pressing a button and then trying to display the value of the variable with a toast in the same task.
public class Mahlzeiten extends AppCompatActivity {
public static int proteine = 0;
public static int carbs = 0;
public static int fette = 0;
public static int kcal = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_mahlzeiten);
String text = "Hallo" + proteine + "danke";
Toast.makeText(Mahlzeiten.this, text, Toast.LENGTH_SHORT).show();
}
public void aldirindersalami (int proteine){
proteine++;
// String text1 = "Hallo" + proteine + "danke";
// Toast.makeText(Mahlzeiten.this, text1, Toast.LENGTH_SHORT).show();
}
}
You have an onClick listener set in the xml but you didn't implement the onClick method in the code. You need the following method
public void aldirindersalami(View v) {}
to handle the click on the button.
I was using an integer for the money factor in this little test app but I realized that long was more appropriate and I changed the code so that money is a long instead of an int and I changed SharedPreferences appropriately as well, however it does not work wheras it did when I used int. Thank you for the help!
public class Home extends AppCompatActivity {
SharedPreferences pref;
SharedPreferences.Editor editor;
Intent intent;
TextView home_money_view;
long money; // this is the variable that is causing problems
int initial;
final long TEST = (long)-1;
int gold_pieces;
int gold_price = 50;
TimerTask timerTask;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
home_money_view = (TextView) findViewById(R.id.home_money_view)
pref = getApplicationContext().getSharedPreferences("MY_PREFS", MODE_PRIVATE);
editor = pref.edit();
money = pref.getLong("temp_money",Long.MIN_VALUE); // get value
if (money==Long.MIN_VALUE){
money=0;
}
gold_pieces = pref.getInt("temp_gold",-1);
if (gold_pieces==-1){
gold_pieces=0;
}
initial = pref.getInt("initial",0);
money+=initial;
editor.putInt("initial",0);
editor.commit();
home_money_view = (TextView) findViewById(R.id.home_money_view);
home_money_view.setText(money+"");
editor.commit();
}
public void backToSplash(View view){
intent = new Intent(Home.this,BusinessSelector.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
}
public void goToSecondView(View view){
long temp_money = money;
editor.putLong("temp_money",temp_money); // set value
int temp_gold = gold_pieces;
editor.putInt("temp_gold",temp_gold);
editor.commit();
intent = new Intent(Home.this,SecondView.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
}
public void goToOtherView(View view) {
long temp_money = money;
editor.putLong("temp_money",temp_money); // set value
int temp_gold = gold_pieces;
editor.putInt("temp_gold", temp_gold);
editor.commit();
intent = new Intent(Home.this, Next.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
}
}
Logcat:
04-13 19:01:03.675 12896-12896/com.exampleryancocuzzo.ryan.markettycoon E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.exampleryancocuzzo.ryan.markettycoon/com.exampleryancocuzzo.ryan.markettycoon.Home}: java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Long
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1956)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)
at android.app.ActivityThread.access$600(ActivityThread.java:123)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4424)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Long
at android.app.SharedPreferencesImpl.getLong(SharedPreferencesImpl.java:228)
at com.exampleryancocuzzo.ryan.markettycoon.Home.onCreate(Home.java:56)
at android.app.Activity.performCreate(Activity.java:4466)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1920)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)
at android.app.ActivityThread.access$600(ActivityThread.java:123)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4424)
at java.lang.reflect.Method.invokeNative(Native Method)
I am working on a financial app and i have to use BigDecimal to calculate currency.Now I am trying to make one entrance activity which is searching in the SharedPreferences for a previous registration and if their is one it starts another activity , if not it starts the registration activity.The problem is the registration activity causes NumberFormatException Error while I am trying to construct a new object of time Profit (the Profit class contains BigDecimal field).Also I am not quite sure that I am using SharedPreferences right.I am not quite sure that my idea and my coding are fine because I am new at android development and i am stuck with this problem so I am giving you all the classes.
the Registration activity:
public class Registration extends Activity {
private static String enteredPassword;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final EditText password1 = (EditText) findViewById(R.id.password1);
final EditText password2 = (EditText) findViewById(R.id.password2);
final EditText availability = (EditText) findViewById(R.id.availability);
EditText profitEditText = (EditText) findViewById(R.id.profit);
Spinner spinner = (Spinner) findViewById(R.id.period_spinner);
Button registrationButton = (Button) findViewById(R.id.registrationButton);
DatePicker picker = (DatePicker) findViewById(R.id.thePicker);
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,
R.array.periods_array, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
final String balance = availability.getText().toString().replace(",",".");
String profitPeriod = ((Period) spinner.getSelectedItem()).name();
final Profit profit = new Profit("regular_profit", profitEditText.getText().toString(),
profitPeriod ,picker);
registrationButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (password1.getText().toString().equals(password2.getText().toString())) {
enteredPassword = password1.getText().toString();
Repository.setPassword(enteredPassword, mContext);
}
Repository.setBalance(balance, mContext);
Repository.setProfit(profit, mContext);
}
});
}
}
the profit activity
public class Profit {
private Date mProfitDate;
private Date mNextProfitDate;
private BigDecimal value;
public final static String TITLE = "title";
public final static String PERIOD = "period";
Profit(String title,String value, String period, DatePicker picker) {
this.mTitle = title;
if(value!=null){this.value = new BigDecimal(value);}else{ this.value = new BigDecimal("0.0");};
this.mPeriod = Period.class.cast(period);
this.mProfitDate = Repository.getDateFromPicker(picker);
}
public long getNextProfitDate(Date profitDate, Period period){
long unixProfitDate = profitDate.getTime() / 1000L;
long nextProfitDate=0;
switch (period){
case DAILY:
nextProfitDate = DateUtils.DAY_IN_MILLIS/1000 + unixProfitDate;
break;
case WEEKLY:
nextProfitDate = DateUtils.WEEK_IN_MILLIS/1000 + unixProfitDate;
break;
case MONTHLY:
Date dateNow = new Date();
dateNow.getTime();
nextProfitDate = Repository.monthsToSeconds(Calendar.getInstance()
.get(Calendar.MONTH)) + unixProfitDate;
break;
case YEARLY:
nextProfitDate = DateUtils.YEAR_IN_MILLIS/1000 + unixProfitDate;
break;
}
return nextProfitDate;
}
}
the entrance activity
public class EnterActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_enter);
CountDownTimer timer = new CountDownTimer(3000, 100) {
public void onTick(long millisUntilFinished) {
}
public void onFinish() {
if(Repository.getPassword(mContext.getApplicationContext()).equals("No Value")){
Intent registrationIntent = new Intent(mContext, Registration.class);
startActivity(registrationIntent);
}
else{
Intent configurationIntent = new Intent(mContext, Configuration.class);
startActivity(configurationIntent);
}
}
}.start();
}
}
the Repository
public class Repository {
public static SharedPreferences sharedPreferences;
private static SharedPreferences getPrefs(Context context) {
return context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
}
public static String getPassword(Context context){
return getPrefs(context).getString(PASSWORD,"No Value");
}
public Repository() {
}
public static void setPassword(String password, Context context){
SharedPreferences.Editor editor = getPrefs(context).edit();
editor.putString(PASSWORD, password);
editor.commit();
}
public static void setBalance(String balance, Context context){
SharedPreferences.Editor editor = getPrefs(context).edit();
editor.putString(BALANCE, balance);
editor.commit();
}
public static void setProfit(Profit profit, Context context){
SharedPreferences.Editor editor = getPrefs(context).edit();
editor.putString(BALANCE, profit.getValue().toString());
editor.commit();
}
}
the output
E/AndroidRuntime: FATAL EXCEPTION: main
E/AndroidRuntime: java.lang.RuntimeException: Unable to start activity ComponentInfo{/.Registration}: java.lang.NumberFormatException: Bad offset/length: offset=0 len=0 in.length=0
E/AndroidRuntime: at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1956)
E/AndroidRuntime: at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)
E/AndroidRuntime: at android.app.ActivityThread.access$600(ActivityThread.java:123)
E/AndroidRuntime: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147)
E/AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime: at android.os.Looper.loop(Looper.java:137)
E/AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:4424)
E/AndroidRuntime: at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime: at java.lang.reflect.Method.invoke(Method.java:511)
E/AndroidRuntime: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
E/AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
E/AndroidRuntime: at dalvik.system.NativeStart.main(Native Method)
E/AndroidRuntime: Caused by: java.lang.NumberFormatException: Bad offset/length: offset=0 len=0 in.length=0
E/AndroidRuntime: at java.math.BigDecimal.<init>(BigDecimal.java:282)
E/AndroidRuntime: at java.math.BigDecimal.<init>(BigDecimal.java:438)
E/AndroidRuntime: at .Profit.<init>(Profit.java:41)
E/AndroidRuntime: at .Registration.onCreate(Registration.java:57)
E/AndroidRuntime: at android.app.Activity.performCreate(Activity.java:4466)
E/AndroidRuntime: at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
E/AndroidRuntime: at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1920)
E/AndroidRuntime: at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)
E/AndroidRuntime: at android.app.ActivityThread.access$600(ActivityThread.java:123)
E/AndroidRuntime: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147)
E/AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime: at android.os.Looper.loop(Looper.java:137)
E/AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:4424)
E/AndroidRuntime: at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime: at java.lang.reflect.Method.invoke(Method.java:511)
E/AndroidRuntime: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
E/AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
E/AndroidRuntime: at dalvik.system.NativeStart.main(Native Method)
You instantiate a Profit in only one place in the code you presented:
Profit profit = new Profit("regular_profit", profitEditText.getText().toString(),
profitPeriod, picker);
If that causes a NumberFormatException then it must come from this code in the Profit constructor:
if(value!=null){this.value = new BigDecimal(value);}else{ this.value = new BigDecimal("0.0");};
Since the value String will have come from invoking toString() on an object, you can rely on it to not be null (and anyway, if it were null then you would end up at new BigDecimal("0.0"), and you can verify for yourself that that works fine). That leaves us with new BigDecimal(value) as the culprit. The docs for this constructor provide details of the expected format of the argument string. If the argument does not comply with that format then a NumberFormatException will be thrown.
Among the more likely malformed strings that one might imagine in a scenario such as you describe is an empty string, which is not the same as null in Java. Given that the text is coming from a UI field, you also have to watch out for fun and difficult-to-spot malformations such as leading and trailing whitespace.
Perhaps it would be better to write the affected part of the constructior like so:
if (value != null) {
value = value.trim();
this.value = value.length() == 0 ? BigDecimal.ZERO : new BigDecimal(value);
} else {
this.value = BigDecimal.ZERO;
}
Do note that even with that change, this constructor will still throw NumberFormatException in the event of other kinds of malformation. Wherever you are uncertain about the validity of the data, you should be prepared to handle such an exception.
You aren't parsing your string to a Big Decimal correctly.
The following in your Profit contructor:
if(value!=null)
{
this.value = new BigDecimal(value);
}
else
{
this.value = new BigDecimal("0.0");
}
Needs to parse the string to a BigDecimal. Like the following where this.value is of type BigDecimal:
this.value = (BigDecimal) decimalFormat.parse(value);
Also keep in mind that decimalFormat.parse can throw a ParseException. You will need to handle it with try/catch or throw it.
Building on a theme from yesterday...I'm getting an NPE accessing a method in a singleton Application class from within an AlertDialog.
Activity SavedMealsActivity sets OnLongClickListenerSavedMeals as the listener for a series of TextViews in a ScrollView. OnLongClickListenerSavedMeals is defined as a separate class.
OnLongClickListenerSavedMeals displays an AlertDialog which gives the option of going to a different Activity, but it first needs to fire the methods of an Application class which is defined as a singleton (MealTimerApplication). This is the first line of the onClick method (line 25 in the first code sample below), and it throws the NPE because the activity is null at the time.
I've tried passing in the activity from the calling Activity (SavedMealsActivity) but for some reason it's not working as I'd hoped. Any ideas?
OnLongClick listener class - OnLongClickListenerSavedMeals:
public class OnLongClickListenerSavedMeals implements OnLongClickListener {
Context context;
String id;
private Activity activity;
public OnLongClickListenerSavedMeals(Activity activity) {
this.activity = activity;
this.context = activity;
}
#Override
public boolean onLongClick(View view){
// TODO Auto-generated method stub
this.context = context;
id = view.getTag().toString();
final CharSequence[] items = { "Edit", "Delete" };
//Set activity to allow context to be used in the OnClickListener/onClick method below
this.activity = activity;
new AlertDialog.Builder(context).setTitle("Meal Item")
.setItems(items, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
if (item == 0) {
//Set the global meal_id variable and invoke the MealActivity
((MealTimerApplication) activity.getApplication()).setMealId(Long.getLong(id));
Intent myIntent = new Intent(activity.getBaseContext(),MealActivity.class);
activity.startActivityForResult(myIntent, 0);
}
else if (item == 1) {
boolean deleteSuccessful = new TableControllerMeal(context).delete(id);
if (deleteSuccessful){
Toast.makeText(context, "Record was deleted.", Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(context, "Unable to delete record.", Toast.LENGTH_SHORT).show();
}
((SavedMealsActivity) context).readRecords();
}
dialog.dismiss();
}
}).show();
return false;
}
Calling Activity - SavedMealsActivity:
public class SavedMealsActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_saved_meals);
//Read saved meal records from the database and display them
readRecords();
}
public void readRecords() {
LinearLayout linearLayoutRecords = (LinearLayout) findViewById(R.id.linearLayoutRecords);
linearLayoutRecords.removeAllViews();
List<meal> meal = new TableControllerMeal(this).read();
if (meal.size() > 0) {
for (meal obj : meal) {
long id = obj.id;
String MealDesc = obj.meal_desc;
int MealMinutes = obj.meal_ready_time;
String textViewContents = MealDesc + " - ready at "
+ Utilities.formatTime(MealMinutes);
TextView textViewItem = new TextView(this);
textViewItem.setPadding(0, 10, 0, 10);
textViewItem.setText(textViewContents);
textViewItem.setTag(Long.toString(id));
textViewItem.setOnLongClickListener(new OnLongClickListenerSavedMeals(this));
linearLayoutRecords.addView(textViewItem);
}
}
else {
TextView Item = new TextView(this);
Item.setPadding(8, 8, 8, 8);
Item.setText("No records yet.");
linearLayoutRecords.addView(Item);
}
}
Application class:
public class MealTimerApplication extends Application {
private static MealTimerApplication singleton;
private long mealId = 0;
// Returns the application instance
public static MealTimerApplication getInstance() {
return singleton;
}
public final void onCreate() {
super.onCreate();
singleton = this;
}
public void setMealId(long mealId) {
this.mealId = mealId;
}
public long getMealId() {
return this.mealId;
}
}
Logcat:
05-28 16:48:03.637: E/AndroidRuntime(4241): java.lang.NullPointerException
05-28 16:48:03.637: E/AndroidRuntime(4241): at com.ian.mealtimer.OnLongClickListenerSavedMeals$1.onClick(OnLongClickListenerSavedMeals.java:39)
05-28 16:48:03.637: E/AndroidRuntime(4241): at com.android.internal.app.AlertController$AlertParams$3.onItemClick(AlertController.java:941)
05-28 16:48:03.637: E/AndroidRuntime(4241): at android.widget.AdapterView.performItemClick(AdapterView.java:299)
05-28 16:48:03.637: E/AndroidRuntime(4241): at android.widget.AbsListView.performItemClick(AbsListView.java:1113)
05-28 16:48:03.637: E/AndroidRuntime(4241): at android.widget.AbsListView$PerformClick.run(AbsListView.java:2904)
05-28 16:48:03.637: E/AndroidRuntime(4241): at android.widget.AbsListView$3.run(AbsListView.java:3638)
05-28 16:48:03.637: E/AndroidRuntime(4241): at android.os.Handler.handleCallback(Handler.java:733)
05-28 16:48:03.637: E/AndroidRuntime(4241): at android.os.Handler.dispatchMessage(Handler.java:95)
05-28 16:48:03.637: E/AndroidRuntime(4241): at android.os.Looper.loop(Looper.java:136)
05-28 16:48:03.637: E/AndroidRuntime(4241): at android.app.ActivityThread.main(ActivityThread.java:5017)
05-28 16:48:03.637: E/AndroidRuntime(4241): at java.lang.reflect.Method.invokeNative(Native Method)
05-28 16:48:03.637: E/AndroidRuntime(4241): at java.lang.reflect.Method.invoke(Method.java:515)
05-28 16:48:03.637: E/AndroidRuntime(4241): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
05-28 16:48:03.637: E/AndroidRuntime(4241): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
05-28 16:48:03.637: E/AndroidRuntime(4241): at dalvik.system.NativeStart.main(Native Method)
You get NPE because of autoboxing. Long.getLong(String) is not what you actually you need, check its description:
Returns the Long value of the system property identified by string.
It definitely returns null in your case. Moreover it returns null reference to Long object, but your MealTimerApplication.setMealId expects argument with primitive type long. Here is the point where auto-boxing implicitly trying to cast your Long object returned by getLong method to the long primitive. But as value was null auto-boxing fails and you get NPE.
You should just use Long.valueOf(String) instead of Long.getLong(String).
I have this code for show the MediaController, but it give me a fatal error when I'm calling to Show() method.
The MediaPlayer itself working on Service and get Intent from the MediaPlayerControl interface.
My code:
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mediaController = new MediaController(this, false);
mediaController.setMediaPlayer(mediaPlayerControl);
mediaController.setAnchorView(findViewById(R.id.mediaController));
mediaController.setEnabled(true);
mediaController.show(0);
}
//implements MediaPlayerControl interface
private MediaPlayerControl mediaPlayerControl = new MediaPlayerControl()
{
//Override the methods to send Intent to the MediaPlayer Service
....
....
};
my logcat:
07-27 11:03:07.365: E/AndroidRuntime(328): FATAL EXCEPTION: main
07-27 11:03:07.365: E/AndroidRuntime(328): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.radius100fm/com.example.radius100fm.MainActivity}: android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running?
07-27 11:03:07.365: E/AndroidRuntime(328): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1647)
07-27 11:03:07.365: E/AndroidRuntime(328): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663)
07-27 11:03:07.365: E/AndroidRuntime(328): at android.app.ActivityThread.access$1500(ActivityThread.java:117)
07-27 11:03:07.365: E/AndroidRuntime(328): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931)
07-27 11:03:07.365: E/AndroidRuntime(328): at android.os.Handler.dispatchMessage(Handler.java:99)
07-27 11:03:07.365: E/AndroidRuntime(328): at android.os.Looper.loop(Looper.java:123)
07-27 11:03:07.365: E/AndroidRuntime(328): at android.app.ActivityThread.main(ActivityThread.java:3683)
07-27 11:03:07.365: E/AndroidRuntime(328): at java.lang.reflect.Method.invokeNative(Native Method)
07-27 11:03:07.365: E/AndroidRuntime(328): at java.lang.reflect.Method.invoke(Method.java:507)
07-27 11:03:07.365: E/AndroidRuntime(328): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
07-27 11:03:07.365: E/AndroidRuntime(328): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
07-27 11:03:07.365: E/AndroidRuntime(328): at dalvik.system.NativeStart.main(Native Method)
07-27 11:03:07.365: E/AndroidRuntime(328): Caused by: android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running?
07-27 11:03:07.365: E/AndroidRuntime(328): at android.view.ViewRoot.setView(ViewRoot.java:527)
07-27 11:03:07.365: E/AndroidRuntime(328): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:177)
07-27 11:03:07.365: E/AndroidRuntime(328): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
07-27 11:03:07.365: E/AndroidRuntime(328): at android.view.Window$LocalWindowManager.addView(Window.java:424)
07-27 11:03:07.365: E/AndroidRuntime(328): at android.widget.MediaController.show(MediaController.java:304)
07-27 11:03:07.365: E/AndroidRuntime(328): at com.example.radius100fm.MainActivity.onCreate(MainActivity.java:100)
07-27 11:03:07.365: E/AndroidRuntime(328): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
07-27 11:03:07.365: E/AndroidRuntime(328): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611)
07-27 11:03:07.365: E/AndroidRuntime(328): ... 11 more
What is the problem with my code?
Use this method.
#Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if(mediaController != null)
mediaController.show(0);
}
I got the same problem and after several hours got the solution. I did the following:
Summary:
The Activity class implements the interfaces: MediaPlayer.OnPreparedListener and MediaController.MediaPlayerControl
OnCreate. setContentView.
onStart. Create MediaPlayer and MediaController, start the listener with setOnPreparedListener and call prepare() method of MediaPlayer.
Implement method onPrepared. Link the mediaController with the mediaPlayer, start mediaPlayer and here is where the method show() is called using a handler, only when we know that mediaPlayer is ready.
My code:
public class MainActivity extends Activity implements MediaPlayer.OnPreparedListener, MediaController.MediaPlayerControl {
private static final String TAG = "AudioPlayer";
private MediaPlayer mediaPlayer;
private MediaController mediaController;
private Handler handler = new Handler();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
protected void onStart() {
Log.d(TAG, "Play - onStart");
super.onStart();
mediaPlayer = new MediaPlayer();
mediaController = new MediaController(this);
mediaPlayer.setOnPreparedListener(this);
try {
AssetFileDescriptor afd = getApplicationContext().getResources().openRawResourceFd(R.raw.audio_example);
mediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getDeclaredLength());
mediaPlayer.prepare();
afd.close();
} catch (IOException e) {
Log.e(TAG, "Error opening audio: " + e.getCause());
}
}
// override this method because of the OnPreparedListener interface
#Override
public void onPrepared(MediaPlayer mediaPlayer) {
Log.d(TAG, "Play - onPrepared");
mediaController.setMediaPlayer(this);
mediaController.setAnchorView(findViewById(R.id.mediaController1));
mediaPlayer.start();
handler.post(new Runnable() {
#Override
public void run() {
mediaController.setEnabled(true);
mediaController.show(0);
}
});
}
// override these methods because of the MediaController.MediaPlayerControl interface
#Override
public boolean canPause() {
return true;
}
#Override
public boolean canSeekBackward() {
return true;
}
#Override
public boolean canSeekForward() {
return true;
}
#Override
public int getAudioSessionId() {
// TODO Auto-generated method stub
return 0;
}
#Override
public int getBufferPercentage() {
// TODO Auto-generated method stub
return 0;
}
#Override
public int getCurrentPosition() {
return mediaPlayer.getCurrentPosition();
}
#Override
public int getDuration() {
return mediaPlayer.getDuration();
}
#Override
public boolean isPlaying() {
return mediaPlayer.isPlaying();
}
#Override
public void pause() {
mediaPlayer.pause();
}
#Override
public void seekTo(int pos) {
mediaPlayer.seekTo(pos);
}
#Override
public void start() {
mediaPlayer.start();
}
// release resources before kill the Activity
#Override
protected void onStop() {
Log.d(TAG, "Play - onStop");
super.onStop();
if (mediaPlayer != null) {
mediaController.hide();
mediaPlayer.stop();
mediaPlayer.release();
mediaPlayer = null;
}
} }
Ok, so finely I found the answer.
The problem is in the line:
mediaController.show(0);
Because it called in onCreate() and the app still not activated.
Simple tried, add bottom that callingmediaController.show(0); when it clicked, and the app work perfect.
So now I have to call this line after the app get activate.
I'm tried onStart() and onResume() and it not working. The same error logCat.
How can I fix that??
I needed to show the MediaController to a already running MediaPlayer, so I couldn't set the OnPreparedListener like e_v_e said.
With the answer to this question: Can't fix MediaController.show() exception I discovered that the show method is been called before all the activity lifecycle methods were called. The solution proposed there(setting a delay to show) works, but to avoid the delay, you can place the show inside the onAttachedToWindow method, that is called after all the activity lifecycle methods.
Just put the mediaPlayer.prepare() and mediaPlayer.start() in a thread like handler or AsyncTask and done.
If you are using kotlin and anko lib, you can put it in doAsync {}.